Print

发布、传输和安装现代 JavaScript 以实现更快的应用程序


作者: 文章来源:

本文原地址:https://www.mimiwuqi.com/webqianduan/195899.html

目录文章目录
  1. 现代 JavaScript
  2. 传统 JavaScript
  3. npm 上的现代 JavaScript
  4. 仅现代
  5. 具有传统回退的现代代码
  6. 具有传统回退的现代代码和 ESM 捆绑程序优化
  7. 应用程序中的现代 JavaScript
  8. webpack
  9. Optimize Plugin
  10. BabelEsmPlugin
  11. 将 babel-loader 配置为转换 node_modules
  12. Rollup
  13. 其他构建工具

发布、传输和安装现代 JavaScript 以实现更快的应用程序 1

BabelEsmPlugin

BabelEsmPlugin 是一个 webpack 插件,它与 @babel/preset-env 一起工作来生成现有捆绑包的现代版本,以将更少的转换代码传输到现代浏览器。它是 Next.js 和 Preact CLI 使用最多的模块/无模块现成解决方案。

// webpack.config.js
const BabelEsmPlugin = require('babel-esm-plugin');

module.exports = {
  //...
  module: {
    rules: [
      // your existing babel-loader configuration:
      {
        test: /.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
          },
        },
      },
    ],
  },
  plugins: [new BabelEsmPlugin()],
};

BabelEsmPlugin 支持多种 webpack 配置,因为它运行应用程序的两个基本独立的版本。对于大型应用程序,编译两次可能需要一点额外的时间,但是这种技术允许 BabelEsmPlugin 无缝集成到现有 webpack 配置中,使其成为最方便的选择之一。

将 babel-loader 配置为转换 node_modules

如果使用 babel-loader 而没有使用前两个插件之一,则需要执行一个重要的步骤才能使用现代 JavaScript npm 模块。定义两个单独的 babel-loader 配置可以将 node_modules 中的现代语言特性自动编译为 ES2017,同时仍然使用 Babel 插件和项目配置中定义的预设来转换您自己的第一方代码。这不会为模块/无模块设置生成现代和传统捆绑包,但可以安装和使用包含现代 JavaScript 的 npm 软件包,而不会破坏旧版浏览器体验。

webpack-plugin-modern-npm 使用这种技术来编译在 package.json 中具有 "exports" 字段的 npm 依赖项,因为它们可能包含现代语法:

// webpack.config.js
const ModernNpmPlugin = require('webpack-plugin-modern-npm');

module.exports = {
  plugins: [
    // auto-transpile modern stuff found in node_modules
    new ModernNpmPlugin(),
  ],
};

或者,可以通过在解析模块时检查 package.json 中是否存在 "exports" 字段,在 webpack 配置中手动实现该技术。为简洁起见而省略缓存,自定义实现可能如下所示:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      // Transpile for your own first-party code:
      {
        test: /.js$/i,
        loader: 'babel-loader',
        exclude: /node_modules/,
      },
      // Transpile modern dependencies:
      {
        test: /.js$/i,
        include(file) {
          let dir = file.match(/^.*[/\]node_modules[/\](@.*?[/\])?.*?[/\]/);
          try {
            return dir && !!require(dir[0] + 'package.json').exports;
          } catch (e) {}
        },
        use: {
          loader: 'babel-loader',
          options: {
            babelrc: false,
            configFile: false,
            presets: ['@babel/preset-env'],
          },
        },
      },
    ],
  },
};

使用此方法时,您需要确保缩小器支持现代语法。Terser 和 uglify-es 都有指定 {ecma: 2017} 的选项,以便在压缩和格式化期间保留 ES2017 语法并在某些情况下生成该语法。

Rollup

Rollup 内部支持生成多组捆绑包作为单个版本的一部分,并默认生成现代代码。因此,可以将 Rollup 配置为通过您可能已经在使用的官方插件生成现代和传统捆绑包。

@rollup/plugin-babel

如果使用 Rollup,getBabelOutputPlugin() 方法(由 Rollup 的官方 Babel 插件提供)会转换生成的捆绑包中的代码,而不是单个源模块。Rollup 内部支持生成多组捆绑包作为单个版本的一部分,每个捆绑包都有自己的插件。您可以通过不同的 Babel 输出插件配置来传递各个捆绑包,从而生成不同的现代和传统捆绑包:

// rollup.config.js
import {getBabelOutputPlugin} from '@rollup/plugin-babel';

export default {
  input: 'src/index.js',
  output: [
    // modern bundles:
    {
      format: 'es',
      plugins: [
        getBabelOutputPlugin({
          presets: [
            [
              '@babel/preset-env',
              {
                targets: {esmodules: true},
                bugfixes: true,
                loose: true,
              },
            ],
          ],
        }),
      ],
    },
    // legacy (ES5) bundles:
    {
      format: 'amd',
      entryFileNames: '[name].legacy.js',
      chunkFileNames: '[name]-[hash].legacy.js',
      plugins: [
        getBabelOutputPlugin({
          presets: ['@babel/preset-env'],
        }),
      ],
    },
  ],
};

其他构建工具

Rollup 和 webpack 是高度可配置的,这通常意味着每个项目都必须更新其配置以在依赖项中启用现代 JavaScript 语法。还有更高级的构建工具更倾向于惯例和默认值,而不是配置,例如 Parcel、Snowpack、Vite 和 WMR。这些工具中的大多数假定 npm 依赖项可能包含现代语法,并在生产编译时将它们转换为适当的语法级别。

除了 webpack 和 Rollup 的专用插件,还可以使用 devolution 将具有传统回退的现代 JavaScript 捆绑包添加到任何项目中。Devolution 是一个独立的工具,可转换编译系统的输出以生成传统 JavaScript 变体,从而允许捆绑和转换采用现代输出目标。

原文链接:点击这里

更多 建站教程 请访问 https://www.mimiwuqi.com/webqianduan/