Webpack и Babel не передают зависимость внутри node_modules, которая нарушает IE 11 и Edge из-за синтаксиса расширения ES6 - PullRequest
0 голосов
/ 25 февраля 2020

У меня есть проект, который использует @mdx-js/runtime, и он полностью разбивается на IE 11 или Edge (Edge 44.18362.449.0):

SCRIPT1028: SCRIPT1028: Expected identifier, string or number

Он фактически ломается из-за синтаксиса распространения здесь:

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

Эта строка кода взята из remark-mdx, которая является зависимостью @mdx-js/runtime, особенно этот файл и строка: https://github.com/mdx-js/mdx/blob/master/packages/remark-mdx/extract-imports-and-exports.js#L66

У меня есть пытался заставить Webpack и Babel преобразовать этот файл, чтобы распространения больше не было:

Список браузеров:

Если я запустил npx browserslist, я вижу IE 11 есть.

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

.babelr c:

Я пытался отключить режим loose и добавить @babel/plugin-transform-spread и @babel/plugin-proposal-object-rest-spread, но не устранил проблему.

  {
    "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:

Здесь я попытался явно включить remark-mdx и @mdx-js/runtime, а также удалить exclude или измените его на /node_modules\/(?!(remark-mdx|@mdx-js\/runtime)\/).*/, но, похоже, ничего не работает:

  {
    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.

1 Ответ

0 голосов
/ 25 февраля 2020

Хорошо, получается, что для обработки файлов внутри node_modules вам нужно использовать babel.config.js вместо .babelrc, как объяснено здесь и здесь :

Какой у вас сценарий использования?

  • Вы используете monorepo?
  • Вы хотите скомпилировать node_modules?

    babel.config.json для вас!

  • У вас есть конфигурация, которая применяется только к одной части вашего проекта?

    .babelrc.json для вас!

Кроме того, если вы используете monorepo, вам нужно установить rootMode: 'upward', чтобы Babel мог найти ваш новый файл конфигурации, как объяснено здесь .

Конфигурация babel-loader Webpack должна выглядеть примерно так:

  {
    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',
      }
    }],
  }

После этого изменения файл обрабатывался, но я получал другую ошибку:

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

В этом случае мне пришлось добавить sourceType: "unambiguous" к babel.config.json, поскольку remark-mdx использовал модули Common JS вместо модулей ES6. Вы можете добавить это в root вашего babel.config.json файла или внутри overrides, чтобы оно предназначалось только для пакетов внутри node_modules.

Подробнее о том, почему это происходит , см. Как использовать опцию babel "useBuiltIns: 'using" в пакете поставщиков? .

Babel's babel.config.json в итоге выглядел так:

{
    "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"
    }]
}
...