寫在前面。
以下的配置,可以實現基礎的使用,無論是在開發環境,還是生產環境。
這是第一個基礎的版本,為了對 webpack4 有個比較大致的認識,以及和 4.0- 版本的區別。
webpack 的主要優勢在於 code splitting(程式碼拆分)
1,零配置是指:
-
entry point(入口點) 預設為 ./src/index.js
-
output(輸出) 預設為 ./dist/main.js
-
production(生產) 和 development(開發) 模式 (無需為生產和開發環境建立2個單獨的配置)
2,零配置介紹
- 在 webpack 4 中,既不必須定義 entry point(入口點) ,也不必須定義 output file(輸出檔案)。
它將查詢 ./src/index.js 作為預設入口點。 而且,它會在 ./dist/main.js 中輸出模組包。
也就是說,當只配置瞭如下檔案,並在根目錄下建立了./src/index.js
,執行npm run build
,就會自動建立.dist/main.js
// package.json
"scripts": {
"build": "webpack"
},
複製程式碼
- webpack 4 引入了 production(生產) 和 development(開發) 模式。
在上面的程式碼執行時,還會有一個警告:
“模式”選項尚未設定。 將 “mode” 選項設定為 “development” 或 “production” 以啟用此環境的預設值。
更改如下:
// package.json
"scripts": {
"build": "webpack --mode production",
"dev": "webpack --mode development"
},
複製程式碼
再執行npm run build
時,就會發現.dist/main.js
中的程式碼都已經被壓縮了(一個壓縮後的 bundle)。
預設使用production mode
(生產模式)時,可以開箱即用地進行各種優化。 包括壓縮,作用域提升,tree-shaking(按需載入) 等。
當執行npm run dev
,會預設使用development mode
(開發模式)針對速度進行優化,僅僅提供了一種不壓縮的 bundle 。
- 覆蓋預設 entry(入口)/output(輸出)
entry(入口)被設定為./demo/src/index.js
,output(輸出)被設定為./demo/main.js
// package.json
"scripts": {
"dev": "webpack --mode development ./demo/src/index.js --output ./demo/main.js",
"build": "webpack --mode production ./demo/src/index.js --output ./demo/dist/main.js"
},
複製程式碼
3,Babel轉譯
使用預設入口和出口。
3.1 依賴項
- babel-core
- 包含了 babel 提供的功能
- babel-loader
- 讓webpack理解 babel 的語法
- babel-preset-env
- 包含 es2015/es2016/es2017 所有新的標準語法的解析器
複製程式碼
npm i babel-core babel-loader babel-preset-env --save-dev
// .babelrc
{
"presets": [
"env"
]
}
複製程式碼
3.2 此時,配置babel-loader
有2種方法
3.2.1 使用 webpack 的配置檔案
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
}
複製程式碼
接著,在./src/index.js
編寫ES6的語法後,npm run dev
就可以在./dist/main.js
中檢視轉譯後的程式碼。
3.2.2 使用 webpack 的配置檔案
--module-bind
引數允許在命令列指定載入器(版本3已經存在了)
// package.json
"scripts": {
"dev": "webpack --mode development --module-bind js=babel-loader",
"build": "webpack --mode production --module-bind js=babel-loader"
},
複製程式碼
同樣的,在./src/index.js
編寫ES6的語法後,npm run dev
就可以在./dist/main.js
中檢視轉譯後的程式碼。
4,webpack 外掛
首先解釋一下外掛plugin,一般關於 html,css 的外掛都會用在生產環境中使用。
因為生產環境中要使用 plugin 進行檔案的生成,而不是在記憶體裡。
4.1 html的生成
- webpack 需要兩個額外的元件來處理HTML:
html-webpack-plugin
和html-loader
。
npm i html-webpack-plugin html-loader --save-dev
這是一個webpack外掛,可以簡化HTML檔案的建立,以便為webpack包提供服務。 並且可以使用如 ejs,lodash 等模板提供的模板。
有的模板,比如
jade
模板,需要配置對應的loader
ejs模板需要下載依賴即可,不需要配置loader
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true } // 載入器切換到優化模式,啟用壓縮。
}
]
}
]
},
plugins: [
new HtmlWebPackPlugin({
// 指定原始檔,比如可以是html檔案,或ejs檔案
template: "./src/index.html",
// 指定生成檔案路徑,和檔名(路徑以出口檔案,所在資料夾為基準)(預設為index.html)
filename: "./index.html",
// 指定生成 html 檔案的 title
title: 'myWebpack'
})
]
};
複製程式碼
// ejs模板檔案,注意<title>標籤,這樣就可以使用指定的title
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
</body>
</html>
複製程式碼
接下來,npm run build
就可以看到在dist資料夾中生成的html檔案,並且title標籤也會對應。
4.2,CSS的提取
- 先說一點寫法的差異:
在之前的版本中,會這樣寫,其中 “!” 用來分隔不同的loader
。
module: {
loaders: [
{
test: /\.css$/,
loader: 'style-loaer!css-loader'
}
]
}
複製程式碼
現在大部分的寫法:
module: {
rules: [
{
test: /\.css$/,
/*
* use作用和 loader相同。
* 陣列中的元素,會順序執行的。下面寫法的會先執行 css-loader,
* 也就是這個形式:style(css(css檔案)),函式巢狀的形式
* css-loader,將css檔案變為 js 模組檔案
* style-loader,將生成一個內容為最終解析完的css程式碼的<style>標籤,新增到頁面的<head>標籤中
* */
use: ['style-loader','css-loader']
}
]
}
複製程式碼
其中,use
可以新增多個loader
,各個loader
就可以新增自己的配置項了。如下例子:
use: [
{
loader: "css-loader",
options: {
sourceMap: false,
minimize: true
}
},
{
loader: 'postcss-loader',
options: {
}
},
]
複製程式碼
- 進入正題,css的提取。
- webpack不知道如何提取,需要藉助
mini-css-extract-plugin
又看到網上說webpack要更新到4.2+的版本,該外掛才會生效。但經過測試,4.16版本也可以。
npm i mini-css-extract-plugin css-loader --save-dev
// webpack.config.js
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true } // 載入器切換到優化模式
}
]
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"]
}
]
},
plugins: [
// 如果使用了html-loader,將會壓縮生成的html檔案
new HtmlWebPackPlugin({
// template: "./src/index.html", // 指定原始檔,比如可以是html檔案,或ejs檔案
template: "./src/index.ejs",
filename: "index.html", // 生成檔名(路徑以出口檔案,所在資料夾為基準)(預設為index.html)
title: 'webpack'
}),
new MiniCssExtractPlugin({
filename: "[name].css",
})
]
};
複製程式碼
// 入口js中引入,該例中,css檔案: src/main.css
import style from './main.css'
複製程式碼
- 這時,在
npm run build
,就可以在dist
資料夾下看到被打包的css
5,webpack dev server
- 配置開發伺服器,可以實現:更改檔案,自動重新整理瀏覽器
npm i webpack-dev-server --save-dev
// package.json
// start新增啟動伺服器,--open表示自動開啟瀏覽器,如果沒有寫,可手動以預設8080埠開啟瀏覽器
"scripts": {
"start": "webpack-dev-server --mode development --open",
"build": "webpack --mode production"
}
複製程式碼
npm run start
,瀏覽器就會開啟,並且自動重新整理。