如果不直接使用,WebPack 包中不包含导出的 TypeScript 类 [英] Exported TypeScript Class not included in WebPack bundle if not used directly

查看:34
本文介绍了如果不直接使用,WebPack 包中不包含导出的 TypeScript 类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将一个带有 Angular 1.x 的 javascript 项目转换为 WebPack 和 TypeScript(使用 ts-loader).我大部分时间都在工作,但是当 ts-loader 似乎在没有直接使用导出的情况下优化我的脚本时,我遇到了麻烦.

I'm converting a javascript project with Angular 1.x to WebPack and TypeScript (using ts-loader). I got it mostly working, but I'm running into trouble when ts-loader seems to be optimizing my scripts out of the bundle when the exports are not directly used.

这是一个演示问题的示例项目(npm install、webpack,然后加载 index.html 并观察控制台).

Here's a sample project demonstrating the issue (npm install, webpack, then load index.html and watch the console).

https://github.com/bbottema/webpack-typescript

来自 ClassA 的日志记录显示,但 angular 报告 ClassB 丢失(提供程序).如果您查看 bundle.js,您会发现 ClassB 完全丢失了.不同的是ClassA导入后直接开始使用,ClassB只被类型引用编译.

The logging from ClassA is showing up, but angular is reporting ClassB missing (provider). If you look in bundle.js you'll notice ClassB missing entirely. The difference is ClassA begin use directly after importing, and ClassB is only referenced by type for compilation.

这是一个错误,还是有办法强制包含 ClassB?还是我做错了?Angular 2 可能会解决这个问题,但现在这一步太大了.

Is it a bug, or is there a way to force ClassB to be included? Or am I going about it wrong? Angular 2 would probably solve this issue, but that's a step too large right now.

上述项目的相关脚本:

package.json

package.json

{
    "devDependencies": {
        "typescript": "^1.7.5",
        "ts-loader": "^0.8.1"
    },
    "dependencies": {
        "angular": "1.4.9"
    }
}

webpack.config.js

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

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>

入口.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;

推荐答案

原来是你必须通过在没有 import 语句的情况下添加额外的 require 调用来通知 WebPack 显式包含一个模块.

Turns out you have to signal WebPack to explicitly include a module by adding an extra require call without import statement.

我还没有准备好通过添加重复导入来破坏我的 .ts 文件,所以我使用 预处理器加载器:

I'm not ready to mangle my .ts files by adding duplicate imports, so I made a generic solution for that using the preprocessor loader:

{
    "line": false,
    "file": true,
    "callbacks": {
    "fileName": "all",
    "scope": "line",
    "callback": "(function fixTs(line, fileName, lineNumber) { return line.replace(/^(import.*(require\\(.*?\\)))/g, '$2;$1'); })"
    }]
}

作为概念证明,此正则表达式版本非常有限,仅支持以下格式:

As a proof of concept, this regex version is very limited it only support the following format:

import ClassA = require('ClassA');
// becomes
require('ClassA');import ClassA = require('ClassA');

但它对我有用.同样,我添加了需要垫片:

But it works for me. Similarly, I'm adding the require shim:

{
    "fileName": "all",
    "scope": "source",
    "callback": "(function fixTs(source, fileName) { return 'declare var require: any;' + source; })"
}

我用这个解决方案制作了一个示例项目.

I made a sample project with this solution.

这篇关于如果不直接使用,WebPack 包中不包含导出的 TypeScript 类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆