Webpack配置中如何正确配置Express外部依赖解决ES模块报错
问题描述
项目package.json中设置了"type": "module",使用Webpack构建Node服务,配置webpack-node-externals排除node_modules依赖后,打包生成的外部依赖(如express)代码为:
/***/ ((module) => { module.exports = require("express"); /***/ }),
运行时触发报错:
module.exports = require("express"); ^
ReferenceError: require is not defined in ES module scope, you can use
import instead This file is being treated as an ES module because it
has a '.js' file extension and
'/test/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
期望生成的外部依赖引用形式为:
/***/ ((module) => { module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("express"); /***/ }),
当前核心Webpack配置:
import nodeExternals from 'webpack-node-externals'; const config: webpack.Configuration = { experiments: { outputModule: true, }, externals: [ nodeExternals(), ], output: { filename: '[name].js', path: output, publicPath: '/node/', chunkFormat: 'module', }, target: 'node', // ...其他配置 };
服务入口server.ts代码:
import express from 'express'; const app = express(); app.get('/', (request, response) => { response.send('Hi there'); }); app.listen(3000, () => { console.log('Listen on the port 3000...'); });
解决方法
修改webpack-node-externals的配置,添加importType: 'module'选项,让它生成适配ES模块的外部引用代码:
externals: [ nodeExternals({ importType: 'module' }), ],
原理说明
默认情况下webpack-node-externals会生成CommonJS风格的require()引用,但当项目启用ES模块("type": "module")时,这种写法会触发运行时错误。通过设置importType: 'module',该工具会自动生成Webpack兼容的ES模块外部引用逻辑,使用__WEBPACK_EXTERNAL_createRequire(import.meta.url)加载依赖,完全匹配期望的代码形式。
无需单独将express添加到externals数组中,webpack-node-externals会自动排除所有node_modules内的依赖。
内容的提问来源于stack exchange,提问作者qwerty

