webpack v3 學習筆記(三) 打包css程式碼 和 Tree Shaking

WanFengZ發表於2019-12-25

打包 css

打包 css 主要用到的 loader 是 style-loader 和 css-loader。css-loader 的作用是處理在 js 中引入的css。另外如果我們用到了 css 預編譯,如 sass,則我們還需要 sass-loader 和 node-sass(node環境下執行的sass)。同時我們還可以在 loader 的過程中藉助 postcss-loader 使用很多有用的 css 外掛,如 autoprefixer,pxtorem。

在打包的結果中其實是沒有 css 檔案的,如打包出的 app.bundle.js,打包進去的 css 程式碼都是在瀏覽器中執行 js 後新增的,如果要把 css 單獨打包成檔案,還需要 webpack 的外掛 extract-text-webpack-plugin(v3,已被廢棄),v4 中使用 mini-css-extract-plugin

npm install webpack@^3.0.0 style-loader css-loader sass-loader@^7.0.0 node-sass // sass-loader v8 在 v3 中報錯
npm install postcss postcss-loader autoprefixer cssnano
npm install extract-text-webpack-plugin
touch webpack.config.js
mkdir src
mkdir src/css
touch src/app.js
touch src/css/base.scss
touch src/css/common.scss
複製程式碼

base.scss

$color: red;
html {
  background-color: $color;
}

ul {
  li {
    list-style: none;
  }
}
複製程式碼

common.scss

body {
  div {
    width: 100px;
    height: 100px;
    background-color: blue;
    display: flex;
  }
}

.big {
  width: 200px;
  height: 200px;
}
複製程式碼

app.js

import './css/base.scss'
import common from './css/common.scss'

const div = document.createElement('div')
// 使用css-module
div.className = common.big
document.body.append(div)
複製程式碼

webpack.config.js

var path = require('path')
var ExtractTextWebpackPlugin = require('extract-text-webpack-plugin')

module.exports = {
  entry: {
    app: './src/app'
  },
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, './dist'),
    publicPath: './dist/',
    chunkFilename: '[name].chunk.js'
  },
  module: {
    rules: [
      {
        test: /\.scss$/,
        // 使用外掛,將 css 提取成單獨的檔案
        use: ExtractTextWebpackPlugin.extract({
          fallback: {
            loader: 'style-loader',
            // 提取 css 成單獨檔案時下面的設定其實是沒有效果的
            options: {
              /*
              * styleTag: style 標籤插入
              * linkTag:link 標籤插入
              * singletonStyleTag:單 style 標籤插入
              * lazyStyleTag:附加原來的 usable 的功能,可以使用 use() 和 unuse()
              * lazySingletonStyleTag: 同上,單 style 標籤
              * */
              injectType: 'singletonStyleTag',
              // 插入的位置
              insert: 'head'
            }
          },
          use: [
            {
              loader: 'css-loader',
              options: {
                // 啟用css-module
                modules: true
                // 壓縮程式碼的選項被移除,可以轉而使用 postcss 或者 UglifyjsWebpackPlugin
              }
            },
            {
              loader: 'postcss-loader',
              options: {
                ident: 'postcss',
                plugins: [
                  // css 瀏覽器字首外掛
                  require('autoprefixer')(),
                  // 壓縮 css 外掛
                  require('cssnano')()
                ]
              }
            },
            {
              loader: 'sass-loader'
            }
          ]
        })
      }
    ]
  },
  plugins: [
    // 配置提取 css 的外掛,v4 中使用 mini-css-extract-plugin
    new ExtractTextWebpackPlugin({
      filename: '[name].min.css',
      allChunks: true
    })
  ]
}
複製程式碼

打包效果如下:

webpack v3 學習筆記(三) 打包css程式碼 和 Tree Shaking

webpack v3 學習筆記(三) 打包css程式碼 和 Tree Shaking

Tree Shaking

tree shaking 可以幫助我們去除專案中沒有用到的程式碼,雖然在 v3 版本中有缺陷沒什麼用處,但是在 v4 中修復了缺陷,下面的是 v3 的 Tree Shaking:

在上面打包 css 的目錄檔案的基礎上:

mkdir src/utils
touch src/utils/util.js
複製程式碼

util.js

export function a () {
  return 'this is a'
}

export function b () {
  return 'this is b'
}

export function c () {
  return 'this is c'
}
複製程式碼

在 app.js 下面新加:

import { a } from './utils/util'

console.log(a())
複製程式碼

原來設定下的打包結果下,util 下的三個函式都會打包進去:

webpack v3 學習筆記(三) 打包css程式碼 和 Tree Shaking

然後我們使用外掛,在設定中require webpack並在 plugins 下新加外掛:

var webpack  = require('webpack')

plugins: [
    // 配置提取 css 的外掛,v4 中使用 mini-css-extract-plugin
    new ExtractTextWebpackPlugin({
      filename: '[name].min.css',
      allChunks: true
    }),
    // js tree shaking
    new webpack.optimize.UglifyJsPlugin()
  ]
複製程式碼

在打包結果中,就只剩下了 a 方法:

webpack v3 學習筆記(三) 打包css程式碼 和 Tree Shaking

如果還要對 css 進行 tree shaking,則要藉助 purifycss-webpack 和 glob-all,這裡要注意和 css-module 是衝突的,要把 css-loader 裡的 modules 設為 false。!

npm install purify-css purifycss-webpack glob-all
複製程式碼

我們給 common.scss 新加幾個不用的 css:

.small-box {
    width: 50px;
    height: 50px;
}
.mini-box {
    width: 50px;
    height: 50px
}
複製程式碼

app.js下我們使用了 .small-box

import './css/base.scss'
import common from './css/common.scss'

const div = document.createElement('div')
div.className = 'small-box'
document.body.append(div)

import { a } from './utils/util'

console.log(a())
複製程式碼

在webpack.config.js 下設定外掛

var PurifyCSS = require('purifycss-webpack')
var glob = require('glob-all')

plugins: [
    // 配置提取 css 的外掛,v4 中使用 mini-css-extract-plugin
    new ExtractTextWebpackPlugin({
      filename: '[name].min.css',
      allChunks: true
    }),
    // css tree shaking, 外掛放在 ExtractTextWebpackPlugin 之後
    new PurifyCSS({
      // 原來的壓縮會失效,在這裡重新設定
      minimize: true,
      paths: glob.sync([
        // 使用到 css 的所有檔案的路徑,沒配置對的話用到的 css 也可能被刪掉
        path.join(__dirname, './src/*.js')
      ])
    }),
    // js tree shaking
    new webpack.optimize.UglifyJsPlugin()
  ]
複製程式碼

打包後 css 檔案:

webpack v3 學習筆記(三) 打包css程式碼 和 Tree Shaking

沒用到的類成功去除。

相關文章