Spec-Zone.ru › webpack 5

babel-loader

Предупреждение: babel-loader — это пакет сторонних разработчиков, поддерживаемый участниками сообщества. Возможно, он не имеет той же поддержки, политики безопасности или лицензии, что и webpack, и не поддерживается командой webpack.

Данное руководство предназначено для babel-loader v8/v9 с Babel v7. Если вы используете устаревшую Babel v6, обратитесь к документации ветки 7.x.

Этот пакет позволяет транспилировать JavaScript-файлы с помощью Babel и webpack.

Примечание: Проблемы с результатом следует сообщать в трекере проблем Babel.

Установка

babel-loader Поддерживаемые версии webpack Поддерживаемые версии Babel Поддерживаемые версии Node.js
8.x 4.x или 5.x 7.x >= 8.9
9.x 5.x ^7.12.0 >= 14.15.0
npm install -D babel-loader @babel/core @babel/preset-env webpack

Использование

Документация webpack: Загрузчики

В объекте вашей конфигурации webpack необходимо добавить babel-loader в список модулей, как показано ниже:

module: {
  rules: [
    {
      test: /\.(?:js|mjs|cjs)$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: {
          targets: "defaults",
          presets: [
            ['@babel/preset-env']
          ]
        }
      }
    }
  ]
}

Параметры

См. babel параметры.

Вы можете передать параметры в загрузчик, используя свойство options:

module: {
  rules: [
    {
      test: /\.(?:js|mjs|cjs)$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: {
          targets: "defaults",
          presets: [
            ['@babel/preset-env']
          ],
          plugins: ['@babel/plugin-proposal-decorators', { version: "2023-11" }]
        }
      }
    }
  ]
}

Передаваемые здесь options будут слиты с конфигурационными файлами Babel, например babel.config.js или .babelrc.

Этот загрузчик также поддерживает следующие специфичные для загрузчика параметры:

  • cacheDirectory: Значение по умолчанию false. При установке, указанный каталог будет использоваться для кэширования результатов загрузчика. Будущие сборки webpack будут пытаться читать из кэша, чтобы избежать необходимости выполнения потенциально дорогостоящего процесса перекомпиляции Babel на каждом запуске. Если значение установлено в true в опциях ({cacheDirectory: true}), загрузчик будет использовать каталог кэша по умолчанию в node_modules/.cache/babel-loader или перейдёт к каталогу временных файлов ОС по умолчанию, если папка node_modules не будет найдена в корневых каталогах.

  • cacheIdentifier: Значение по умолчанию — строка, составленная из версии @babel/core и версии babel-loader. Конечный идентификатор кэша будет определяться путём входного файла, слитой конфигурацией Babel через Babel.loadPartialConfigAsync и cacheIdentifier. Слитная конфигурация Babel будет определяться файлами babel.config.js или .babelrc, если они существуют, или значением переменной окружения BABEL_ENV и NODE_ENV. cacheIdentifier может быть установлено в пользовательское значение для принудительного обновления кэша, если идентификатор изменился.

  • cacheCompression: Значение по умолчанию true. При установке каждый результат преобразования Babel будет сжат с помощью Gzip. Если вы хотите отказаться от сжатия кэша, установите его в false — ваш проект может извлечь выгоду от этого, если он транспилирует тысячи файлов.

  • customize: Значение по умолчанию null. Путь к модулю, который экспортирует custom обратный вызов как тот, что вы передадите в .custom(). Поскольку вам уже необходимо создать новый файл для использования этого, рекомендуется вместо этого использовать .custom для создания оболочечного загрузчика. Используйте это только если вы *обязательно* продолжаете использовать babel-loader напрямую, но всё ещё хотите настроить его.

  • metadataSubscribers: Значение по умолчанию []. Принимает массив имён функций контекста. Например, если вы передали ['myMetadataPlugin'], вы бы назначили функцию подписчика context.myMetadataPlugin в рамках хуков плагина webpack, и эта функция будет вызвана с metadata. См. https://github.com/babel/babel-loader/main/test/metadata.test.js для примера.

Устранение неполадок

Включение отладки журналов

Укажите параметр webpack stats.loggingDebug для вывода подробных отладочных журналов.

// webpack.config.js
module.exports = {
  // ...
  stats: {
    loggingDebug: ["babel-loader"]
  }
}

babel-loader работает медленно!

Убедитесь, что вы преобразуете как можно меньше файлов. Так как вы, вероятно, сопоставляете /\.m?js$/, вы можете преобразовывать папку node_modules или другие нежелательные источники.

Чтобы исключить node_modules, см. параметр exclude в конфигурации loaders как описано выше.

Вы также можете ускорить babel-loader в 2 раза, используя параметр cacheDirectory. Это позволит кешировать преобразования в файловой системе.

Некоторые файлы в node_modules не транспилируются для IE 11

Хотя мы обычно рекомендуем не компилировать node_modules, может потребоваться при использовании библиотек, которые не поддерживают IE 11 или другие устаревшие цели.

Для этого вы можете использовать комбинацию test и not, или передать функцию вашему параметру exclude. Вы также можете использовать отрицательный предикат регулярного выражения, как предложено здесь.

{
    test: /\.(?:js|mjs|cjs)$/,
    exclude: {
      and: [/node_modules/], // Exclude libraries in node_modules ...
      not: [
        // Except for a few of them that needs to be transpiled because they use modern syntax
        /unfetch/,
        /d3-array|d3-scale/,
        /@hapi[\\/]joi-date/,
      ]
    },
    use: {
      loader: 'babel-loader',
      options: {
        presets: [
          ['@babel/preset-env', { targets: "ie 11" }]
        ]
      }
    }
  }

Babel вставляет помощники в каждый файл и увеличивает размер моего кода!

Babel использует очень небольшие помощники для общих функций, таких как _extend. По умолчанию это будет добавлено в каждый файл, который его требует.

Вместо этого вы можете потребовать выполнения среды выполнения Babel как отдельного модуля, чтобы избежать дублирования.

Следующая конфигурация отключает автоматическую инъекцию среды выполнения в каждый файл в Babel, требуя @babel/plugin-transform-runtime вместо этого и делая все ссылки на помощники использующими её.

См. документацию для получения дополнительной информации.

ПРИМЕЧАНИЕ: Вам необходимо выполнить npm install -D @babel/plugin-transform-runtime для включения этого в ваш проект и @babel/runtime само по себе как зависимость с npm install @babel/runtime.

rules: [
  // the 'transform-runtime' plugin tells Babel to
  // require the runtime instead of inlining it.
  {
    test: /\.(?:js|mjs|cjs)$/,
    exclude: /node_modules/,
    use: {
      loader: 'babel-loader',
      options: {
        presets: [
          ['@babel/preset-env', { targets: "defaults" }]
        ],
        plugins: ['@babel/plugin-transform-runtime']
      }
    }
  }
]

ПРИМЕЧАНИЕ: transform-runtime и пользовательские полифилы (например, библиотека Promise)

Поскольку @babel/plugin-transform-runtime включает полифил, который включает пользовательский regenerator-runtime и core-js, следующий обычный метод подмены, использующий webpack.ProvidePlugin, не будет работать:

// ...
        new webpack.ProvidePlugin({
            'Promise': 'bluebird'
        }),
// ...

Следующий подход также не сработает:

require('@babel/runtime/core-js/promise').default = require('bluebird');

var promise = new Promise;

что выводит (используя runtime):

'use strict';

var _Promise = require('@babel/runtime/core-js/promise')['default'];

require('@babel/runtime/core-js/promise')['default'] = require('bluebird');

var promise = new _Promise();

Предыдущая библиотека Promise ссылается и используется до её переопределения.

Один из подходов — выполнить «bootstrap» шаг в вашем приложении, который сначала переопределит глобальные переменные по умолчанию перед запуском вашего приложения:

// bootstrap.js

require('@babel/runtime/core-js/promise').default = require('bluebird');

// ...

require('./app');

API Node.js для babel перенесён в babel-core.

Если вы получаете это сообщение, значит, у вас установлен npm пакет babel и вы используете короткое обозначение загрузчика в конфигурации webpack (которое больше не является допустимым начиная с webpack 2.x):

  {
    test: /\.(?:js|mjs|cjs)$/,
    loader: 'babel',
  }

webpack затем пытается загрузить пакет babel вместо babel-loader.

Для решения этой проблемы вам следует удалить npm пакет babel, так как он устарел в Babel v6. (Вместо этого установите @babel/cli или @babel/core. ) В случае, если одна из ваших зависимостей устанавливает babel, и вы не можете удалить её самостоятельно, используйте полное имя загрузчика в конфигурации webpack:

  {
    test: /\.(?:js|mjs|cjs)$/,
    loader: 'babel-loader',
  }

Исключение библиотек, которые не должны транспилироваться

core-js и webpack/buildin приведут к ошибкам, если их транспилирует Babel.

Вам необходимо исключить их из babel-loader.

{
  "loader": "babel-loader",
  "options": {
    "exclude": [
      // \\ for Windows, / for macOS and Linux
      /node_modules[\\/]core-js/,
      /node_modules[\\/]webpack[\\/]buildin/,
    ],
    "presets": [
      "@babel/preset-env"
    ]
  }
}

Функция верхнего уровня (IIFE) всё ещё является стрелочной (в Webpack 5)

Эта функция вставляется самим Webpack *после* выполнения babel-loader. По умолчанию Webpack предполагает, что ваша целевая среда поддерживает некоторые функции ES2015, но вы можете переопределить это поведение, используя параметр output.environment webpack (документация).

Чтобы избежать функции верхнего уровня в виде стрелочной функции, вы можете использовать output.environment.arrowFunction:

// webpack.config.js
module.exports = {
  // ...
  output: {
    // ...
    environment: {
      // ...
      arrowFunction: false, // <-- this line does the trick
    },
  },
};

Настройка конфигурации в зависимости от целевой среды webpack

Webpack поддерживает объединение нескольких целей. В случаях, когда вам могут потребоваться разные конфигурации Babel для каждой цели (например, web и node), этот загрузчик предоставляет свойство target через API вызывающей программы Babel .

Например, чтобы изменить целевые среды, передаваемые в @babel/preset-env в зависимости от целевой среды webpack:

// babel.config.js

module.exports = api => {
  return {
    presets: [
      [
        "@babel/preset-env",
        {
          useBuiltIns: "entry",
          // caller.target will be the same as the target option from webpack
          targets: api.caller(caller => caller && caller.target === "node")
            ? { node: "current" }
            : { chrome: "58", ie: "11" }
        }
      ]
    ]
  }
}

Настраиваемый загрузчик

babel-loader предоставляет утилиту построения загрузчика, которая позволяет пользователям добавлять пользовательскую обработку конфигурации Babel для каждого файла, который он обрабатывает.

.custom принимает обратный вызов, который будет вызываться с экземпляром загрузчика babel, чтобы инструменты могли гарантировать, что они используют ровно тот же экземпляр @babel/core , что и сам загрузчик.

В случаях, когда вы хотите настроить его без фактического наличия файла, для вызова .custom, вы также можете передать параметр customize со строкой, указывающей на файл, который экспортирует вашу функцию обратного вызова custom.

Пример

// Export from "./my-custom-loader.js" or whatever you want.
module.exports = require("babel-loader").custom(babel => {
  // Extract the custom options in the custom plugin
  function myPlugin(api, { opt1, opt2 }) {
    return {
      visitor: {},
    };
  }

  return {
    // Passed the loader options.
    customOptions({ opt1, opt2, ...loader }) {
      return {
        // Pull out any custom options that the loader might have.
        custom: { opt1, opt2 },

        // Pass the options back with the two custom options removed.
        loader,
      };
    },

    // Passed Babel's 'PartialConfig' object.
    config(cfg, { customOptions }) {
      if (cfg.hasFilesystemConfig()) {
        // Use the normal config
        return cfg.options;
      }

      return {
        ...cfg.options,
        plugins: [
          ...(cfg.options.plugins || []),

          // Include a custom plugin in the options and passing it the customOptions object.
          [myPlugin, customOptions],
        ],
      };
    },

    result(result) {
      return {
        ...result,
        code: result.code + "\n// Generated by some custom loader",
      };
    },
  };
});
// And in your Webpack config
module.exports = {
  // ..
  module: {
    rules: [{
      // ...
      loader: path.join(__dirname, 'my-custom-loader.js'),
      // ...
    }]
  }
};

customOptions(options: Object): { custom: Object, loader: Object }

Исходя из параметров загрузчика, выделите пользовательские параметры из опций babel-loader.

config(cfg: PartialConfig, options: { source, customOptions }): Object

Исходя из объекта конфигурации Babel, верните объект options, который должен быть передан babel.transform.

result(result: Result): Result

Исходя из объекта результата Babel, разрешите загрузчикам вносить дополнительные корректировки в него.

Лицензия

MIT

© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://webpack.js.org/loaders/babel-loader

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API