theme: channing-cyan
问题
💢💢在 Nest 项目中,我使用了 file-type 来识别文件类型。就像这样子:
import { fileTypeFromFile } from 'file-type'
这时候控制台就出现了报错:
module.exports = require("file-type");
^
Error [ERR_REQUIRE_ESM]: require() of ES Module xxx\node_modules\file-type\index.js from yyy not supported.
Instead change the require of index.js in yyy to a dynamic import() which is available in all CommonJS modules.
Nest 使用的是 CommonJs 模块,加载 ESModule 的模块时出现了错误。这里是说我们使用了require
导入 ESModule,但是我们用的 file-type 明明是 ESModule 模块。
解决方法
出现这个问题的原因是 Nest-CLI 内置的 Webpack 把所有import
语句都编译成 CommonJs 的形式了。file-type 这个包是 ESModule 形式的,解决方法自然是自定义 Webpack 配置,阻止它把 ESModule 的模块打包成 commonjs 的形式。
这里使用 webpack-node-externals 这个 Webpack 第三方包(??反正它不是 loader,也不是 plugin)。它主要用于排除项目中的内置模块和 node_modules 中的第三方模块,会为被排除的模块创建一个外部函数。例如,我们排除了 file-type 这个库,在打包完成后的 ./dist/main.js 中,在最外层的代码可以找到 file-type 这个库中导出的函数:
// ...
async function fileTypeFromStream(stream) {
return new FileTypeParser().fromStream(stream);
}
async function fileTypeFromBuffer(input) {
return new FileTypeParser().fromBuffer(input);
}
async function fileTypeFromBlob(blob) {
return new FileTypeParser().fromBlob(blob);
}
// ...
修改 Webpack 配置
找到项目根目录的 nest-cli.json,compilerOptions
加入webpack
和webpackConfigPath
的属性:
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true,
"webpack": true,
"webpackConfigPath": "./webpack.config.js"
}
}
./webpack.config.js 就是自定义 Webpack 配置的路径,在项目根目录新建 webpack.config.js。使用 webpack-node-externals 来忽略转换指定的模块或者文件,把涉及到的包都扔进去。
const fs = require('fs')
const path = require('path')
const nodeExternals = require('webpack-node-externals');
const appDirectory = fs.realpathSync(process.cwd());
module.exports = function (options, webpack) {
console.log('My Webpack Config ...');
return {
...options,
resolve: {
extensions: [".ts", ".js"],
alias: {
'src': path.resolve(appDirectory, 'src')
}
},
externals: [
nodeExternals({
allowlist: ['file-type', /^strtok3/, 'peek-readable', 'token-types']
})
],
}
}
重新运行就跑起来了。
结语
初次用 Nest 做了个练习性的小项目,一开始对 Nest 中 webpack 的配置又不太了解,遇到问题还是花了不少时间的。这也是熟悉了一下 Node.js 的打包。
有什么不足请批评指正...... 大家的阅读是我发帖的动力。
本文首发于我的博客:deerblog.gu-nami.com/