[Webpack]No.6 讓 SCSS 也加入打包的行列

前言

接著我們要讓 Webpack 也支援 SCSS ,輸入指令後轉成 CSS 並且優化之後打包輸出,同樣地延續上一篇的專案資料夾。

建立 & 調整部份檔案

  • 於 src 資料夾內建立 scss 的資料夾,並且在裡面建立一些 .scss 的檔案

  • 並且個別再 _a.scss 、 _b.scss 內寫了一些 CSS 語法,觀察變化。
  • index.html 也做一些微調,我希望使用 dev 指令時會輸出再 src 內,並且以 all.min.css 的檔名出現。

安裝對應的 loader 與 plugins

最基本的 Webpack 功能其實只有 Javascript 部份,因此若是希望 Webpack 也能幫我們做更多事情的話,就必須要仰賴相對應的 loader 與 plugins 。

因此規畫之後我們需要以下的東西:

  • css-loader : 載入 .css 的檔案
  • mini-css-extract-plugin : 將 CSS 輸出成檔案
  • sass-loader : 載入 .scss 的檔案
  • node-sass : Sass 的編譯器

順序大致上是這樣的

sass-loader 載入 .scss 檔 > 編譯成 css 檔 > css-loader 載入 .css 檔 > 最後則是給 mini-css-extract-plugin 打包成檔案。

全部串在一起下載回來吧!


webpack.config 添加對應的設定

由於上一篇提到的問題,所以我們將設定拆成了開發用以及部屬用的兩隻設定檔。

前情提要一下

接下來我們要在開發用設定檔裡面增加 loader 設定,在物件 module 底下會有一個 rules 的陣列,在這個陣列裡面放置的每一個物件,是當 Webpack 無法辨識目前要載入的資源檔時,會到這邊去查找看看有沒有相對應的載入方式,在這個物件裡面會有兩個屬性:

  • test : 是一個正規表示式,主要是去查找目前要載入的檔案,有沒有跟這個正規表示式符合
  • use : 表示我們載入檔案要使用的 loader

值得注意的是, Webpack 調用 loader 的順序是從後面到前面

動手設定如下

  • mini-css-extract-pluginrequire 進來

    1
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
  • use 陣列內依序填入 MiniCssExtractPlugin.loadercss-loadersass-loader

  • test 正則表達式的部份也要修改成 test: /\.(scss|sass)$/,
  • module 區塊下方補上 plugins 區塊
    1
    2
    3
    4
    5
    plugins: [  
    new MiniCssExtractPlugin({
    filename: './src/all.min.css',
    })
    ]

這一段主要是使用 MiniCssExtractPlugin 指定 .css 檔案該輸出到哪裡。

做完這些調整後,會長的像這樣:

別忘了我們的進入點是 all.js ,需要把 .scss 檔案給載入才會一起打包哦。

做到這邊先測試看看吧~ npm run dev

網頁的部份也沒有問題哩!

而且因為使用了 --watch ,每當檔案有異動、按下存檔時都會再度編譯,是不是跟 VS CODE 的插件 Live Sass Compiler 用起來體感相似呢?

部屬時的 config 檔 也需要補上設定

所以我們將剛才設定的內容都複製一份到這裡,我們會覺得有很多重複的東西感覺很不智慧,事實上這可以利用 Webpack-merge 來處理重複的部份,但這不在這次的討論範圍內,為了控制篇幅,就不提了。

這邊附上相關的介紹

調整後檔案設定如下

別忘了輸出路徑也要調整一下,才會輸出到正確的地方唷。

確認一下輸出結果:

雖然結果是正確的,但不夠理想。

畢竟這是正式部屬的設定檔,我們需要針對 .css 做壓縮才行。

使用 optimize-css-assets-webpack-plugin

這個套件將幫助我們把 CSS 優化,馬上輸入指令下載回來

1
npm install optimize-css-assets-webpack-plugin --save-dev

  • optimize-css-assets-webpack-plugin 載入
  • 接著再 module 下方額外加入 optimization 物件,如:
1
2
3
4
5
optimization: {  
minimizer: [
new OptimizeCssAssetsWebpackPlugin()
]
},

調整完之後,整體配置如:

看起來完成了,測試看看吧!

成功的壓縮了,但…事情沒這麼簡單,我們的原先由 Webpack 自動幫我們壓縮好的 all.min.js 失去壓縮了。

為什麼 JavaScript 失去壓縮了

因為 Webpack 預設是當我們使用部屬模式時,會自動的幫我們壓縮 .js 檔案,但是當我們自行加入 optimization 區塊時,它就會認為我們要自己管理,也就是說我們現在必須額外加入壓縮 JavaScript 的套件。

  • 加入 terser-webpack-plugin
    1
    npm install terser-webpack-plugin --save-dev

如同加入 CSS 壓縮功能的步驟:

  • terser-webpack-plugin require 進檔案
  • optimization 物件加入以下
    1
    2
    3
    4
    5
    6
    optimization: {  
    minimizer: [
    new TerserWebpackPlugin(),
    new OptimizeCssAssetsWebpackPlugin()
    ]
    },

調整完之後,整體配置如:

再次測試看看吧!


至此,設定全部都完成了呢!

替 CSS 加上前綴詞,讓開發更便利

現在瀏覽器這麼多種,為了相容各式各樣的瀏覽器,有些時候我們得在 CSS 語法前手動補上一些前綴詞,才能在相應的瀏覽器內生效,但是這樣子不夠智慧。

聰明的工程師想出了一套解決辦法:

透過這兩個工具,自動的為我們補上前綴詞

事不宜遲,馬上下載安裝

1
npm install postcss-loader autoprefixer --save-dev

順序

我們知道在 Webpack 內 loader 載入的順序是有差別的,因此在加入這些套件後,順序應該調整為:

  • sass-loader 編譯
  • 交由 postcss-loader 加上前綴詞
  • 在給 css-loader 處理
  • 最後由 MiniCssExtractPlugin.loader 打包輸出

調整設定

得知順序後,開始著手調整設定吧。

調整後的設定檔如下:

測試看看是否成功加上前綴

_a.scss
all.min.css

成功了!可喜可賀!別忘了把部屬用的設定檔也補上哦。

心得

透過這樣一連串的設定,對於如何替 Webpack 加裝一些套件有更深刻的體驗,幸好這樣的設定只要做一次,後續就可以直接沿用,否則每次要做這麼多的設定也是很麻煩的。

0%