Babel 无法解析导入自己的源代码



我已经升级了一个React项目到Webpack 5。别名由Babel解析。在Webpack 4中一切都运行良好。但是当启动webpack开发服务器时,Babel会导致构建崩溃,因为它无法解析自己的导入(在源代码中)。

我检查了Babel运行时的节点模块。一切看起来都很好:

// from the file babel/runtime/helpers/esm/toConsumableArray.js
import arrayWithoutHoles from "./arrayWithoutHoles";
import iterableToArray from "./iterableToArray";
import unsupportedIterableToArray from "./unsupportedIterableToArray";
import nonIterableSpread from "./nonIterableSpread";
export default function _toConsumableArray(arr) {
return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) 
|| nonIterableSpread();
}

我的终端显示以下错误:

ERROR in ../../node_modules/@babel/runtime/helpers/esm/toConsumableArray.js 4:0-52
Module not found: Error: Can't resolve './nonIterableSpread' in '/Users/MyNamee/Desktop/MyApp/node_modules/@babel/runtime/helpers/esm'
Did you mean 'nonIterableSpread.js'?
BREAKING CHANGE: The request './nonIterableSpread' failed to resolve only because it was resolved as fully specified
(probably because the origin is a '*.mjs' file or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.
@ ../../node_modules/rc-slider/es/Range.js 2:0-78 77:43-61 193:23-41 337:23-41
@ ../../node_modules/rc-slider/es/index.js 2:0-28 6:23-28 10:0-50
@ ../../kit/src/form/slider/index.tsx
@ ../../kit/src/form/index.tsx 27:41-71
@ ../shared/src/panels/card-library/index.tsx 10:15-38
@ ./src/pages/main.tsx 12:47-93
@ ./src/app.tsx 11:39-82
@ ./src/index.tsx 6:38-54

我知道这个问题来自别名解决方案,因为我在webpack中注释别名:{}部分时没有得到这些错误(别名是由babel别名自动填充的):

const { isArray, size, get, find, reduce } = require("lodash");
const path = require("path");
const BabelConfig = require("../../../babel.config");
const findModuleResolverPlugin = (plugins) => {
return (
find(plugins, (plugin) => {
return isArray(plugin) && plugin[0] === "module-resolver";
}) || []
);
};
const getModuleResolverAliasPlugin = (configuration = {}) => {
const plugin = findModuleResolverPlugin(configuration.plugins);
if (size(plugin)) {
return get(plugin[1], "alias", {});
} else {
return {};
}
};
const getBabelAliases = (rootPath = "") => {
return reduce(
getModuleResolverAliasPlugin(BabelConfig),
(aliases, p, alias) => {
aliases[alias] = path.resolve(rootPath, p);
return aliases;
},
{}
);
};
module.exports = getBabelAliases;

所以问题似乎是我需要在每个Babel/runtime导入结束时添加.js。这当然是不现实的。我该怎么做才能解决这个问题?

这是我的Babel配置:


module.exports = {
ignore: ["node_modules"],
babelrcRoots: ["."],
presets: [
"@babel/preset-typescript",
[
"@babel/preset-env",
{
targets: {
browsers: ["defaults"],
},
},
],
"@babel/preset-react",
],
env: {
test: {
plugins: [
[
"babel-plugin-react-css-modules",
{
generateScopedName: "[local]",
filetypes: {
".less": {
syntax: "postcss-less",
},
},
},
],
//
],
},
development: {
plugins: [
[
"babel-plugin-react-css-modules",
{
webpackHotModuleReloading: true,
generateScopedName: "[local]___[hash:base64:5]",
handleMissingStyleName: "warn",
filetypes: {
".less": {
syntax: "postcss-less",
},
},
},
],
// "react-hot-loader/babel"
],
},
production: {
plugins: [
[
"babel-plugin-react-css-modules",
{
webpackHotModuleReloading: true,
generateScopedName: "[hash:base64]",
filetypes: {
".less": {
syntax: "postcss-less",
},
},
},
],
],
},
},
plugins: [
"@babel/plugin-transform-object-assign",
"@babel/plugin-transform-regenerator",
"@babel/plugin-transform-runtime",
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-transform-modules-commonjs",
["@babel/plugin-proposal-class-properties", { loose: true }],
[
"module-resolver",
{
cwd: "babelrc",
root: "./",
alias: {
"@components": "./components/src",
"@pages": "./pages/src",
"@assets": "./assets",
},
},
],
],
};

任何帮助都将非常感激!

我能够通过添加以下模块规则来解决webpack 4到5升级时的相同问题:

// see  https://github.com/webpack/webpack/issues/11467#issuecomment-808618999/
// for details
const webpack5esmInteropRule = {
test: /.m?js/,
resolve: {
fullySpecified: false
}
};
config.module.rules = [ webpack5esmInteropRule, ...otherRules ]

如果webpack被要求在编译周期中需要一个mjs文件,它需要关于如何处理这些文件类型的明确细节。fullySpecified的用法可能是您的特殊情况所特有的,这里有关于该行为的更多文档:

fullySpecified当启用时,当在.mjs文件或任何其他.js文件中导入模块时,当它们最近的父包时,应该提供文件扩展名。Json文件包含一个"类型"字段的值为" Module ",否则webpack将编译失败,并显示Module not found错误

https://webpack.js.org/configuration/module/resolvefullyspecified

对我来说,我认为这个问题的发生是因为我的一个node_modules需要一个mjs文件(但不带扩展名),或者可能有:

{ "type": "module" }

在package.json.

最新更新