以Typescript导入JavaScript文件,无法访问TS中的函数,能够以html访问它们

时间:2018-07-27 10:40:23

标签: javascript typescript

我最近开始将TypeScript和React与我公司的旧版JavaScript代码库集成在一起。我敢肯定,你们中的很多人都明白这一点。

在克服了许多大障碍之后,例如设置了正确的webpack程序,理解并设置了tsconfig文件以及正确地分解了捆绑,我终于将它们全部与我们当前的CI管道集成了。

但是,现在我在TypeScript代码中导入JavaScript库时遇到了问题。我知道这是不好的做法,但是在完全符合TS要求之前,这只是中间人。

我有一个构建良好的基本组件:

import * as React from "react";
import * as ReactDOM from "react-dom";
import { Header } from "./components/header";
import * as $C from "./../../fortress.content.js";
import * as $F from "./../../fortress.js"; 

let url : string  = $F.writeUrl("Account", "LoginAjax");

ReactDOM.render(
    <div>
        <div> {url} </div>
    </div>,  
    document.getElementById("body")
);

$F.writeUrl允许我们从根本上基于项目根目录中的webconfig文件创建一个字符串,因此基本上是一个函数,该函数需要几个不同的参数并基于该参数返回一个字符串:

但是,当我在裸机html文件中运行转译的JavaScript时:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<div id="body"></div>
<div id="header"></div>
<body> 
    <script src="js/jquery-2.1.4.min.js"></script> 
    <script src="js/react-0.14.3.js"></script>
    <script src="js/react-dom-0.14.3.js"></script> 
    <script src="js/filemanager/filemanager.bundle.js"></script>
    <script src="js/anothermanager/anothermanager.bundle.js"></script>
    <script>  
            console.log("$F: ", $F);
            console.log("$C: ", $C);
    </script>
</body>
</html>

我得到这些错误:

Uncaught TypeError: Cannot read property 'bind' of undefined
    at new t (filemanager.bundle.js:1)
    at ReactCompositeComponentWrapper.mountComponent (react.js:5504)
    at ReactCompositeComponentWrapper.wrapper [as mountComponent] (react.js:12346)
    at Object.mountComponent (react.js:12971)
    at ReactDOMComponent.mountChildren (react.js:11685)
    at ReactDOMComponent._createContentMarkup (react.js:6817)

anothermanager.bundle.js:1 Uncaught ReferenceError: $C is not defined
    at anothermanager.bundle.js:1
    at Object.<anonymous> (anothermanager.bundle.js:1)
    at n (anothermanager.bundle.js:1)
    at Object.<anonymous> (anothermanager.bundle.js:1)
    at n (anothermanager.bundle.js:1)
    at anothermanager.bundle.js:1
    at anothermanager.bundle.js:1
    at ReactDOMComponent.mountComponent (react.js:6705)
    at Object.mountComponent (react.js:12971)
    at ReactCompositeComponentWrapper.mountComponent (react.js:5581)
    at ReactCompositeComponentWrapper.wrapper [as mountComponent] (react.js:12346)

index.html:17 Uncaught ReferenceError: $F is not defined
    at index.html:17

所以我尝试将其更改为在我的TS中实例化$C$F

let test = $F;
let test2 = $C;

这消除了上述错误,并实际上在控制台日志中向我显示了$F$C对象。但是现在的问题是$ F.writeUrl(“ Account”,“ LoginAjax”)正在吹响,因为Chrome不会将其识别为“功能”。

我的进口商品做错了吗?

2 个答案:

答案 0 :(得分:3)

我想您不需要import在您的反应包中的那些文件。如果这些文件没有使用module.exportsexport导出任何内容,而是设置了window成员以供以后使用(实际上是几年前的标准)。我知道你应该:

1) 将这些文件作为脚本加载,因此它们随处可见。确保将它们添加到任何react相关的脚本/捆绑软件之前,以便确保在安装react代码时它们可用:

<script src="js/jquery-2.1.4.min.js"></script>
<script src="js/path-to-fortress-content.js"></script>
<script src="js/path-to-fortress.js"></script> 
<script src="js/react-0.14.3.js"></script>
<script src="js/react-dom-0.14.3.js"></script>

2) 现在,它们在您的反应代码中可用。您需要使用window中的它们,而不是让捆绑程序处理$ F / $ C模块:

let $f: any = (window as any).$F;
let url : string  = $F.writeUrl("Account", "LoginAjax");

答案 1 :(得分:1)

  

[...]用我的TypeScript代码导入JavaScript库。我知道这是不好的做法,但是在完全兼容TS之前只是中间人

别担心,这不一定是坏习惯,尤其是在过渡时期。

Sergeon's answer的一个小的添加中,它涵盖了实现问题,我将添加一些JavaScript库 do 具有允许您使用它们的类型。在TypeScript应用程序中,例如jQuery

npm i --saveDev "@types/jquery"

然后在.ts模块中使用键入内容:

import "jquery";
declare const $: JQueryStatic;

这还为您提供了一些IDE IntelliSense协助的好处:

IntelliSense for jQuery

如果需要,可以从@types/存储库中查找并添加其他库。