1.1何為Webpack
webpack是開源的JS模塊打包工具
核心功能是解決模塊之間的依賴,吧哥哥模塊按照特定的規則和順序組織在一起,最終合并為一個JS文件。這個過程叫模塊打包
1.2為何需要Webpack
1.2.1何為模塊
在設計程序結構時,更好的組織方式是按照特定的功能將其拆分為多個代碼段,每個代碼段實現一個特定的目的。可進行獨立的設計開發測試,最終通過接口來組合在一起,這就是基本的模塊化思想。
1.2.2 JavaScript中的模塊
JavaScript中沒有模塊,Brendan Rich最初設計語言只定位成小型腳本語言。再過去很長時間只能通過script標簽將他們一個個插入頁面,缺點很多:
- 需要手動維護加載順序,依賴關系隱式
- 每個script意味一次請求,拖慢網頁渲染速度
- 每個script標簽頂層作用域即全局作用域,容易造成全局作用域的污染。
模塊化解決了上述問題:
- 通過導入導出語句清晰看到模塊間的依賴關系
- 模塊可以借助工具進行打包,在頁面中只需要加載合并后的資源文件,減少網絡開銷
- 多個模塊之間作用域隔離,彼此不會用命名沖突
2015年, ES6正式定義了JavaScript模塊標準!已得大多數現代瀏覽器支持,但實際應用方面還需要等待一段時間,主要原因:
- 無法使用 code splitting 和 tree shaking
- 大多數npm模塊還是CommonJS形式,瀏覽器不支持其語法,沒法世界拿來用
- 仍然需要考慮個別瀏覽器及平臺的兼容性問題
那么,如何讓我們的工程在使用模塊化的同時也能正常運行在瀏覽器中,就到了模塊打包工具的出場了。
1.2.3模塊打包工具
任務是解決模塊間的依賴,使其打包后的結果能運行在瀏覽器上。工作方式主要分兩種:
- 將存在依賴關系的模塊按照特定規則合并為單個JS文件,一次全部加載進頁面
- 在頁面初始時加載一個入口模塊,其他模塊一步的進行加載
目前社區中比較流行的模塊打包工具Webpack、Parcel、Rollup等
1.2.4 為何選擇Webpack
1) Webpack默認支持多種模塊標準,包括AMD、CommonJS,以及最終的ES6模塊
2)Webpack有完備的代碼分割(code splitting)解決方案
3)Webpack可以處理各種類型的資源
4)Webpack擁有龐大的社區支持。
1.3安裝
安裝Node.js環境
node -v
npm -v
npm安裝Webpack方式:一種全局安裝,一種本地安裝
全局安裝Webpack好處是npm幫我們綁定一個命令行環境變量,一次安裝處處運行
本地安裝則會添加其成為項目中的依賴,只能在項目內部使用。
建議本地安裝方式,主要原因:
- 全局安裝與他人進行項目協作時,由于每個人系統中Webpack版本不同,可能會導致輸出結果不一致
- 部分依賴于Webpack的插件會調用項目中的Webpack的內部模塊,這種情況下仍然需要在項目本地安裝Webpack,而如果全局本地都用則容易混淆
新建一個工程目錄
npm init
生成一個package.json文件
安裝Webpack命令
npm i webpack webpack-cli --save-dev
webpack是核心模塊,webpack-cli則是命令行工具,在本例中兩者是必需的
安裝結束后,在命令行執行npx webpack -v 以及 npx webpack-cli -v 可顯示各自的版本號,即證明安裝成功
1.4打包第一個應用
工程目錄添加以下幾個文件
index.js
import addContent from "./add-content.js";
document.write("my first Webpack app.<br />");
addContent();
add-content.js
export default function () {document.write("Hello world!");
}
index.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>My first Webpack app.</title></head><body><script src="./dist/bundle.js"></script></body>
</html>
在控制臺輸入打包命令
npx webpack --entry=./index.js --output-filename=bundle.js --mode=development
打包效果
用瀏覽器打開index.html,如圖
?
?回顧指令
entry是資源打包入口。webpack從這里開始進行模塊查找
output-filename是輸出資源名,打包完成出現dist目錄包含bundle.js是Webpack打包結果
mode是打包模式(development、production、none),當置于development和production模式下自動添加適合當前模式的一系列配置,減少人為工作量。開發環境一般設置為development模式
1.4.2使用npm script
為了使命令行指令簡潔,我們可以在package.json中添加一個腳本命令
"scripts": {"build": "webpack --entry=./index.js --output-filename=bundle.js --mode=development"},
重新打包輸入npm命令即可
npm run build
1.4.3使用默認目錄配置
通常我們分別設置源碼目錄與資源輸出目錄
工程中創src目錄,并將index.js和add-content.js移動到該目錄下,資源輸出目錄,Webpack已經默認是/dist,源代碼入口Webpack默認就是src/index.js。可以省略掉entry配置
編輯package.json:
"scripts": {"build": "webpack --output-filename=bundle.js --mode=development"},
1.4.4使用配置文件
?Webpack有非常多的配置項以及對應的命令行參數
npx webpack -h
當項目需要越來越多的配置項時,命令維護困難。所以創建一個配置文件,在Webpack每次打包是讀取該配置即可
工程下創建 webpack.config.js
module.exports = {entry: "./src/index.js",output: {filename: "bundle.js",},mode: "development",
};
值得注意的是Webpack對于output.path的要求是使用絕對路徑(從系統根目錄開始的完整路徑),之前我們在命令行中為了簡潔所以使用了相對路徑,而在webpack.config.js中,我們通過調用node.js的路徑拼裝函數——path.join,將__dirname與dist連接起來,得到了最終的資源輸出路徑。
去掉package.json中配置的打包參數了
"scripts": {"build": "webpack"},
1.4.5webpack-dev-server
提高調試效率的本地開發工具 文件修改,自動刷新
npm install webpack-dev-server --save-dev
ps:--save-dev將工具作為devDependencies開發環境依賴,工程上線時要進行依賴安裝可以通過
npm install --production過濾掉devDependencies中的模塊
為了便捷啟動webpack-dev-server,添加dev指令
"scripts": {"dev": "webpack-dev-server","build": "webpack"},
更改webpack.config.js
module.exports = {entry: "./src/index.js",output: {filename: "./bundle.js",},mode: "development",devServer: {publicPath: '/dist',}
};
添加devServer對象專門放webpack-dev-server配置。webpack-dev-server可以看做服務者,接收瀏覽器請求,將資源返回。當服務啟動時,會先讓Webpack進行模塊打包并將資源準備好。當接收到瀏覽器的資源請求時,會首先進行URL地址校驗。如果改地址是資源服務地址(上面配置的publicPath),就從打包結果中尋找該資源返回瀏覽器。反之,地址不屬于資源服務地址,則直接讀取硬盤中的源文件并將其返回。
webpack-dev-server兩大職能:
1.令Webpack進行模塊打包,并處理靜態資源文件請求
2.作為普通的Web Server,處理靜態資源文件請求