瀏覽器相容以及PostCSS詳解

Lyx發表於2022-06-30
本系列文章是我在學習webpack時的總結與收穫。本片文章為系列文章的第三篇,包含對於很對新的前端開發者常常忽略的瀏覽器相容性問題以及postcss使用

瀏覽器相容性

當前市場上有很多瀏覽器,對不同瀏覽器的適配,我們應該如何解決呢?

首先需要注意的是,這裡的瀏覽器適配指的是針對不同瀏覽器特性的支援:比如,CSS 特性、JavaScript 語法特性等

那麼,這裡就有一個問題,如何確定支援哪些版本的瀏覽器呢?

在專案開發中,我們經常在 .broswerslistrc 或 package.json 中看到如下配置:

> 1%
last 4 version
not dead

通過這些配置在 "Can I use" usage table 中查詢符合條件的瀏覽器,再去針對這些瀏覽器去作特性的相容。

Untitled.png

為了能夠在多個前端工具中共享這些配置,需要使用一個叫做 browserlist 的工具

Browserslist

在不同前端工具之間共享目標瀏覽器和 Node.js 版本的配置。 它用於:

browserslist 編寫規則

  • defaults: Browserslist 的預設瀏覽器(>0.5%, last 2 versions, FIrefox ESR, not dead)
  • 5%:通過全球使用情況統計資訊選擇的瀏覽器版本
  • dead:24個月內沒有官方支援或更新的瀏覽器。目前是IE 10,IE_Mob 11
  • last 2 versions:每個瀏覽器的最新2個版本
  • 還有一些不太常用的配置可以檢視官網

多個條件之間的關係如下圖所示:

Untitled (1).png

使用方法

  1. 在package.josn中新增 browserslist 欄位

Untitled (2).png

  1. 在根目錄下新增 .browserslistrc 檔案,在該檔案中寫入配置

Untitled (3).png

  1. 命令列使用

    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 樣式重置。但是要想實現上述功能,必須藉助於對應的外掛

未命名繪圖.png

在 webpack 中使用 Postcss,需要先安裝 postcss-loader 和 postcss。通過 postcss-loader 使用 postcss,對於特定功能,需要安裝特定的外掛

使用方法

  1. 直接在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特性
                        ]
                    }
                }
              }
            ]
          }
        ]
      }
    }
  2. 建立 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處理一次

reference

  1. browserslist/browserslist: ? Share target browsers between different front-end tools, like Autoprefixer, Stylelint and babel-preset-env (github.com)
  2. "Can I use" usage table

相關文章