Webpack 4.X
文章目錄
一、Webpack概述
webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(module bundler)。當 webpack 處理應用程序時,它會遞歸地構建一個依賴關係圖(dependency graph),其中包含應用程序需要的每個模塊,然後將所有這些模塊打包成一個或多個 bundle。
1.1 Webpack的功能
- 代碼轉換:將ES6轉換成ES5的JavaScript語言,把Less轉換成Sass
- 文件優化:壓縮代碼的體積,合併文件
- 代碼分隔:公共頁面的抽離
- 模塊合併:多個模塊合併爲一個模塊
- 自動刷新:啓動一個本地服務器,實現代碼和模塊的熱更新
- 代碼校驗:校驗代碼是否符合規範標準
- 自動發佈:將完成打包後的文件自動發佈到服務器上
二、Webpack的基本構成
- 入口:entry
- 出口:output
- 插件:plugins
- 轉化器:loaders
- 開發服務器:devServer
三、Webpack的安裝
3.1 全局安裝
NPM方式全局安裝Webpack以及webpack-cli
npm install webpack webpack-cli -g
YAEN方式全局安裝Webpack以及webpack-cli
yarn add webpack webpack-cli -g
3.2 局部安裝
初始化環境,配置package.json文件
npm init -y
本地安裝開發環境webpack以及webpack-cli包,生成node_modules
npm webpack webpack-cli -D
devDependencies: ,編寫代碼階段,用於開發環境
dependencies: 代碼被壓縮,發佈到生產環境-g: 全局環境安裝
-y: 表示 “yes”,省略確認步驟,生成默認的配置文件
-D: 表示 “-save-dev”,寫入開發環境
-S: 表示 “-save”,寫入生產環境
@: 定義webpack版本號 例 [email protected]
3.3 初步配置文件
目錄分佈
package.json配置文件
{
"name": "webpack4.x",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^4.1.0"
}
}
webpack.config.js配置文件
const path = require('path');
module.exports = {
// 入口配置
entry:{
entryName:'./src/index.js'
},
// 出口配置
output:{
path:path.resolve(__dirname,'dist'),
filename:'bundle.js'
}
};
生成dist目錄
webpack
按照webpack.config.js的配置對文件打包成dist目錄
四、多入口多出口-entry&output
4.1 入口-entry
入口起點(entry point)指示 webpack 應該使用哪個模塊,來作爲構建其內部 依賴圖的開始。進入入口起點後,webpack 會找出有哪些模塊和庫是入口起點(直接和間接)依賴的。
默認值是 ./src/index.js
但你可以通過在 webpack configuration中配置 entry 屬性,來指定一個(或多個)不同的入口起點。是指在webpack.config.js配置文件中entyr設置多個入口地址和在output設置多個出口地址。
4.2 出口-output
output 屬性告訴 webpack 在哪裏輸出它所創建的 bundle,以及如何命名這些文件。主要輸出文件的默認值是 ./dist/main.js
,其他生成文件默認放置在 ./dist
文件夾中。
4.3 依賴包安裝
- 導入html-webpack-plugin依賴包
npm install html-webpack-plugin -D
html-webpack-plugin 插件生成 HTML5的index.html頁面,當有多入口時,將入口文件自動使用script標籤引入
- 導入clean-webpack-plugin依賴包
npm install clean-webpack-plugin -D
clean-webpack-plugin插件用於刪除/清理已經構建的文件夾
4.3.1 html-webpack-plugin配置表
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-cw5jG9kH-1588677251263)(Webpack.assets/html-webpack-plugin.png)]
詳細配置的使用方式參照網址:
4.4 多入口對應單出口
webpack.config.js配置文件
/*jshint esversion:6*/
// 導入path
const path = require('path');
// 導入html-webpack-plugin
const htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// 設置生產模式
mode:'development',
// 入口配置
entry:{
indexOne:'./src/indexOne.js',
indexTwo:'./src/indexTwo.js'
},
// 出口配置
output:{
path:path.resolve(__dirname,'dist'),
filename:'[name].bundle.js'// 多出口的bundle.js寫法
},
plugins:[
new htmlWebpackPlugin({
// 設置模板
template:'./src/index.html',
// 設置標題
title:'Webpack Learning',
// 消除生成鏈接的緩存,使用隨機哈希碼爲爲後綴
hash:true
})
]
};
src目錄下的 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= htmlWebpackPlugin.options.title%></title>
</head>
<body>
<h3>Webpack學習</h3>
<div id="container">
<div>
<span id="showText1"></span>
<span id="showTest2"></span>
</div>
</div>
</body>
</html>
title 的使用,配合對應的HTML文件,對title標籤內語句聲明:
<%= htmlWebpackPlugin.options.title%>
dist目錄下的 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpack Learning</title>
</head>
<body>
<h3>Webpack學習</h3>
<div id="container">
<div>
<span id="showText1"></span>
<span id="showTest2"></span>
</div>
</div>
<script src="indexOne.bundle.js?5a081682f2f6abb0c542"></script>
<script src="indexTwo.bundle.js?5a081682f2f6abb0c542"></script>
</body>
</html>
4.5 多入口對應多出口
webpack.config.js配置文件
const path = require('path');// 導入path
const HtmlWebpackPlugin = require('html-webpack-plugin');// 導入html-webpack-plugin
const {CleanWebpackPlugin} = require('clean-webpack-plugin');// 導入clean-webpack-plugin
module.exports = {
// 設置生產模式
mode:'development',
// 入口配置
entry:{
One:'./src/webpack_EntryOutput/One.js',
Two:'./src/webpack_EntryOutput/Two.js'
},
// 出口配置
output:{
filename:'[name].js',// 多出口的.js寫法
path:path.resolve(__dirname,'dist/webpack_EntryOutput')
},
// 插件配置
plugins:[
// 每次進行webpack命令後,刪除舊dist目錄
new CleanWebpackPlugin(),
// 生成第一個頁面
new HtmlWebpackPlugin({
filename:'firstPage.html',//爲生成的出口文件設置名字,默認爲index.html
chunks:['One'],// 設置指定引入的模塊
template:'./src/webpack_EntryOutput/indexOld.html',// 設置模板
title:'First page',// 設置標題
hash:true // 消除生成鏈接的緩存,使用隨機哈希碼爲最爲後綴
}),
// 生成第二個頁面
new HtmlWebpackPlugin({
filename:'SecondPage.html',
chunks:['Two'],
template:'./src/webpack_EntryOutput/indexNew.html',
title:'Second page',
hash:true
}),
]
};
src目錄下的 indexOld.html和indexNew.html
- indexOld.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= htmlWebpackPlugin.options.title%></title>
</head>
<body>
<h3>Webpack學習</h3>
<div id="container">
<div>
<span id="showText1"></span>
</div>
</div>
</body>
</html>
- indexNew.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= htmlWebpackPlugin.options.title%></title>
</head>
<body>
<h3>Webpack學習</h3>
<div id="container">
<div>
<span id="showText2"></span>
<div id="class"></div>
</div>
</div>
</body>
</html>
dist目錄下的 firstPage.html和secondPage.html
- firstPage.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>First page</title>
</head>
<body>
<h3>Webpack學習</h3>
<div id="container">
<div>
<span id="showText1"></span>
</div>
</div>
<script src="One.bundle.js?4b3ddb68e68a51656ea5"></script></body>
</html>
- secondPage.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Second page</title>
</head>
<body>
<h3>Webpack學習</h3>
<div id="container">
<div>
<span id="showText2"></span>
<div id="class"></div>
</div>
</div>
<script src="Two.bundle.js?4b3ddb68e68a51656ea5"></script></body>
</html>
五、開發服務器-devServer
webpack-dev-server 是在devServer裏運行的插件,用於本地開發的工具,它支持代碼熱更新和模塊組件熱更新,能迅速將更改後的代碼和模塊更新到瀏覽器中。熱更新的功能適用於開發模式之中,讓用戶開發更迅速便捷,而不適用於生產環境。
- 導入webpack-dev-server依賴包
npm install webpack-dev-server -D
- 配置webpack.config.js文件的devServer項
module.exports = {
devServer:{
// 設置服務器基本的訪問目錄
contentBase: paht.resolve(__dirname,'dist'),
host: 'localhost', // 服務器IP地址
port: 8089, // 設置端口
open: true // 自動打開頁面
hot:true // 開啓熱更新功能
}
}
- 配置webpack.config.js文件的plugins項
const webpack = require('webpack'); //引入webpack
module.exports = {
plugins:{
new webpack.HotModuleReplacementPlugin() //配合dveServer的Hot開啓熱更新
}
}
- 配置package.json文件的scripts項
"scripts": {
"dev": "webpack-dev-server"
}
- 運行webpack-dev-server
npm run dev
- 瀏覽器輸入對應的IP地址和端口號,默認進入index.html頁面
http://loclahost:8089
六、加載器-Loader
webpack 只能理解 JavaScript 和 JSON 文件。loader 讓 webpack 能夠去處理其他類型的文件,並將它們轉換爲有效 模塊,以供應用程序使用,以及被添加到依賴圖中。
6.1 CSS文件的加載與提取分離
6.1.1 CSS文件加載到JS文件中
- 創建style.css文件
body{
background: #cccccc
}
- 創建index.js文件
import '../css/style.css'; // index.js文件裏導入css路徑
document.write('----輸出到頁面的文字----');
- 安裝style-loader與css-loader依賴包
npm install style-loader css-loader -D
- 在weboack.config.js文件配置module的rules規則
module: {
rules: [
{
test: /\.css$/, //正則判斷尋找.css文件
loader: ['style-loader','css-loader']
}
],
}
loader 的三種書寫方式:
loader: [ ‘style-loader’,‘css-loader’ ]
use: [ ‘style-loader’,‘css-loader’ ]
use: [
{loader: ‘style-loader’},
{loader: ‘cssloader’}
]
- 配置package.jsom文件
{
"scripts":{
"dev":"webpack-dev-server --mode development"
}
}
- 開啓開發服務器devServer查看
npm run dev
6.1.2 CSS文件的提取分離
- 安裝extract-text-webpack-plugin依賴包
npm i extract-text-webpack-plugin -D
- webpack.config.js配置
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
module.exports = {
module: {
rules:[
test:/\.css$/,
use:ExtractTextWebpackPlugin.extract({
fallback:'style-loader', // 回滾函數
use:'css-loader',
publicPath:'../' //css文件爲找圖片設置靜態路徑
}
),
]
},
plugins: [
//定義打包後的路徑以及css文件的名稱
new ExtractTextWebpackPlugin('./css/main.css')
]
};
- 配置package.json
{
"scripts":{
"dev":"webpack-dev-server --mode development"
}
}
- 運行webpack進行打包
npm run build
6.2 Less文件的加載與提取分離
6.2.1 Less文件加載到JS文件中
- 安裝less與less-loader依賴包
npm i less less-loader -D
- 添加style.less文件並設置樣式
@a: pink;
#div-less{
color: @a;
ul{
li{
list-style: none;
height: 60px;
line-height: 30px;
}
}
}
- 將路徑導入index.js文件內
import '../less/style.less';
- 配置webpack.config.js
module: {
rules: [
{
test: /\.less$/, //正則判斷尋找.less文件
loader: ['style-loader','css-loader','less-loader']
}
],
}
- 運行webpack進行打包
npm run build
6.2.2 Less文件的提取分離
- 安裝extract-text-webpack-plugin依賴包
npm i extract-text-webpack-plugin -D
- webpack.config.js配置
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
module.exports = {
module: {
rules:[
{
test:/\.less$/,
use:ExtractTextWebpackPlugin.extract({
fallback:'style-loader', // 回滾函數
use:['css-loader','less-loader']
}
}
),
]
},
plugins: [
//定義打包後的路徑以及css文件的名稱
new ExtractTextWebpackPlugin('./css/main.css')
]
};
- 配置package.json
{
"scripts":{
"dev":"webpack-dev-server --mode development"
}
}
- 運行webpack進行打包
npm run build
6.3 Sass文件的加載與分離
6.3.1 Sass文件加載到JS文件中
- 安裝less與less-loader依賴包
npm i node-sass sass-loader -D
- 添加style.less文件並設置樣式
$color: blue;
#div-sass{
color: $color;
ul{
li{
list-style: none;
height: 60px;
line-height: 30px;
}
}
}
- 將路徑導入index.js文件內
import '../sass/style.scss';
- 配置webpack.config.js
module: {
rules: [
{
test: /\.(sass|scss)$/, //正則判斷尋找.less文件
loader: ['style-loader','css-loader','sass-loader']
}
],
}
- 運行webpack進行打包
npm run build
6.3.2 Sass文件的提取分離
- 安裝extract-text-webpack-plugin依賴包
npm i extract-text-webpack-plugin -D
- webpack.config.js配置
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
module.exports = {
module: {
rules:[
{
test:/\.(sass|scss)$/,
use:ExtractTextWebpackPlugin.extract({
fallback:'style-loader', // 回滾函數
use:['css-loader','sass-loader']
}
}
),
]
},
plugins: [
//定義打包後的路徑以及css文件的名稱
new ExtractTextWebpackPlugin('./css/main.css')
]
};
- 配置package.json
{
"scripts":{
"dev":"webpack-dev-server --mode development"
}
}
- 運行webpack進行打包
npm run build
6.4 CSS冗餘代碼優化
- 安裝purifycss-webpack與purify-css依賴包
npm i purifycss-webpack purify-css -D
- 安裝glob依賴包
npm i glob -D # 用於掃描路徑
- webpack.config.js配置
const purifyCssWebpack = require('purifycss-webpack');
const glob = require('glob');
module.exports = {
plugins: [
new purifyCssWebpack({
pahts:glob.sync(path.join(__dirname,'src/*.html'));
// glob 用於掃描項目的路徑
});
]
};
6.5 圖片文件的加載
- 安裝url-loader與file-loader依賴包
cnpm i file-loader url-loader -D
- 在weboack.config.js文件配置module的rules規則
module: {
rules:[
{
test:/\.(png|jpg|gif)$/,
use:[{
loader:'url-loader',
options:{
limit:50, // 文件大小限制
outputPath:'images' //圖片輸出的目錄路徑
}
}
]
}
]
}
- style.css文件添加樣式
body {
bsckground: url('./imgs/bz.jpg');
}
- 在index.js文件導入stylle.css文件
import './css/style.css';
- 開啓開發服務器devServer查看
npm run dev
七、靜態資源輸出
開發項目中會有沒有引用的圖片資源或者其他靜態資源這些靜態資源有可能是文檔,也有可能是一些額外的圖片。打包時保留這些靜態資源,直接打包到制定文件夾。
- 安裝copy-webpack-plugin依賴包
npm i copy-webpack-plugin -D
- webapck.config.js的配置
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports{
plugins: [
new CopyWebapckPlugin([{
// 靜態資源源文件路徑
from:path.resolve(__dirname,'src/assets'),
to:'../public', // 打包的路徑
}]
),
]
};
八、引入第三方庫
8.1 使用npm下載引入
npm i jquery -S
8.2 使用ProvidePlugin
const webpack = require('webapck');
module.export = {
plugins: [
new webapck.ProvidePlugin({
$: 'jqury' // 引入Jquery庫
});
]
};
九、提取第三方JS庫
- 配置webpack.config.js
const webapck = require('webapck');
module.exports = {
entry: {
jquery: 'jquery'
}
optimization: {
splitchunks: {
cacheGroups:{
vendor: {
chunks: 'initial',
name:'jquery',
enforce:true
}
}
}
}
};
十、Vue.js的引入
- 安裝vue依賴包
npm i vue -S
- 在Test.js文件中導入vue依賴包
import Vue from 'vue';
new Vue({
el:'#app',
data: {
message: 'Hello Webpack'
}
});
3.配置webpack.config.js
module.exports = {
resolve: {
// 取別名
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
};
webpack打包Vue後,會默認使用runtiom-only,此時代碼Vue所指定的template不會被編譯,瀏覽器不顯示效果。故應該要對vue進行取別名的配置,將使用具有有runtiom-compiler模式的Vue版本。
- runtime-only : 代碼中不包含有template
- runtime-compiler : 代碼中包含有template,使用compiler對其進行編譯
- 進行打包操作
npm run build
十一 、vue文件的封裝處理
- 安裝vue-loader與vue-template-compiler依賴包
npm vue-loader vue-template-compiler -D
- 創建Vue.vue文件
<template>
<h1 class="title">{{name}}</h1>
</template>
<script>
export default {
name: 'App',
data(){
return {
name: 'Vue文件的封裝處理'
}
}
}
</script>
<style scoped>
.title {
color: blue;
}
</style>
- 配置webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
use: ['vue-loader']
}
]
}
};
- 在main.js文件中導入Vue.vue
import App from './vue/App.vue'
new Vue({
el: '#app',
template: '<App/>',
components: {
App
}
})
- 在index.html文件中掛載對應ID
<!DOCTYPE>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue</title>
</head>
<body>
<div id = "app">
</div>
</body>
</html>