如果不直接使用,导出的 TypeScript Class 不包含在 WebPack 包中
Exported TypeScript Class not included in WebPack bundle if not used directly
我正在将 Angular 1.x 的 javascript 项目转换为 WebPack 和 TypeScript(使用 ts-loader)。我大部分时间都在使用它,但是当 ts-loader 似乎在不直接使用导出时从捆绑包中优化我的脚本时,我 运行 遇到了麻烦。
这是一个演示问题的示例项目(npm 安装、webpack,然后加载 index.html 并观察控制台)。
https://github.com/bbottema/webpack-typescript
显示来自 ClassA 的日志记录,但 angular 报告缺少 ClassB(提供者)。如果您查看 bundle.js,您会发现 ClassB 完全缺失。不同的是ClassA导入后直接使用,而ClassB编译时只按类型引用
这是一个错误,还是有办法强制包含 ClassB?还是我做错了? Angular 2 可能会解决这个问题,但现在这一步太大了。
上述项目的相关脚本:
package.json
{
"devDependencies": {
"typescript": "^1.7.5",
"ts-loader": "^0.8.1"
},
"dependencies": {
"angular": "1.4.9"
}
}
webpack.config.js
var path = require('path');
module.exports = {
entry: {
app: './src/entry.ts'
},
output: {
filename: './dist/bundle.js'
},
resolve: {
root: [
path.resolve('./src/my_modules'),
path.resolve('node_modules')
],
extensions: ['', '.ts', '.js']
},
module: {
loaders: [{
test: /\.tsx?$/,
loader: 'ts-loader'
}]
}
};
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs"
},
"exclude": [
"node_modules"
]
}
index.html
<!doctype html>
<html ng-app="myApp">
<body>
<script src="dist/bundle.js"></script>
</body>
</html>
entry.js
declare var require: any;
'use strict';
import ClassA = require('ClassA');
import ClassB = require('ClassB');
var a:ClassA = new ClassA(); // direct use, this works
var angular = require('angular');
angular.module('myApp', []).
// this compiles as it should, but in runtime the provider will not be packaged and angular will throw an error
run(function(myProvider: ClassB) {
}
);
ClassA.ts
// this line will be logged just fine
console.log('ClassA.ts: if you see this, then ClassA.ts was packaged properly');
class ClassA {
}
export = ClassA;
ClassB.ts
declare var require: any;
// this line is never logged
console.log('ClassB.ts: if you see this, then ClassB.ts was packaged properly');
class ClassB {
}
var angular = require(angular);
angular.module('myApp').service(new ClassB());
export = ClassB;
Turns out you have to signal WebPack 通过添加一个没有 import
语句的额外 require
调用来显式包含模块。
我还没有准备好通过添加重复的导入来破坏我的 .ts 文件,所以我使用 preprocessor loader:
做了一个通用的解决方案
{
"line": false,
"file": true,
"callbacks": {
"fileName": "all",
"scope": "line",
"callback": "(function fixTs(line, fileName, lineNumber) { return line.replace(/^(import.*(require\(.*?\)))/g, ';'); })"
}]
}
作为概念验证,此正则表达式版本非常有限,仅支持以下格式:
import ClassA = require('ClassA');
// becomes
require('ClassA');import ClassA = require('ClassA');
但这对我有用。同样,我要添加 :
{
"fileName": "all",
"scope": "source",
"callback": "(function fixTs(source, fileName) { return 'declare var require: any;' + source; })"
}
我用这个解决方案做了一个sample project。
我正在将 Angular 1.x 的 javascript 项目转换为 WebPack 和 TypeScript(使用 ts-loader)。我大部分时间都在使用它,但是当 ts-loader 似乎在不直接使用导出时从捆绑包中优化我的脚本时,我 运行 遇到了麻烦。
这是一个演示问题的示例项目(npm 安装、webpack,然后加载 index.html 并观察控制台)。
https://github.com/bbottema/webpack-typescript
显示来自 ClassA 的日志记录,但 angular 报告缺少 ClassB(提供者)。如果您查看 bundle.js,您会发现 ClassB 完全缺失。不同的是ClassA导入后直接使用,而ClassB编译时只按类型引用
这是一个错误,还是有办法强制包含 ClassB?还是我做错了? Angular 2 可能会解决这个问题,但现在这一步太大了。
上述项目的相关脚本:
package.json
{
"devDependencies": {
"typescript": "^1.7.5",
"ts-loader": "^0.8.1"
},
"dependencies": {
"angular": "1.4.9"
}
}
webpack.config.js
var path = require('path');
module.exports = {
entry: {
app: './src/entry.ts'
},
output: {
filename: './dist/bundle.js'
},
resolve: {
root: [
path.resolve('./src/my_modules'),
path.resolve('node_modules')
],
extensions: ['', '.ts', '.js']
},
module: {
loaders: [{
test: /\.tsx?$/,
loader: 'ts-loader'
}]
}
};
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs"
},
"exclude": [
"node_modules"
]
}
index.html
<!doctype html>
<html ng-app="myApp">
<body>
<script src="dist/bundle.js"></script>
</body>
</html>
entry.js
declare var require: any;
'use strict';
import ClassA = require('ClassA');
import ClassB = require('ClassB');
var a:ClassA = new ClassA(); // direct use, this works
var angular = require('angular');
angular.module('myApp', []).
// this compiles as it should, but in runtime the provider will not be packaged and angular will throw an error
run(function(myProvider: ClassB) {
}
);
ClassA.ts
// this line will be logged just fine
console.log('ClassA.ts: if you see this, then ClassA.ts was packaged properly');
class ClassA {
}
export = ClassA;
ClassB.ts
declare var require: any;
// this line is never logged
console.log('ClassB.ts: if you see this, then ClassB.ts was packaged properly');
class ClassB {
}
var angular = require(angular);
angular.module('myApp').service(new ClassB());
export = ClassB;
Turns out you have to signal WebPack 通过添加一个没有 import
语句的额外 require
调用来显式包含模块。
我还没有准备好通过添加重复的导入来破坏我的 .ts 文件,所以我使用 preprocessor loader:
做了一个通用的解决方案{
"line": false,
"file": true,
"callbacks": {
"fileName": "all",
"scope": "line",
"callback": "(function fixTs(line, fileName, lineNumber) { return line.replace(/^(import.*(require\(.*?\)))/g, ';'); })"
}]
}
作为概念验证,此正则表达式版本非常有限,仅支持以下格式:
import ClassA = require('ClassA');
// becomes
require('ClassA');import ClassA = require('ClassA');
但这对我有用。同样,我要添加
{
"fileName": "all",
"scope": "source",
"callback": "(function fixTs(source, fileName) { return 'declare var require: any;' + source; })"
}
我用这个解决方案做了一个sample project。