本系列文章是我在學習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處理一次