本系列文章是我在学习webpack时的总结与收获。本片文章为系列文章的第三篇,包含对于很对新的前端开发者常常忽略的浏览器兼容性问题以及postcss使用
浏览器兼容性
当前市场上有很多浏览器,对不同浏览器的适配,我们应该如何解决呢?
首先需要注意的是,这里的浏览器适配指的是针对不同浏览器特性的支持:比如,CSS 特性、JavaScript 语法特性等
那么,这里就有一个问题,如何确定支持哪些版本的浏览器呢?
在项目开发中,我们经常在 .broswerslistrc 或 package.json 中看到如下配置:
> 1%
last 4 version
not dead
通过这些配置在 "Can I use" usage table 中查询符合条件的浏览器,再去针对这些浏览器去作特性的兼容。
为了能够在多个前端工具中共享这些配置,需要使用一个叫做 browserlist 的工具
Browserslist
在不同前端工具之间共享目标浏览器和 Node.js 版本的配置。 它用于:
- Autoprefixer
- Babel
- postcss-preset-env
- eslint-plugin-compat
- stylelint-no-unsupported-browser-features
- postcss-normalize
- obsolete-webpack-plugin
browserslist 编写规则
- defaults: Browserslist 的默认浏览器(>0.5%, last 2 versions, FIrefox ESR, not dead)
- 5%:通过全球使用情况统计信息选择的浏览器版本
- dead:24个月内没有官方支持或更新的浏览器。目前是IE 10,IE_Mob 11
- last 2 versions:每个浏览器的最新2个版本
- 还有一些不太常用的配置可以查看官网
多个条件之间的关系如下图所示:
使用方法
- 在package.josn中添加 browserslist 字段
- 在根目录下添加 .browserslistrc 文件,在该文件中写入配置
命令行使用
npx browserslist ">1%, last 2 versions, not dead"
npx browserslist
,后面不加参数,也可以使用,不加参数时,就会去当前目录查找.browserslistrc
文件中的条件
上述三种使用方法,前两种是我们在平时开发中经常使用的方法。例如,autoprefixer、babel 会自动寻找 package.json 中的 browserslist 字段或 .browserslistrc 文件,然后自动使用 caniuse-lite 工具查询符合条件的浏览器,进而对目标浏览器作特性兼容等处理。
caniuse-lite
该工具并不是发送请求到 Can I use... Support tables for HTML5, CSS3, etc ,然后获得符合条件的浏览器数据。caniuse-lite 本身就是一个小型的数据集,以紧凑的格式保存数据的重要部分。
因此,无论是autoprefixer还是babel只需要根据 .browserslistrc 文件筛选出对应的浏览器即可
PostCSS
PostCSS 是一个通过 JavaScript 转换样式的工具,可以帮助我们进行 CSS 转换和适配,比如自动添加浏览器前缀、CSS 样式重置。但是要想实现上述功能,必须借助于对应的插件
在 webpack 中使用 Postcss,需要先安装 postcss-loader 和 postcss。通过 postcss-loader 使用 postcss,对于特定功能,需要安装特定的插件
使用方法
直接在module中编写配置
module.exports = { module: { rules: [ { test: /\.css$/, exclude: /node_modules/, use: [ { loader: 'style-loader', }, { loader: 'css-loader', options: { importLoaders: 1, } }, { loader: 'postcss-loader', options: { postcssOptions: { plugins: [ require('autoprefixer'), // 添加浏览器前缀 require('postcss-preset-env') // 该插件可以使用一些未来的CSS特性 ] } } } ] } ] } }
创建 postcss.config.js 文件,在给该文件中添加使用的loader。这种方式更加简洁相较于第一种
module.exports = { plugins: [ require('autoprefixer'), require('postcss-preset-env') ] }
importLoaders
该选项用于处理一个 CSS 文件,通过 @import 的方式引入另一个CSS 文件的情况
/* index.css */
@import "./test.css/"
/* test.css */
:fullscreen {
}
.content {
user-select: none;
}
在这种情况下,如果不添加 importLoaders 选项,那么 test.css 中的样式是不会被处理的。
原因在于,当匹配到 css 文件时,首先使用 postcss-loader 处理 index.css 文件,它并不会根据@import 语法去处理引入的 test.css 文件。然后使用 css-loader进行处理,css-loader 可以根据@import 处理引入的 test.css 文件,这就导致 test.css 中的文件其实并没有被 postcss 处理
为了解决这种问题,可以在css-loader的options中添加一个 importLoaders 选项
{
loader: 'css-loader',
options: {
importLoaders: 1 // 该数字代表需要前面几个loader再次处理
}
}
其意思是,当使用 css-loader时,再使用css-loader之前的若干个loader处理一次