由于ES6的扩展语法,Webpack和Babel不会在node_modules内部转换依赖项,该依赖项会破坏IE 11和Edge [英] Webpack and Babel not transpiling a dependency inside node_modules that breaks IE 11 and Edge due to ES6's spread syntax

查看:295
本文介绍了由于ES6的扩展语法,Webpack和Babel不会在node_modules内部转换依赖项,该依赖项会破坏IE 11和Edge的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用 @ mdx-js/runtime 的项目,它在IE 11或Edge( Edge 44.18362.449.0 )上完全损坏:

I have a project that uses @mdx-js/runtime and it completely breaks on IE 11 or Edge (Edge 44.18362.449.0):

SCRIPT1028: SCRIPT1028: Expected identifier, string or number

实际上由于在此处的传播语法而中断:

It actually breaks because of the spread syntax here:

const allNodes = sortedNodes.map(({ start: _, ...node }, i) => { 

此行代码来自 remark-mdx ,它是 @ mdx-js/runtime 的依赖项,尤其是以下文件和行:

This line of code comes from remark-mdx, which is a dependency of @mdx-js/runtime, particularly this file and line: https://github.com/mdx-js/mdx/blob/master/packages/remark-mdx/extract-imports-and-exports.js#L66

我一直在尝试让Webpack和Babel对该文件进行转换,以使传播不再存在:

I've been trying to get Webpack and Babel to transform that file so that the spread is no longer there:

浏览器列表:

如果运行 npx browserslist ,我可以看到IE 11.

If I run npx browserslist I can see IE 11 is there.

"browserslist": [
    "> 0.5%",
    "last 2 version",
    "Firefox ESR",
    "not dead",
    "iOS >= 9"
]

.babelrc:

我尝试禁用 loose 模式并添加 @ babel/plugin-transform-spread @ babel/plugin-proposal-object-rest-spread,但没有解决问题.

I've tried disabling loose mode and adding @babel/plugin-transform-spread and @babel/plugin-proposal-object-rest-spread, but didn't fix the issue.

  {
    "presets": [[
        "@babel/preset-env", {
            "useBuiltIns": "usage",
            "loose": false, // Was true before
            "modules": "auto",
            "corejs": 3
        }],
        "@babel/preset-react",
        "@babel/preset-typescript"
    ],

    "plugins": [
        ["@babel/plugin-proposal-decorators", {
            "legacy": true
        }],
        ["@babel/plugin-proposal-class-properties", {
            "loose": true
        }],
        "@babel/plugin-transform-spread", // Just added
        "@babel/plugin-proposal-object-rest-spread", // Just added
        "@babel/plugin-proposal-optional-chaining",
        "@babel/plugin-proposal-nullish-coalescing-operator",
        "react-hot-loader/babel"
    ]
}

webpack.config.js:

webpack.config.js:

在这里,我尝试显式包括 remark-mdx @ mdx-js/runtime ,还删除了 exclude 属性或将其更改为<代码>/node_modules \/(?!(remark-mdx | @ mdx-js \/runtime)\/).*/,但似乎无济于事:

Here I tried explicitly including remark-mdx and @mdx-js/runtime and also removing the exclude property or changing it to /node_modules\/(?!(remark-mdx|@mdx-js\/runtime)\/).*/, but nothing seems to work:

  {
    test: /\.(j|t)sx?$/,
    include: [
      path.resolve(__dirname, 'src'),
      // Tried explicitly adding these 2:
      path.resolve('node_modules/remark-mdx'),
      path.resolve('node_modules/@mdx-js/runtime'),
    ],
    // Tried removing `exclude` or not excluding those 2 packages:
    // exclude: /node_modules/,
    // exclude: /node_modules\/(?!(remark-mdx|@mdx-js\/runtime)\/).*/,
    use: [{
      loader: 'babel-loader',
      options: {
        cacheDirectory: true,
        babelrc: true,
      }
    }],
  }

我正在使用Babel 7和Webpack 4.

I'm using Babel 7 an Webpack 4.

推荐答案

好吧,事实证明,要处理 node_modules 内部的文件,您需要使用 babel.config.js 而不是此处

Ok, it turns out to process files inside node_modules you need to use babel.config.js rather than .babelrc as explained here and here:

您的用例是什么?

  • 您正在使用monorepo吗?
  • 您要编译node_modules吗?

  • You are using a monorepo?
  • You want to compile node_modules?

babel.config.json 适合您!

您的配置仅适用于项目的单个部分吗?

You have a configuration that only applies to a single part of your project?

.babelrc.json 适合您!

此外,如果您使用的是monorepo,则需要设置 rootMode:'upward' ,以便Babel可以找到您的新配置文件,如此处所述.

Also, if you are using a monorepo you need to set rootMode: 'upward' so that Babel can find your new config file, as explained here.

Webpack的 babel-loader 配置应如下所示:

Webpack's babel-loader config should look something like this:

  {
    test: /\.(j|t)sx?$/,
    include: [
      path.resolve(__dirname, 'src'),
      // No need to add @mdx-js/runtime, just add the problematic package:
      path.resolve('node_modules/remark-mdx'),
    ],
    // You also need to exclude it from the exclusions:
    exclude: /node_modules\/(?!(remark-mdx)\/).*/,
    use: [{
      loader: 'babel-loader',
      options: {
        cacheDirectory: true,
        // And replace .babelrc with babel.config.json...
        babelrc: false,
        // ...which might also mean you need this if you are using a monorepo:
        rootMode: 'upward',
      }
    }],
  }

此更改后,正在处理文件,但出现另一个错误:

After this change the file was being processed, but I was getting a different error:

Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'

在这种情况下,我必须添加 sourceType:明确" babel.config.json ,因为 remark-mdx 使用的是CommonJS模块而不是ES6模块.您可以将其添加到 babel.config.json 文件的根目录或 overrides ,因此它仅定位 node_modules 内部的包.

In this case, I had to add sourceType: "unambiguous" to babel.config.json, as remark-mdx was using CommonJS modules rather than ES6 ones. You can add this at the root of your babel.config.json file or inside overrides, so that it only targets packages inside node_modules.

有关发生这种情况的更多信息,请参见

For more on why this happens, see How do I use babel's `useBuiltIns: 'usage'` option on the vendors bundle?.

Babel的 babel.config.json 最终看起来像这样:

Babel's babel.config.json ended up looking like this:

{
    "presets": [[
        "@babel/preset-env", {
            "useBuiltIns": "usage",
            "loose": true,
            "modules": "auto",
            "corejs": 3
        }],
        "@babel/preset-react",
        "@babel/preset-typescript"
    ],

    "plugins": [
        ["@babel/plugin-proposal-decorators", {
            "legacy": true
        }],
        ["@babel/plugin-proposal-class-properties", {
            "loose": true
        }],
        "@babel/plugin-proposal-optional-chaining",
        "@babel/plugin-proposal-nullish-coalescing-operator",
        "react-hot-loader/babel"
    ],

    "overrides": [{
        "test": "./node_modules",
        "sourceType": "unambiguous"
    }]
}

这篇关于由于ES6的扩展语法,Webpack和Babel不会在node_modules内部转换依赖项,该依赖项会破坏IE 11和Edge的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆