- 现代 JavaScript
- 传统 JavaScript
- npm 上的现代 JavaScript
- 仅现代
- 具有传统回退的现代代码
- 具有传统回退的现代代码和 ESM 捆绑程序优化
- 应用程序中的现代 JavaScript
- webpack
- Optimize Plugin
- BabelEsmPlugin
- 将 babel-loader 配置为转换 node_modules
- Rollup
- 其他构建工具
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 变体,从而允许捆绑和转换采用现代输出目标。
原文链接:点击这里