標題黨
總結Webpack4常見的配置, 含DEMO, 一步步肥腸詳細,略長, 後續結束時候我們給出原始碼檔案。
準備開發環境
- 安裝node- 安裝webpack- npm init 初始化專案複製程式碼
目錄結構
寫跑一個小demo
// src/index.jsimport _ from 'lodash'function create_div_element () {
const div_element = document.createElement('div') div_element.innerHTML = _.join(['kobe', 'cpul'], ' ') return div_element
}const div_ele = create_div_element()document.body.appendChild(div_ele)複製程式碼
// dist/index.html<
!DOCTYPE html>
<
html lang="en">
<
head>
<
meta charset="UTF-8">
<
title>
webpack4<
/title>
<
/head>
<
body>
<
script src="./bound.js">
<
/script>
<
/body>
<
/html>
複製程式碼
// webpack.config.jsconst path = require('path')module.exports = {
entry: './src/index.js', mode: 'development', output: {
filename: 'bound.js', path: path.resolve(__dirname, 'dist')
}
}複製程式碼
然後通過npx執行webpack進行打包。
或者配成一個script命令也可以。
"scripts": {
"build": "npx webpack -c webpack.config.js"
}複製程式碼
npx webpack複製程式碼
在瀏覽器開啟index.html就會發現程式碼執行成功了。
webpack處理CSS
假設我們現在需要在index.js引入css檔案。
// index.jsimport './style/reset.css'複製程式碼
我們需要使用專門的loader來解析css, 並把css注入到html檔案
npm i -D css-loader style-loader複製程式碼
修改webpack配置檔案
const path = require('path')module.exports = {
entry: './src/index.js', mode: 'development', output: {
filename: 'bound.js', path: path.resolve(__dirname, 'dist')
}, module: {
rules: [ {
test: /\.css/, use: ['style-loader', 'css-loader'] // use的順序從右往左
} ]
}
}複製程式碼
這個時候你在npx webpack, 打包後執行index.html你會發現css已經注入成功了。
webpack處理sass檔案
現在前端專案都是使用一些css前處理器來幫助更好的使用CSS,如Sass等。
假設我們現在index.js中需要引入一個base.scss檔案。那麼webpack改如何處理sass/scss檔案呢?
npm install sass-loader node-sass -D複製程式碼
// src/style/base.scss$bd-bg: pink;
body {
background: $bd-bg;
}複製程式碼
// index.jsimport './style/base.scss'複製程式碼
更過配置檔案處理scss
const path = require('path')module.exports = {
entry: './src/index.js', mode: 'development', output: {
filename: 'bound.js', path: path.resolve(__dirname, 'dist')
}, module: {
rules: [ {
test: /\.(sc|sa|c)ss$/, use: ['style-loader', 'css-loader', 'sass-loader'] // use的順序從右往左
} ]
}
}複製程式碼
webpack為sass新增source map
配置source map是為了當出現錯誤時候方便我們進行定位除錯, 當然我們在生產環境不需要啟動這個。
像我們上面例子中, 你會發現打包後我們看不出scss來自哪個檔案。
修改webpack配置檔案。
const path = require('path')module.exports = {
entry: './src/index.js', mode: 'development', output: {
filename: 'bound.js', path: path.resolve(__dirname, 'dist')
}, module: {
rules: [ {
test: /\.(sc|sa|c)ss$/, use: [ {
loader: 'style-loader'
}, {
loader: 'css-loader', options: {
sourceMap: true
}
}, {
loader: 'sass-loader', options: {
sourceMap: true
}
} ]
} ]
}
}複製程式碼
打包後在瀏覽器開啟index.html.
webpack為css新增CSS3字首
PostCSS是一個用 JavaScript 工具和外掛轉換 CSS 程式碼的工具, 功能強大, 我們最常用的就是利用PostCSS幫我們Autoprefixer 自動獲取瀏覽器的流行度和能夠支援的屬性,並根據這些資料幫你自動為 CSS 規則新增字首。
npm i -D postcss-loader autoprefixer postcss-import// postcss-import: 在使用@import css檔案時候讓webpack可以監聽並編譯// postcss-nextcss: 支援css4複製程式碼
修改配置檔案
rules: [ {
test: /\.(sc|sa|c)ss$/, use: [ {
loader: 'style-loader'
}, {
loader: 'css-loader', options: {
sourceMap: true
}
}, {
loader: 'postcss-loader', options: {
ident: 'postcss', sourceMap: true, plugins: loader =>
[ // 可以配置多個外掛 require('autoprefixer')({
browsers: [' >
0.15% in CN ']
}) ]
}
}, {
loader: 'sass-loader', options: {
sourceMap: true
}
} ]
}]複製程式碼
抽離樣式表為單獨的css檔案並打版本號
抽離css前提是我們只在生產環境這麼做, 因此你的配置檔案的mode: production。
另外抽離了css就不能在使用style-loader注入到html檔案。
npm i -D mini-css-extract-plugin複製程式碼
配置一個script命名
"scripts": {
"dist": "cross-env NODE_ENV=production npx webpack --progress --config webpack.prod.config.js"
},複製程式碼
新增一個webpack.prod.config.js.當然正式專案我們是會拆分配置檔案, 然後通過merge處理。
- webpack.base.config.js- webpack.dev.config.js- webpack.prod.config.js- webpack.vue.config.js複製程式碼
這裡demo就沒有這麼做, 所以程式碼有些冗餘。
// webpack.prod.config.jsconst path = require('path')const MiniCssExtractPlugin = require('mini-css-extract-plugin')const devMode = process.env.NODE_ENV !== 'production'module.exports = {
entry: './src/index.js', mode: 'production', output: {
filename: 'bound.js', path: path.resolve(__dirname, 'dist')
}, module: {
rules: [ {
test: /\.(sc|sa|c)ss$/, use: [ MiniCssExtractPlugin.loader, {
loader: 'css-loader'
}, {
loader: 'postcss-loader', options: {
ident: 'postcss', plugins: (loader) =>
[ require('autoprefixer')({
browsers: [ 'last 10 Chrome versions', 'last 5 Firefox versions', 'Safari >
= 6', 'ie >
8' ]
}) ]
}
}, {
loader: 'sass-loader'
} ]
} ]
}, plugins: [ new MiniCssExtractPlugin({
filename: devMode ? '[name].css' : '[name].[hash:5].css', // 設定輸出的檔名 chunkFilename: devMode ? '[id].css': '[id].[hash:5].css'
}) ]
}複製程式碼
打包後你會發現
這個時候我們如果去使用只能在index.html去引用它了, 很明顯這是不方便的, 因為我們css檔案肯定很龐大, 後面會解決這個問題, 這裡就略過。
webpack壓縮JS和CSS
壓縮的作用自然是為了減小包的體積了, 提升載入效率, 因此壓縮都是配置在生產環境。
壓縮css
Webpack後面版本應該會內建CSS壓縮, 目前先手工配置。
npm i -D optimize-css-assets-webpack-plugin複製程式碼
更改配置檔案:
const OptimizeCSSAssertsPlugin = require('optimize-css-assets-webpack-plugin')optimization: {
minimizer: [ // 壓縮CSS new OptimizeCSSAssertsPlugin({
}) ]
}複製程式碼
JS壓縮
npm i -D uglifyjs-webpack-plugin複製程式碼
修改配置檔案
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')optimization: {
minimizer: [ // 壓縮JS new UglifyJsPlugin({
// 有很多可以配置 cache: true, parallel: true, sourceMap: true, uglifyOptions: {
// 在UglifyJs刪除沒有用到的程式碼時不輸出警告 warnings: false, output: {
// 刪除所有的註釋 comments: false, // 最緊湊的輸出 beautify: false
}, compress: {
// 刪除所有的 `console` 語句 // 還可以相容ie瀏覽器 drop_console: true, // 內嵌定義了但是隻用到一次的變數 collapse_vars: true, // 提取出出現多次但是沒有定義成變數去引用的靜態值 reduce_vars: true,
}
}
}) ]
}複製程式碼
這個時候去打包我發現一個錯誤, ERROR in js/background.js from UglifyJs Unexpected token: keyword (const)。
Uglify-js不支援es6語法,請使用terser外掛, 於是我們更改使用terser外掛試試, 其實你繼續用uglifyjs-webpack-plugin也可以, 只需要配合babel先轉下。
npm install terser-webpack-plugin -D複製程式碼
更多使用見官網terser-webpack-plugin。
optimization: {
minimizer: [ // 壓縮JS new TerserPlugin({
cache: true, parallel: true, sourceMap: true, // 等等詳細配置見官網
}), ]
}複製程式碼