前言
关于webpack的一些问题的tips
疑问:在使用webpack打包js库时,webpack的配置和babel的配置冲突时js到底会打包成什么模块?
// webpack的配置,打包目标是umd模块
output: {
path: resolve(__dirname, '../dist'),
filename: '[name].js',
library: 'library',
libraryTarget: 'umd',
}
// babel的配置
[
"@babel/preset-env",
{
modules: 'cjs'
}
]
我经过测试,如果使用webpack打包会无视@babel/preset-env的modules配置。会打包成umd模块
疑问:webpack支持将代码打包成es6的lib吗?
因为之前都是写一些应用程序的代码,没有注意过这些问题。后来谷歌了一下,结果如下👇。
webpack4以及之前都不能将代码打包成es6模块,这是相关的issues。如果想将代码打包成es6模块,可以使用gulp与babel配合。
// 使用gulp和babel打包es6模块的示例
// 直接使用babel将代码编译成es6模块
// gulp配置
const buildEs = () => {
return src(入口地址)
.pipe(babel(babelrc()))
.pipe(dest(输入地址));
};
// babel配置
[
"@babel/preset-env",
{
// 设置为false,将打包成es模块
modules: false
}
],
不过webpack将会在下一个版本实现打包成es6模块的功能, 👇
疑问:webpack通常都会将我们的打包成es5然后配合polyfills使用。但是现在主流浏览器都已经支持es的语法了,我们如何直接使用es的语法?
这是一篇相关的文章:
疑问: 如何使用nomodule以及module优化包的大小
这是一个使用了webpack-module-nomodule-plugin,实现nomodule的例子。
这是一些相关的文章:
使用nomodule和module优化大小,可以在现代浏览器上减小一半的js大小
疑问: @babel/preset-env的useBuiltIns配置项的含义
useBuiltIns的配置分为3个选项false(不使用垫片),entry,usage
entry
设置entry时,需要在代码的入口文件处手动引入"core-js"和"regenerator-runtime/runtime", 根据不同环境(browsers声明的需要兼容的浏览器,如果是只需要支持最新的浏览器将不会进行转换),babel会将core-js转换不同的内容。
// 入口文件
// 输入
import "core-js";
import "regenerator-runtime/runtime"
// 转换后
import "core-js/modules/es.string.pad-start";
import "core-js/modules/es.string.pad-end";
如果我们明确知道,我们需要那些垫片,可以只引入一部分
// 入口文件
import 'core-js/stable/object/assign'
import 'core-js/features/promise';
usage
在每一个文件使用到垫片时,都会自动进行导入垫片的操作
// a文件
var a = new Promise();
// b文件
var b = new Map();
// a文件转换后
import "core-js/modules/es.promise";
var a = new Promise();
// b文件转换后
import "core-js/modules/es.map";
var b = new Map();
疑问: @babel/runtime和babel/plugin-transform-runtime的关系
- @babel/plugin-transform-runtime, 作为开发时的依赖。用来转换代码。
- @babel/runtime,作为生产时的依赖。转换后的代码需要依赖运行时本身所以,所以需要将@babel/runtime作为生产的依赖(需要添加到dependencies)。
还需注意的是transform-runtime的核心版本是可选的,不同的核心转换的API的范围是不同的
- corejs: false,
- corejs: 2, 会对全局Promise变量,或者静态属性Array.from做替换。
- corejs: 3, 除了全局之外,也会对实例属性比如includes做替换。
当我们更改了transform-runtime的corejs的配置,相对应的runtime运行时的版本也需要修改
- corejs: false,对应@babel/runtime
- corejs: 2, 对应@babel/runtime-corejs2
- corejs: 3, 对应@babel/runtime-corejs3
疑问: @babel/preset-env的useBuiltIns: usage和@babel/runtime如何选择?或者说目前那一种才是最佳的实践?
大家可以看下这篇文档, 关键内容如下👇,@babel/runtime无法针对特定的环境,@babel/runtime可能会注入不必要的polyfill内容。
在corejs: 3的设置下,应该是useBuiltIns:usage生成的包是最小的。
Currently, we can't set the target environment as @babel/runtime like we can do for @babel/preset-env. That means that @babel/runtime injects all possible polyfills even when targeting modern engines: it unnecessarily increases the size of the final bundle.
Since core-js-compat contains all the necessary data, in the future, it will be possible to add support for compiling for a target environment to @babel/runtime and to add a useBuiltIns: runtime option to @babel/preset-env.