网站搜索

typescript - 如何让 splitChunks 生成 commonjs 的 require() 语句?


我有以下的 Webpack 配置。我的应用程序由一堆部署到 AWS Lambda 的脚本组成,因此目标环境是 Node 和 CommonJS。每个脚本都是入口点,不过为了举例,我把入口点限制为两个。

这些入口点通常使用彼此相同的库/依赖,因此生成的文件包含大量重复,我正在尝试减少这些重复。

我添加了包含 splitChunks 的 optimization 部分,/dist 中的输出文件看起来好很多。每个入口文件都大大减小了,而新的 vendor.js 文件则大了很多。总文件大小减少了超过 5 倍。

问题是,这样做已经破坏了我的应用程序。它无法再正确解析依赖关系。我将 Webpack 设置为开发模式,以便我可以浏览输出。我检查了生成的 add-comment.js 文件,里面没有任何类似 require('./vendor.js') 的引用,实际上完全没有使用到 'vendor' 这个词。

有没有某种配置可以更改,以便每个入口点都能获得对 vendor.js 的引用?或者也许我误解了它的工作方式?

module.exports = [
    {
        name: 'Server',
        mode: 'development',
        entry: {
            'add-comment': './server/add-comment.ts',
            'delete-comment': './server/delete-comment.ts'
        },
        output: {
            filename: 'server/[name].js',
            libraryTarget: 'commonjs'
        },
        target: 'node',
        resolve: {
            extensions: ['.ts', '.js']
        },
        module: {
            rules: [
                {
                    test: /\.ts$/,
                    exclude: /node_modules/,
                    use: [{
                        loader: 'ts-loader',
                        options: {
                            configFile: "server/tsconfig.json"
                        }
                    }]
                }
            ]
        },
        externals: ['aws-sdk'],
        optimization: {
            splitChunks: {
                name: 'vendor',
                chunks: 'all'
            }   
        }
    }
]

不确定这是否相关,但这是我的 tsconfig。"module": "commonjs" 和其他一些东西是通过 extends 指令引入的。其余如下

{
    "$schema": "https://json.schemastore.org/tsconfig",
    "extends": "@tsconfig/node14/tsconfig.json",
    "compilerOptions":
    {
        "moduleResolution": "node",
        "target": "ES2019",
        "strict": false,
        "types": ["jest", "webpack-env"]
    }
}

如果我使用 HtmlWebpackPlugin(这不适用于我的情况,因为我的目标是 Node,而不是浏览器),那么它将按以下顺序生成脚本。

<script src="server/vendor.js"></script>
<script src="server/add-comment.js"></script>
<script src="server/delete-comment.js"></script>

所以 Webpack 显然知道那个 vendor 需要先加载,但我的配置有某些问题,导致它不理解我的代码是如何被调用的。我已经有 target: 'node' 了,也许我还需要别的东西。

答案#1

这已经在 Webpack 5 中实现。据我所知,没有计划将其回移植。

Webpack 4 和 Webpack 5 之间存在不兼容。output 部分需要更改为如下内容:

output: {
    filename: 'server/[name].js',
    library {
        type: 'commonjs'
    }
},