【问题标题】:Webpack code splitting not working for NodeJs appWebpack 代码拆分不适用于 NodeJs 应用程序
【发布时间】:2020-09-26 11:21:13
【问题描述】:

我正在使用 Webpack (4.43.0) 对 AWS Lambda 的 NodeJS 应用程序进行代码拆分。我有一个 main 包,它很小,包含我编写的代码,我有一个 vendors 包,它很大,包含所有(摇树)node_modules 依赖项,如 Express.JS。问题是当我运行主块(使用node ./dist/main.js)时,它无法解决vendors 包中的依赖关系。通读输出代码,我看不出它如何解析 vendors 模块,因为 main 没有办法解决它们。

我收到的错误是:

modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
TypeError: Cannot read property 'call' of undefined

读取dist/main.js中的代码输出,Webpack bootstrap 函数接收到以下模块列表:

[
  './node_modules/express/lib sync recursive',
  './src/main.ts',
  'buffer',
  'crypto',
  'events',
  'fs',
  'http',
  'net',
  'path',
  'querystring',
  'stream',
  'string_decoder',
  'tty',
  'url',
  'util',
  'zlib'
]

./src/main.ts 是入口点,在这里执行:

/******/    // Load entry module and return exports
/******/    return __webpack_require__(__webpack_require__.s = "./src/main.ts");

此模块尝试包含./node_modules/express/index.js,这会引发错误,因为它在初始模块列表中不存在:

/******/    // The require function
/******/    function __webpack_require__(moduleId) {
/******/
/******/        // Check if module is in cache
/******/        if(installedModules[moduleId]) {
/******/            return installedModules[moduleId].exports;
/******/        }
/******/        // Create a new module (and put it into the cache)
/******/        var module = installedModules[moduleId] = {
/******/            i: moduleId,
/******/            l: false,
/******/            exports: {}
/******/        };
/******/
/******/        // Execute the module function
/******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/        // Flag the module as loaded
/******/        module.l = true;
/******/
/******/        // Return the exports of the module
/******/        return module.exports;
/******/    }

如果我手动注入以下代码以将“供应商”模块导入模块列表,代码将正常工作,但这不是一个理想的解决方案。

const vendor = require('./vendors~main.js');
Object.keys(vendor.modules).forEach((mod) => {
  modules[mod] = vendor.modules[mod];
});

有人知道使“供应商”模块可用的正确方法吗?

webpack.config.js

const path = require('path');

module.exports = {
    mode: 'development',
    target: 'node',
    entry: './src/main.ts',
    output: {
        path: path.join(__dirname, './dist'),
        filename: '[name].js',
        libraryTarget: 'commonjs',
    },
    resolve: {
        extensions: [ '.tsx', '.ts', '.js' ],
    },
    module: {
        rules: [
            { test: /\.ts$/, use: 'ts-loader' }
        ]
    },
    optimization: {
        sideEffects: false,
        namedModules: true,
        namedChunks: true,
        splitChunks: {
            chunks: 'all'
        }
    },
};

ma​​in.ts

import express from 'express';
const port = 3000;
const app = express();

app.get('*', (req: express.Request, res: express.Response) => {
    res.send('Working');
});

app.listen(port, () => {
    console.log(`Listening on port ${port}`);
});

我设置了一个演示仓库https://github.com/rjenkin/nodejscodesplit

【问题讨论】:

  • 你能用webpack-node-externals提取所有的npm模块吗? (这需要npm i 才能使用,但会使您的捆绑包显着变小。
  • 如果我理解正确webpack-node-externals 将从供应商捆绑包中排除所有 node_modules。我遇到的问题是“main”无法加载“vendor”包中的依赖项。

标签: node.js typescript webpack commonjs code-splitting


【解决方案1】:

显然目标:“节点”不支持带有块:“初始”或块:“全部”的拆分块。 https://github.com/webpack/webpack/issues/7392

【讨论】:

    猜你喜欢
    • 2020-03-03
    • 2016-09-30
    • 2017-11-06
    • 2020-01-10
    • 2018-04-28
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    相关资源
    最近更新 更多