Luc*_*sky 6 commonjs node.js webpack es6-modules webpack-5
我如何告诉 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.typeis 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',
},
},
};
Run Code Online (Sandbox Code Playgroud)
示例堆栈跟踪:
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)
Run Code Online (Sandbox Code Playgroud)
该支持是在 webpack 版本 5.76 和 5.81 之间添加的,截至 2023 年 6 月版本 5.88.0 支持 ESM 模块作为加载器
由于未合并 PR,目前不可能将其开箱即用,但我设法为其开发了一个解决方法插件。
首先我查看了loadLoader从哪里获取数据。它来自LoaderRunner.js,webpack 使用中间对象并在调用堆栈中导航,我发现了以下代码:
try {
hooks.beforeLoaders.call(this.loaders, this, loaderContext);
} catch (err) {
processResult(err);
return;
}
Run Code Online (Sandbox Code Playgroud)
这告诉我可以通过钩子更改中间对象,并通过在 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'
}
}
}
)
})
}
}
Run Code Online (Sandbox Code Playgroud)
也不确定是否相关,这是我的加载器文件夹的配置部分,它告诉 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']
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1860 次 |
| 最近记录: |