我有一个大型的Typescript项目,它被连接到一个JS文件中进行部署。 确保以正确的连接顺序给出文件的正确方法是什么?有太多的文件可以手动尝试和维护。
如果文件A中的类依赖于文件B中的类,则生成的连接文件中的类的排序很重要。如果文件B出现在文件A之后,则在运行时无法解析该类。
这肯定是一个常见的问题,应该有一个简单的解决方案。 一个警告是我使用命名空间而不是模块。我不确定在整个项目中使用模块是否可以解决这个问题。
这是一个简单的例子 的 TestClassA.ts
namespace Test {
'use strict';
import TestClassB = Test.TestClassB;
export class TestClassA {
private test: TestClassB;
constructor() {
this.test = new TestClassB();
}
}
}
TestClassB.ts
namespace Test {
'use strict';
export class TestClassB {
private value: string;
constructor() {
this.value = 'test';
}
}
}
TestClass.spec.ts
'use strict';
describe('test', (): void => {
it ('should create an object', (): void => {
let a: Test.TestClassA = new Test.TestClassA();
expect(a).toBeDefined();
});
});
在Karma.config文件中将文件指定为
files: [
'src/**/*.js',
'test/**/*.spec.js'
],
测试将失败,但TestClassB不是构造函数。
如果我将Karma.config文件指定为 文件:[' src / TestClassB.ts',' src / TestClassA.ts',' test / ** / *。spec.ts']
然后测试将通过。
但是对于包含数百个文件的项目来说,这样做是不可维护的。
答案 0 :(得分:2)
将ES6导入/导出与捆绑器for example with webpack一起使用。
// File TestClassA.ts
import TestClassB from './TestClassB';
export default class TestClassA {
private test: TestClassB;
constructor() {
this.test = new TestClassB();
}
}
// File TestClassB.ts
export default class TestClassB {
private value: string;
constructor() {
this.value = 'test';
}
}
// File tsconfig.json
{
"compilerOptions": {
// ...
"module": "commonjs",
"noEmit": true
}
// ...
}
// File webpack.config.js
var path = require("path");
module.exports = {
entry: path.join(__dirname, "TestClassA.ts"),
output: {
path: __dirname,
filename: "bundle.js"
},
resolve: {
extensions: ["", ".webpack.js", ".web.js", ".ts", ".js"]
},
module: {
loaders: [
{
test: /\.ts$/,
loader: "ts",
query: {
"compilerOptions": {
"noEmit": false
}
}
}
]
}
};
注意:请参阅楼上的链接以了解此配置。
# Install (to run once)
npm install -g webpack typescript
npm install ts-loader typescript
# Make the bundle
webpack
答案 1 :(得分:0)
作为Paleo suggested,首选将代码分成多个文件的方法是使用 modules 而不是命名空间。我一直在努力,命名空间确实更适合创建编译的连接输出,但开发人员和大多数社区都忽略了它。
对于非平凡的项目,您基本上强制使用模块,首选语法为ES6 syntax:
import { ... } from "./path/to/module-file";
这必须由ES6浏览器,< ES6浏览器(RequireJS)的模块加载系统或NodeJS内置模块加载系统来处理。模块肯定有它们的优点,但它们不明显替代名称空间。
然而,我知道有一个理论解决方案:如果你有一个指定的根文件,并且你的命名空间结构反映了目录布局(例如::namespace Test.Helpers
在文件夹中test/helpers
,请参阅下面的链接问题),可以轻松编写一个工具,以递归方式扫描文件中的import X = ...
语句,然后创建一个包含有序列表的_references.ts
文件参考路径。 TypeScript编译器应该完成类似的,但事实并非如此。
在visual studio中进行编译时,会自动识别此_references.ts
文件并将其传递给编译器,但是AFAIK,您也可以手动将该文件传递给编译器,只需:
tsc _references.ts --out test.js
然后还将编译其中引用的文件。
我在使用这种方法时使用了用C#编写的定制的~200行捆绑程序,然后再切换到ES6模块导入语法。您需要注意一些警告:
import X = ...
语句可以使用来自任何名称空间的相对路径。您需要强制自己仅使用绝对命名空间名称,或处理所有情况。