Webpack
一、市面上有哪些類似於Webpack的前端工程化工具【 自動化工具 】
- grunt
- gulp ( 4.x )
- Browserify ( Webpack 前身 )
- Webpack 【 主流行 】
- rollup.js www.rollupjs.com/guide/zh 【 小眾 】
- parcel 【 小眾 】
- FIS fis.baidu.com/ 【 小眾 】
二、前端工程化工具的發展歷程
- grunt
- gulp ( 4.x ) 流的操作 .pipe()
- Browserify ( Webpack 前身 ) 沒有相容模組化問題( es6 )
- Webpack 【 主流行 】 自動解決模組依賴性問題
總結:
1. 你得知道前端這些年有哪些工程化/自動化工具
2. 前端發展過程中,為啥webpack會逐漸成為流行?
1. grunt vs gulp gulp優勢流式操作
2. webpack vs gulp webpack解決的就是模組化問題
複製程式碼
三、 Webpack版本的發展過程
官網: webpack.js.org/
中文: www.webpackjs.com/
webpack1
支援CMD和AMD,同時擁有豐富的plugin和loader,webpack逐漸得到廣泛應用。
loader: 將某一個型別檔案轉換為其他型別檔案
plugin: 外掛
- 伺服器
- 圖片處理
- 。。。
複製程式碼
webpack2
支援ES Module,分析ESModule之間的依賴關係,
webpack1必須將ES,Module轉換成CommonJS模組,2支援tree sharking
webpack3
新的特性大都圍繞ES Module提出,如Scope Hoisting和Magic Comment;
webpack3以上基本上都可以解決es6提出的模組化
webpack4
可以解決es6模組化【 export default / export import 】
更多個功能性 pulgin【 外掛 】 和 loader 【 轉換器 】
前端框架中廣泛使用: Angular Vue React 的腳手架都是由webpack來進行開發、管理
學習目標:
- 通過webpack自主構建一個專案 【 手動構建一個專案 】
- webpack基本配置
- webpack高階配置
四、 Webpack涉及到的前端環境問題
-
Webpack底層是由 Node.js 來開發的,也就是說Webpack的配置檔案都是 Node.js 檔案
-
Webpack的模組化書寫的規範是Common.js規範
-
環境支援: Node.js 8+
-
前端環境: 【 重點 】
- 開發環境 - 無法直接在伺服器中去執行
- 生產環境 - 將開發環境下的程式碼經過 打包 壓縮 編譯 之後的檔案
- 測試環境 - 將開發環境的程式碼經過 打包 壓縮 編譯 之後的檔案,放在測試環境伺服器中執行
- unit test 單元測試 【 mocha Jest 】
- e2e 端到端測試
- 預上線環境: 將開發環境的程式碼經過 打包 壓縮 編譯 之後的檔案,放到一個區域網中去執行
- 上線環境:將開發環境的程式碼經過 打包 壓縮 編譯 之後的檔案,放到雲伺服器或是伺服器主機中,可以供任何人訪問,使用的一個環境( 這個環境的上線要經過國家稽核 )
-
核心關注點在:
- 開發環境
- 生產環境
五、Webpack的安裝
安裝可以使用任何一個包管理器: npm yarn cnpm
yarn > cnpm > npm
如果有nrm和nvm環境的朋友可以跳過略過這裡
舉例: 我使用npm安裝了一個叫做 node-sass 的包 ,但是出錯了 ,這時,我們想解除安裝,發現解除安裝報錯
解決: 覆蓋安裝
cnpm || yarn 進行覆蓋安裝
cnpm 和 yarn 優先順序沒有那麼絕對
1.全域性安裝( 選擇以下一種即可 )
這裡就是裝兩個包 一個webpack 一個webpack-cli
$ npm install webpack webpack-cli -g
$ cnpm install webpack webpack-cli -g
$ yarn add webpack webpack-cli global
2.區域性安裝
$ npm install webpack webpack-cli -D
$ cnpm install webpack webpack-cli -D
$ yarn add webpack webpack-cli -D
區域性優先順序 > 全域性
安裝完畢後可以使用npm info webpack 檢視資訊
安裝完畢後可以使用webpack --help檢視腳手架命令
六、Webpack的概念
-
webpack* 是一個現代 JavaScript 應用程式的靜態模組打包器(module bundler)。當 webpack 處理應用程式時,它會遞迴地構建一個依賴關係圖(dependency graph),其中包含應用程式需要的每個模組,然後將所有這些模組打包成一個或多個 bundle( 分塊束 )
理解:
舉例: 我們又兩個模組,A模組引用B模組,我們現在使用webpack打包A模組,webpack會自動尋找A和B之間的關係,進而打包B模組
七、Webpack 使用
預設原始碼開發目錄為: src
預設的入口檔名稱為: src/index.js
預設出口目錄為: dist
預設出口打包檔名稱為: main.js
如果要修改預設配置 目錄為 config (沒有限定 但是公認的預設資料夾 通過package.json繫結)
config資料夾下面的檔案:(下面的檔案都需要在package.json中設定終端命令繫結)
webpack-config-dev.js(針對開發環境的專案配置)
webpack-config-prod.js(針對生產環境的專案配置)
通過mode來設定是那個環境下打包使用
開發環境打包: 程式碼不經過壓縮、註釋不會被刪除
eval 這個方法時用來解析字串,這個字串裡面有js程式碼 【 效能不太好 】
預設環境為生產環境
1.終端命令列使用
-
終端執行 webpack
-
當我們區域性安裝了webpack webpack-cli後,發現執行webpack報錯命名找不到
- 解決: 全域性安裝webpack webpack-cli
-
預設生成環境打包
-
-
webpack --mode development/production 開發環境/生產環境打包
-
剛開始建立webpack時需要先執行npm init (-y 跳過除錯) 選擇自己的專案版本錄入(後面需要在此錄入終端命令簡寫)
2.配置檔案使用
- 預設webpack配置性檔名稱為 webpack.config.js,這個檔案是在根目錄下執行的
- 執行 webpack 命令就會自動的去尋找這個 檔案
- webpack.config.js檔案中我們配置的就是 webpack的引數
3.配置webpack.config.js檔案
我們接下來對這個檔案進行配置,主要從以下幾個方面來著手
1. 基礎功能 : 入口 出口 檔案配置 2. 轉換器: loader 3. 外掛: plugin 單頁面配置 vs 多頁面配置 單頁面配置指的只有一個入口一個出口的專案 【 推薦 】 多頁面配置指的是有多個入口多個出口的專案 複製程式碼
1.單頁面配置
1.1 基礎功能
/*
webpack配置檔案
也是Node.js檔案
這個檔案也是一個獨立的 Common.js 模組
*/
const path = require('path')
// 1. 建立模組
const webpackConfig = {
entry: './src/index.js', //網路路徑( 相對路徑 )
output: { //出口目錄、檔案的配置
path: path.join( __dirname,'dist'), // 磁碟路徑
filename: 'js/app.js' // 入口檔案將來打包到出口目錄中的檔案的路徑和名稱
},
mode: 'development'//確定是生產環境還是開發環境的打包
}
// 2. 匯出模組
module.exports = webpackConfig
複製程式碼
1.2 問題: 驗證webpack是否能自動解決模組化依賴問題 可以
1.3 loader 轉換器 可以將其他型別檔案轉換為我們想要的型別檔案
舉例: 實現css的使用
/* ------------------------------- 轉換器 ------------------------------ */
// 在webpack.config.js中做如下配置:
module: { //這裡用來存放轉換器的配置
rules: [
// {} //每一個物件就是一個轉換器的配置
{//css的處理
test: /\.css$/, // 整個專案下匹配 .css結尾的檔案
use: ['style-loader','css-loader'] //兩個順序是不寫反的 下標越大優先順序越提前 這裡需要npm安裝兩個包
// 我們需要使用css-loader將css檔案編譯為js,然後通過style-loader將js處理插入到html檔案中【 style 嵌入模式 】
}
]
},
複製程式碼
1.4 配置前端靜態伺服器
//需要自動重新整理: webServer 搭建前端開發伺服器
cnpm install webpack-dev-server -g | -D
引數:
命令列
webpack-dev-server --port 8080 --open --mode development
webpack-dev-server --port 8080 --config/webpack-config-dev.js
(命令列語句配置config open是開啟 同理設定到package.json 簡化命令列語句)
寫到webpack.config.js配置檔案:
devServer: {//和module同級
port: 8088, //設定埠號
open:true,//是否開啟自動開啟頁面
hot:true,//熱更新
proxy:{}//反向代理
}
終端執行方式2: webpack-dev-server
把執行命令放到package.json檔案: devServer可以不要了
"scripts":{
"dev": "webpack-dev-server --port 8088 --open"
}
終端: npm run dev
複製程式碼
1.5 優雅降級配置
-
先安裝轉換器需要的包
$ cnpm install babel-loader@8.0.4 @babel/core @babel/preset-env -D
-
配置webpack.config.js
// 在webpack.config.js的module.rules中進行配置 {// 配置優雅降級 test: /\.js$/, exclude: /node_modules/, // 排除node_models中的js檔案 use: [{ loader: 'babel-loader',//用來轉換 options: { presets: ['@babel/preset-env']//識別版本 } }] } 複製程式碼
1.6 html產出 - 依賴的是外掛
-
安裝外掛需要的第三方包
$ cnpm i html-webpack-plugin -D
const HtmlWebpackPlugin = require('html-webpack-plugin') //新增一個配置項 plugins:[ new HtmlWebpackPlugin({ template: './public/index.html', filename: './index.html',//預設到output目錄 hash:true,//給打包後的入口檔案新增hash值 防止版本衝突 minify:{ removeAttributeQuotes:true//壓縮 去掉引號 } }) ] 複製程式碼
1.7 css抽離 - 依賴的是外掛
將webpack編譯過得css檔案以 css外部引用的形式引入
-
安裝外掛
$ cnpm i extract-text-webpack-plugin@next -D
const ExtractTextWebapckPlugin= require("extract-text-webpack-plugin") //loader配置: use: ExtractTextWebapckPlugin.extract({ use: 'css-loader' }) //不再需要style-loader //pulgin配置 new ExtractTextWebapckPlugin('css/[name][hash:6].css') //自動引入css檔案 hash為了版本不重複 複製程式碼
1.8 圖片打包
yarn add url-loader file-loader --dev
npm i url-loader file-loader --save-dev
//url-loader 存base64 file-loader存檔案(woff mp3)
{
test:/\.(png|jpg|gif)/,
use:[{
loader: 'url-loader',
options: {
limit: 5000,//4kb=》4*1024 位元組小於5000的 轉換為base64 來減少請求
outputPath: 'images/', //超過5000出口路徑
}
}]
}
//css中引入 | js動態(模組化) 引入
複製程式碼
1.9 靜態資源拷貝
npm i copy-webpack-plugin -D
const CopyWebpackPlugin = require('copy-webpack-plugin')
//plugin配置
new CopyWebpackPlugin([ //將某一個資料夾下的所有資源拷貝到build下,一般為專案中的public和static
{
from: path.resolve(__dirname,'static'),
to:path.resolve(__dirname,'build/static') }
])
複製程式碼
1.10 配置檔案拆分
"dev": "webpack --mode development --config config/webpack.config.dev.js",
"build": "webpack --mode production --config config/webpack.config.prod.js",
"server": "webpack-dev-server --mode development --config config/webpack.config.dev.js"
"start": "npm run dev & npm run server"
複製程式碼
1.11 錯誤資源定製
// 在webpack.config.js中新增如下配置項:
devtool: 'source-map'
制定報錯資訊的源
複製程式碼
console.log中的:
[HMR]指的是熱更新模組
[WDS]webpack dev serve
2.多頁面配置
2.1 基礎功能
/*
webpack配置檔案
也是Node.js檔案
這個檔案也是一個獨立的 Common.js 模組
*/
const path = require('path')
// 1. 建立模組
const webpackConfig = {
entry: { // 多頁面配置,多個入口檔案
'h5': path.join(__dirname, '../src/h5/h5.js'),
'pc': path.join(__dirname, '../src/pc/pc.js'),
'ipad': path.join(__dirname, '../src/ipad/ipad.js')
}, //網路路徑( 相對路徑 )
output: { //出口目錄、檔案的配置
path: path.join( __dirname,'dist'), // 磁碟路徑
filename: 'js/[name].js' // 入口檔案將來打包到出口目錄中的檔案的路徑和名稱
},
mode: 'development'//確定是生產環境還是開發環境的打包
}
// 2. 匯出模組
module.exports = webpackConfig
複製程式碼
解釋: 為什麼我們的檔案要跟上hash字尾?
- 目的: 就是為了建立多個版本,便於版本切換