總結Webpack4常見的配置, 含DEMO, 一步步肥腸詳細,略長, 後續結束時候咱們給出源碼文件。css
- 安裝node
- 安裝webpack
- npm init 初始化項目
複製代碼
// src/index.js
import _ 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.js
const path = require('path')
module.exports = {
entry: './src/index.js',
mode: 'development',
output: {
filename: 'bound.js',
path: path.resolve(__dirname, 'dist')
}
}
複製代碼
而後經過npx執行webpack進行打包。html
或者配成一個script命令也能夠。前端
"scripts": {
"build": "npx webpack -c webpack.config.js"
}
複製代碼
npx webpack
複製代碼
在瀏覽器打開index.html就會發現代碼執行成功了。vue
假設咱們如今須要在index.js引入css文件。node
// index.js
import './style/reset.css'
複製代碼
咱們須要使用專門的loader來解析css, 並把css注入到html文件webpack
npm i -D css-loader style-loader
複製代碼
修改webpack配置文件css3
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已經注入成功了。git
如今前端項目都是使用一些css預處理器來幫助更好的使用CSS,如Sass等。es6
假設咱們如今index.js中須要引入一個base.scss文件。 那麼webpack改如何處理sass/scss文件呢?github
npm install sass-loader node-sass -D
複製代碼
// src/style/base.scss
$bd-bg: pink;
body {
background: $bd-bg;
}
複製代碼
// index.js
import './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的順序從右往左
}
]
}
}
複製代碼
配置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.
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前提是咱們只在生產環境這麼作, 所以你的配置文件的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.js
const 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後面版本應該會內置CSS壓縮, 目前先手工配置。
npm i -D optimize-css-assets-webpack-plugin
複製代碼
更改配置文件:
const OptimizeCSSAssertsPlugin = require('optimize-css-assets-webpack-plugin')
optimization: {
minimizer: [
// 壓縮CSS
new OptimizeCSSAssertsPlugin({})
]
}
複製代碼
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,
// 等等詳細配置見官網
}),
]
}
複製代碼