【发布时间】: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'
}
},
};
main.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}`);
});
【问题讨论】:
-
你能用webpack-node-externals提取所有的npm模块吗? (这需要
npm i才能使用,但会使您的捆绑包显着变小。 -
如果我理解正确
webpack-node-externals将从供应商捆绑包中排除所有 node_modules。我遇到的问题是“main”无法加载“vendor”包中的依赖项。
标签: node.js typescript webpack commonjs code-splitting