Webpack DefinePlugin未在输出中替换文本

3

我在尝试使用webpack的DefinePlugin时遇到了困难。也就是说,npx webpack命令可以正常运行,但是输出的js文件中未替换定义的token。以下是我最简单的(非)工作示例:

const webpack = require('webpack');

module.exports = {
    // bundling mode
    mode: "development",
    devtool: 'source-map',

    // input file
    entry: "./Index.ts",

    // loaders (e.g. run tsc on *.tsx?)
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                exclude: /node_modules/,
                use: {
                    loader: "ts-loader",
                }
            },
        ]
    },

    plugins: [
        new webpack.DefinePlugin({
            DUMMYVARIABLE: JSON.stringify('helloworld'),
        })
    ],
}

Index.ts

var DUMMYVARIABLE: string;

export class IndexModel {
    public static GetDummyVariable(): string {
        return DUMMYVARIABLE;
    }
}

输出的js文件(请注意,DUMMYVARIABLE仍然存在,而不是像预期的那样被'helloworld'替换):
/******/ (() => { // webpackBootstrap
/******/    "use strict";
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it uses a non-standard name for the exports (exports).
(() => {
var exports = __webpack_exports__;
/*!******************!*\
  !*** ./Index.ts ***!
  \******************/

exports.__esModule = true;
exports.IndexModel = void 0;
var DUMMYVARIABLE;
var IndexModel = /** @class */ (function () {
    function IndexModel() {
    }
    IndexModel.GetDummyVariable = function () {
        return DUMMYVARIABLE;
    };
    return IndexModel;
}());
exports.IndexModel = IndexModel;

})();

/******/ })()
;
//# sourceMappingURL=main.js.map

据我了解,拥有一个名为tsconfig.json的文件至关重要,但其内容并不那么重要-目前我只在里面放了{}
能否有人帮助我理解我做错了什么以及如何让DefinePlugin适用于我?
希望您能原谅我作为一名新手对webpack的陌生,之前我一直把webpack当作一个黑盒子来使用。
1个回答

4
Webpack不能将DUMMYVARIABLE变量替换为"helloworld",因为你没有将其定义为全局变量,而是作为局部变量。为使你的示例起作用,你需要删除var DUMMYVARIABLE;声明,因为脚本中的出现使得Webpack认为DUMMYVARIABLE是一个局部变量。此外,为防止TypeScript中的类型错误,你还应该使用declare告诉TypeScript,DUMMYVARIABLE是全局变量:
declare var DUMMYVARIABLE: string;

export class IndexModel {
    public static GetDummyVariable(): string {
        return DUMMYVARIABLE;
    }
}

现在 webpack.DefinePlugin 将会替换掉如下的出现:

var IndexModel = /** @class */ (function () {
    function IndexModel() {
    }
    IndexModel.GetDummyVariable = function () {
        return "helloworld";
    };
    return IndexModel;
}());

非常感谢你——我既震惊又毫不意外,原来问题如此微小。为了确认我理解得对:DefinePlugin只对全局变量进行替换?这真是太聪明了。 再次感谢。 - Zeph
@Zeph,实际上这与TypeScript无关。在您的index.ts示例的第1行中,您有var DUMMYVARIABLE:string;。这将在作用域中创建一个名为DUMMYVARIABLE的变量。当Webpack看到定义了DUMMYVARIABLE,它决定不替换它。相反,如果您使用declare var DUMMYVARIABLE:string;,则告诉TypeScript它是什么类型的变量,但不告诉Webpack。因此,当Webpack浏览您的代码并未找到定义的DUMMYVARIABLE时,它将使用您在webpack.DefinePlugin中指定的内容进行替换。---回复有点啰嗦,但希望能帮到您。 - Swivel
感谢提供额外的信息,我理解了。 - Zeph
谢谢,这个重要的信息感觉在互联网上其他地方都找不到。没有这个信息时我有时会成功,但这比完全没有成功更奇怪。 - Regular Jo

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