打包 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
})
]
}
複製程式碼
打包效果如下:
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 下的三個函式都會打包進去:
然後我們使用外掛,在設定中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 方法:
如果還要對 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 檔案:
沒用到的類成功去除。