【问题标题】:Babel can't resolve imports in it its own source codeBabel 无法在它自己的源代码中解析导入
【发布时间】:2021-01-27 15:33:44
【问题描述】:

我已经将一个 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/运行时导入的末尾添加 .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 babeljs


    【解决方案1】:

    通过添加以下模块规则,我能够在 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 文件中的模块时,当它们最近的父 package.json 文件包含值为“module”的“type”字段时,您应该提供文件扩展名, 否则 webpack 会因为找不到 Module 错误而导致编译失败

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

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

    { "type": "module" }

    在他们的 package.json 中。

    【讨论】:

    • 它有帮助,但你能告诉更多原因吗?
    • 我已经用更多细节修改了答案@Marcin
    猜你喜欢
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-19
    • 1970-01-01
    • 2017-11-13
    • 2017-10-05
    • 2018-12-08
    相关资源
    最近更新 更多