1.干什么?
browserslit 用特定的语句来查询浏览器列表,如 last 2 Chrome versions。
2.有什么用
不同的前端工具之间共用目标浏览器和 node 版本的配置工具
- Autoprefixer
- Babel
- post-preset-env
- eslint-plugin-compat
- stylelint-unsupported-browser-features
- postcss-normalize
一般项目中进行使用主要是为了在 post-css 的autoprefixer 中增加浏览器前缀,在babel 的post-preset-env中增加语法的编译或者是配合core-js增加低版本浏览器的垫片
eslint-plugin-compat可以根绝browserslist的配置项,自动校验当前写的语法是否是我们目标浏览器所支持的,但是如果这样需要书写很多polyfill的支持,目前eslint暂时不增加该配置项
3.怎么使用
常规写法
- Last n version 所有浏览器的最后几个版本
- Browser > = ,<= 表示标志该类型浏览器的版本范围
-
number% 表示在全球的浏览器统计的份额中占有的比例
- not 表示非语法,如果要排除某些浏览器版本 要放到最后
- And 表示取交集
在package.json中书写
{
“browserslist”: [
“last 1 version”,
“> 1%”,
“maintained node versions”,
“not dead”
]
}
直接在.browserslistrc 或者browserslist文件中书写
browsers that we support
[production]
chrome >= 39
last 2 version
not ie <= 10
[development]
last 3 version
0.2%
not dead
[ssr]
node > 14
browserslist会读取NODE_ENV或者BROWSERSLIST的当前环境变量,决定使用哪个规则
4.优先级
工具的options>BROWSERSLIST >browserslist>.browserslistrc>package.json
4.我们的配置
目前是直接放在.browserslistrc文件中,主要是下面用到的@bable/preset-env和autoprefixer推荐这种方式
browsers that we support
chrome >= 39
last 2 version
1%
not ie 10
not ie_mob 10
目的主要是兼容chrome浏览器在 >=39版本以上,兼容ie11浏览器,其他的浏览器只兼容最后两个大版本,浏览器的覆盖91.3%
5.命令行使用
5.1查看支持的浏览器版本列表
可以直接时使用npx browserslist 直接会读取当前的配置文件,抛出浏览器的支持列表,也可后面增加自己的测试的语法 比如 browserslist ‘last 2 version’(需要全局安装browserlist包)
5.2查看覆盖率率
browserslist --coverage
$ browserslist --coverage ‘last 2 version’
These browsers account for 75.98% of all users globally
6.原理
browserslist会读取本地的caniuse-lite目录中的文件不同浏览器的支持等所以有时候browserslist会让你更新本地的caniuse-lite,当然我们也可以自己定制每个浏览器在我们的用户中的使用率,暂时不讨论此方法
.Babelrc 配置相关
babel的作用,在我们写代码的时候如果使用了最新的特性,比如 let const class等语法,这些语法无法在低版本的浏览器中进行支持,所以需要一个转换工具,讲这些代码转换成低版本浏览器也能识别的代码, 可以理解babel是JavaScript的语法转换器
babelrc的作用
babel支持两种类型的文件格式 babel.config.(json|js|) .babelrc.* ,package.json中 的babel key
注意在不同的版本中支持的文件不一样
version
changes
v7.8.0
.babelrc.mjs .babel.config.mjs
v7.7.0
.babelrc.json .babelrc.cjs babel.config.json babel.config.cjs
这里只做字段的解释,具体的文件类型大家根据项目中使用的babel的版本进行配置
在bable执行编译的过程中,会从根目录中读取.babelrc的配置,在.baberc文件中主要是对预设(presets) 和 插件(plugins) 进行配置
文件类型的区别
babel.config 文件定义为prohect-widt configuration 而babelrc为 file-relative configuration ,在babel7.X的版本中增加了 root的概念,
可以理解为 babel.config为项目的配置(主要是针对与部分项目为monorepo的形式),而 babelrc为相对root次一级的目录,但是优先级的话是 babelrc > babel.config,进行配置的合并
主要配置项
相关文档的解析主要参考这篇文章
https://blog.csdn.net/qq_37299525/article/details/125272621
Plugins
告诉babel使用哪些插件,这些插件用来控制如何转换代码
Presets
预设,告诉babel转换远吗使用了哪些新的语法特性, 是plugins的集合
配置
使用core-js的原因参考
Promise垫片的调研
主要是为了兼容低版本浏览器不存在的api
针对于此配置所以我们目前使用
需要安装 @babel/preset-env
{
“presets”: {
[
“@babel/preset-env”: {
“useBuiltIns”: “usage”,
“corejs”:“3”,
// 支持提案中的特性
“proposals”: true
}
]
}
}
- useBuiltIns: false: 不对API进行处理
- useBuiltIns:usage babel会根据代码使用(及browserslist的设置)自动引入所需的垫片
- useBuiltIns:entry 全量引入(引入的垫片数量只跟brwoserslist中的设置有关) 需要在主文件中添加
import ‘core-js’
@babel/plugin-transform-runtime
在@babel/preset-env中使用的usebuiltIns 的垫片会导致污染全局变量,在开发第三方库的时候不建议这么使用
使用此plugin会根据api进行转换,不污染全局变量,需要安装 @babel/plugin-transform-runtime包
{
“plugins”:[
[“@babel/plugin-transform-runtime”, {}
“core-js”: 3
}]
]
}
注意这种方法需要引入@babel/runtime-corejs3 包
其他说明
- @babel/polyfill 在babel7.4.0中已经启用
- @babel/preset-flow 用于flow
- @babel/preset-react 用于react
- @babel/preset-typescript 用于ts
- @babel/runtime 配合@babel/plugin-transform-runtime,但是不能处理api,所以还是使用@babel/runtime-corejs3 合适
顺序
- plugin优先于preset
- plugin从前到后
- preset从后到前
postcss.config.js
postcss主要是为了我们css代码能够在较低版本的浏览器中也能正常使用或者识别,支持多种plugin进行css文件的处理
Autoprefixer
此postcss插件会读取browserslist的配置,添加浏览器的前缀比如(-webkit-,-moz-等),注意:autoprefixer只会增加前缀,并不会增加polyfill
Postcss-preset-env
此插件主要是为了能够使用更新的css特性,可以类比为babel的 @babel/preset-env,提供css的语法polyfill,也会读取browserslist的配置,post-preset-env内置autoprefixer,只需要开启即可
官方的示例如下:
@custom-media --viewport-medium (width <= 50rem);
@custom-selector :–heading h1, h2, h3, h4, h5, h6;
:root {
–mainColor: #12345678;
}
body {
color: var(–mainColor);
font-family: system-ui;
overflow-wrap: break-word;
}
:–heading {
background-image: image-set(url(img/heading.png) 1x, url(img/heading@2x.png) 2x);
@media (–viewport-medium) {
margin-block: 0;
}
}
a {
color: rgb(0 0 100% / 90%);
&:hover {
color: rebeccapurple;
}
}
/* becomes */
:root {
–mainColor: rgba(18, 52, 86, 0.47059);
}
body {
color: rgba(18, 52, 86, 0.47059);
color: var(–mainColor);
font-family: system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Droid Sans, Helvetica Neue;
word-wrap: break-word;
}
h1, h2, h3, h4, h5, h6 {
background-image: url(img/heading.png);
}
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
h1, h2, h3, h4, h5, h6 {
background-image: url(img/heading@2x.png)
}
}
@media (max-width: 50rem) {
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0;
}
}
a {
color: rgba(0, 0, 255, 0.9)
}
a:hover {
color: #639;
}
配置
可以使用postcss.config.js 或者在postcss-loader的options中进行配置,如果使用postcss.config.js,则在webpack的postcss-loader会自动读取相应的配置
建议使用第一种方式,这样在处理less,sass等文件的时候不用在copy更多代码
// postcss.config.js
const postCssPresetEnv = require(‘postcss-preset-env’)
module.exports = {
plugins: [
postCssPresetEnv({
autoprefixer: {
grid: true,
},
}),
],
}
// webpack.config.js
{
test: /.css$/i,
loader: ‘postcss-loader’,
options: {
postcssOptions: {
plugins:[
‘postcss-flexbugs-fixes’,
[
‘postcss-preset-env’,
{
autoprefixer: {
grid: true
}
}
]
]
}
}
}