我如何告诉 Webpack 它应该将我的加载器视为 ES 模块而不是 CommonJS?
我的目标是写一个使用ES Module语法的Loader(
export default...
)
演示(不工作):https://stackblitz.com/edit/webpack-webpack-js-org-7gmdc8?file=webpack.config.js
显然 Webpack 正在尝试将模块加载为 CommonJS。如果您查看 loadLoader,条件
loader.type === "module"
失败,因为 loader.type
是 undefined
.
// webpack.conf.js:
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/app.js',
output: {
filename: 'app.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
module: {
rules: [
{
test: /\.js$/,
use: ['my-loader'],
},
],
},
resolveLoader: {
alias: {
// WEBPACK IS TRYING TO LOAD THIS AS COMMONJS... WHY???
'my-loader':
'/home/projects/webpack-webpack-js-org-7gmdc8/my-loader/main.mjs',
},
},
};
示例堆栈跟踪:
ERROR in ./index.js
Module build failed (from ../my-webpack-loader-esm/dist/index.bundle.mjs):
Error [ERR_REQUIRE_ESM]: require() of ES Module /workspaces/webpack-loader-lab/my-webpack-loader-esm/dist/index.bundle.mjs not supported.
Instead change the require of /workspaces/webpack-loader-lab/my-webpack-loader-esm/dist/index.bundle.mjs to a dynamic import() which is available in all CommonJS modules.
at loadLoader (/workspaces/webpack-loader-lab/the-client/node_modules/loader-runner/lib/loadLoader.js:23:17)
由于未合并 PR,它目前不可能开箱即用,但我设法为它开发了一个解决方法插件。
首先,我查看了
loadLoader
从哪里获取数据。它来自LoaderRunner.js,webpack正在使用中间对象并向上导航我发现以下代码的调用堆栈:
try {
hooks.beforeLoaders.call(this.loaders, this, loaderContext);
} catch (err) {
processResult(err);
return;
}
这告诉我可以通过钩子更改中间对象,并通过在 webpack 代码中搜索
beforeLoaders
我能够找到为此目的调整的示例插件,结果如下:
import NormalModule from 'webpack/lib/NormalModule.js'
const pluginName = 'MjsLoaderPlugin'
export default class MjsLoaderPlugin {
apply(compiler) {
compiler.hooks.compilation.tap(pluginName, compilation => {
NormalModule.getCompilationHooks(compilation).beforeLoaders.tap(
pluginName,
(loaders, normalModule) => {
/*
loader = {
loader: 'F:\\<blah blah>\\webpack-loaders\\my-module-loader.mjs',
options: 'name=value',
ident: undefined
}
*/
for(let loader of loaders) {
if(loader.loader.endsWith(".mjs")) {
loader.type = 'module'
}
}
}
)
})
}
}
也不确定是否相关,这是我的加载程序文件夹的配置部分,告诉 webpack 它可以自动搜索此文件夹中的 mjs 加载程序
import { dirname, resolve } from 'path'
import { fileURLToPath } from 'url'
const __dirname = dirname(fileURLToPath(import.meta.url))
export default {
resolveLoader: {
modules: [
'node_modules',
resolve(__dirname, 'tools/webpack-loaders')
],
extensions: ['.js', '.mjs']
}
}