Webpack和TypeScript中的`__extends`

9

我使用TypeScript编写项目。 项目分成许多模块。 我使用Webpack将所有模块捆绑到一个文件中。

对于每个继承自父类的模块类,Webpack都会添加TypeScript __extends助手。 结果是 - 我得到了许多重复的代码。

/***/ },
/* 24 */
/***/ function(module, exports, __webpack_require__) {

"use strict";
var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var DeepExtend_1 = __webpack_require__(6);

//...

exports.SafariDetector = SafariDetector;


/***/ },
/* 25 */
/***/ function(module, exports, __webpack_require__) {

"use strict";
var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var DeepExtend_1 = __webpack_require__(6);

//...

exports.SafariMobileDetector = SafariMobileDetector;

那么,有什么方法可以解决这个问题吗?

1
这是TypeScript编译器检测到“extends”关键字时的默认行为。由于编译器不知道您是否将输出捆绑成一个文件或多个文件,因此它会在关键字出现的任何地方发出代码片段。 - Nick Tsitlakidis
在谷歌上搜索后,我发现了 --noEmitHelpers 标志,它可以禁用辅助程序。但现在我需要手动使用 Webpack 包含所有的 TS 辅助程序 https://www.npmjs.com/package/typescript-helpers。 我现在在家里,但明天我会尝试使用 imports-loader https://webpack.github.io/docs/shimming-modules.html#importing 或其他方法来完成这个任务。 - Качалов Тимофей
3个回答

7
Webpack的ProvidePlugin实际上有一个未记录的功能:您可以使用数组配置它,而不是字符串,并且它将从模块的导出中提取给定对象路径。
这使您可以使用TypeScript的官方tslib模块,该模块导出所有所需的函数。
以下代码适用于webpack@2.2.1:
new webpack.ProvidePlugin({
    '__assign': ['tslib', '__assign'],
    '__extends': ['tslib', '__extends'],
})

请确保强制Webpack使用ES6模块版本的tslib

aliases: {
    'tslib$': 'tslib/tslib.es6.js',
}

并且配置您的 tsc/tsconfig.json,以便不为每个模块发出辅助函数:

{
    "compilerOptions": {
        "noEmitHelpers": true,
    }
}

编辑: 我的文档更新的拉取请求已被合并,因此您现在也可以在官方网站上找到这个内容: https://webpack.js.org/guides/shimming/


5
一种可能的解决方案是将TypeScript配置为在编译时省略这些辅助函数,然后自己编写这些函数并放在一个单独的文件中,最后由webpack打包。在您的tsconfig.json文件上设置compilerOptions.noEmitHelpers为true。创建一个包含__extends函数定义(typescript-helpers)的extends.js,并将其添加到您的webpack捆绑包中。我从未尝试过这样做,但我在这里有类似的关于__awaiter和代码覆盖的处理方式。

是的,谢谢,我在谷歌上找到了相同的解决方案。但是当所有帮助程序都在Webpack模块中时,我该如何正确导入和包含它们? - Качалов Тимофей
看起来 ProvidePlugin 就是我要找的。 - Качалов Тимофей

5
  1. Please look at @goenning's answer and webpack.ProvidePlugin example for that:

    new webpack.ProvidePlugin({
        __extends: path.join(__dirname, './src', 'extends.ts')
    })
    
  2. We could use "importHelpers": true option in the tsconfig: https://www.typescriptlang.org/docs/handbook/compiler-options.html
    But it adds all ts helpers without duplication (I've tried it with ts-loader).

我选择第二个方案,因为它不会增加太多额外的负担。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接