一. 簡介
1. Webpack背景
(1). 事實上随着前端的快速發展,目前前端的開發已經變的越來越複雜了:
A. 比如開發過程中我們需要通過子產品化的方式來開發;
B. 比如也會使用一些進階的特性來加快我們的開發效率或者安全性,比如通過ES6+、TypeScript開發腳本邏輯, 通過sass、less等方式來編寫css樣式代碼;
C. 比如開發過程中,我們還希望實時的監聽檔案的變化來并且反映到浏覽器上,提高開發的效率;
D. 比如開發完成後我們還需要将代碼進行壓縮、合并以及其他相關的優化;
(2). 但是對于很多的前端開發者來說,并不需要思考這些問題,日常的開發中根本就沒有面臨這些問題:
A. 這是因為目前前端開發我們通常都會直接使用三大架構來開發:Vue、React、Angular;
B. 但是事實上,這三大架構的建立過程我們都是借助于腳手架(CLI)的;
C. 事實上Vue-CLI、create-react-app、Angular-CLI都是基于webpack來幫助我們支援子產品化、less、TypeScript、打包優化等的;
2. Webpack是什麼?
官方解釋:webpack is a static module bundler for modern JavaScript applications. ( webpack是一個靜态的子產品化打包工具,為現代的JavaScript應用程式;)
PS:
- 打包bundler:webpack可以将幫助我們進行打包,是以它是一個打包工具
- 靜态的static:這樣表述的原因是我們最終可以将代碼打包成最終的靜态資源(部署到靜态伺服器);
- 子產品化module:webpack預設支援各種子產品化開發,ES Module、CommonJS、AMD等;
- 現代的modern:我們前端說過,正是因為現代前端開發面臨各種各樣的問題,才催生了webpack的出現和發展;
官網位址:https://webpack.docschina.org/ (中文版)
https://webpack.js.org/ (英文版)

3. 使用Webpack的前提
需要安裝nodejs,安裝步驟詳見:https://www.cnblogs.com/yaopengfei/p/14478126.html
該系列使用的node版本和npm版本如下:
4. 全局安裝和預設打包
(PS:這裡主要是為了進行快速入門,進行全局安裝和簡單的打包,在實際開發中,很少這麼用,都是局部安裝,項目不同,可能安裝的webpack版本也不同)
說明:
(1). 全局安裝webpack,指令和版本如下
【npm install webpack webpack-cli -g】
(2). 建立1個工程,在src/js檔案夾下,建立t1.js 和 t2.js
t1.js 是commonjs的寫法,代碼如下
// 下面是commonjs的寫法
const getPrice=function(){
return "$100";
}
// 對外導出
module.exports={
getPrice
}
View Code
t2.js 是 ES6 Module的寫法,代碼如下
// 下面是 ES6 的寫法
export function sum(num1,num2){
return num1+num2;
}
(3). 在src目錄下建立index.js檔案,然後導入t1.js 和 t2.js
// commonjs的導入
const {getPrice}=require('./js/t1');
// ES6的導入
import {sum} from './js/t2.js';
// 調用
console.log(getPrice());
console.log(sum(10,20));
(4). 運作下面指令進行打包
【webpack】
當我們運作webpack時,webpack會查找目前目錄下的 src/index.js作為入口;然後在dist檔案夾下生成main.js打包後的檔案,這就是預設規範 (如果目前項目中沒有存在src/index.js檔案,那麼會報錯)。
PS:也可以指定入口檔案,指定打包後的檔案名和存放路徑。
【 npx webpack --entry ./src/index.js --output-path ./build】
(5). 引入打包後的檔案,進行運作。
<body>
<div>測試打包問題</div>
<!-- 報錯 -->
<!-- <script src="src/index.js" ></script> -->
<!-- 調用打包後的檔案 -->
<script src="dist/main.js" ></script>
</body>
二. 局部安裝和配置打包
1. 局部安裝和預設打包
(1). 準備基礎項目
src/js下的t1.js 、t2.js; src下的index.js
(2). 運作指令【npm init -y】初始化項目
(3). 運作下面指令,進行webpack的局部安裝(且開發依賴)
【npm install webpack webpack-cli -D】
生成的package.json檔案如下:
{
"name": "01_webpack_localBundle",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^5.52.1",
"webpack-cli": "^4.8.0"
}
}
(4). 運作指令【npx webpack】進行打包
(或者将package.json中scripts标簽進行如下改變,然後運作指令【npm run build】進行打包)
"scripts": {
"build": "webpack"
},
同樣會在dist檔案夾下生成1個main.js檔案,調用即可。
2. 通過配置檔案打包(推薦)
(1). 建立 webpack.config.js 配置檔案(預設名稱就叫這個,不建議改)
指定入口檔案、打包後的存放路徑、打包後的檔案
// 這裡必須通過 commonjs的寫法配置,不能寫 ES6的寫法
const path = require('path');
module.exports = {
entry: "./src/main.js", //入口檔案
output: {
path: path.resolve(__dirname, "./build"), //打包後存放路徑, 必須寫絕對路徑
filename: "bundle.js" //打包後的檔案名稱
}
}
(2). 運作指令【npm run build】,則會在build檔案夾下生成一個 bundle.js檔案,進行調用即可。
PS: webpack.config.js這麼預設檔案名也可以改,但需要修改下面代碼(不建議改!!)
三. 常用loader
1. 什麼是loader?
[常用loader詳見官方文檔:https://webpack.docschina.org/loaders/]
(1). webpack在處理應用程式時,它會根據指令或者配置檔案找到入口檔案;
從入口開始,會生成一個 依賴關系圖,這個依賴關系圖會包含應用程式中所需的所有子產品(比如.js檔案、css檔案、圖檔、字型等);
然後周遊圖結構,打包一個個子產品(根據檔案的不同使用不同的loader來解析);
(2). loader 可以用于對子產品的源代碼進行轉換;在加載這個子產品時,webpack其實并不知道如何對其進行加載,我們必須制定對應的loader來完成這個功能;
比如:對于加載css檔案來說,我們需要一個可以讀取css檔案的loader;這個loader最常用的是css-loader;
2. loader的配置方式
3. css-loader 和 style-loader
(1). 作用
css-loader用于加載解析css檔案,并不會将解析之後的css插入到頁面中,
style-loader用于将css插入<style>标簽的操作,是以這兩個loader通常是一塊使用。
(2). 實戰配置
A. 準備代碼
style.css樣式檔案
.title{
font-size: 20px;
background-color: antiquewhite;
font-weight: bold;
color: blue;
}
ceateHtml.js 檔案
import "../css/style.css";
const divEl = document.createElement("div");
divEl.className = "title";
divEl.innerHTML = "Hello,ypf";
document.body.appendChild(divEl);
createHtml.js檔案需要導入到入口檔案main.js中。
B. 安裝兩個loader
【npm install css-loader -D】
【npm install style-loader -D】
C. 進行配置,webpack.config.js檔案如下
// 這裡必須通過 commonjs的寫法配置,不能寫 ES6的寫法
const path = require('path');
module.exports = {
entry: "./src/main.js", //入口檔案
output: {
path: path.resolve(__dirname, "./build"), //打包後存放路徑, 必須寫絕對路徑
filename: "bundle.js" //打包後的檔案名稱
},
module: {
rules: [{
test: /\.css$/, //(表示所有的css結尾的檔案都進行比對)
use: [
// 此處的執行順序是由下往上(下面寫法是簡化寫法)
"style-loader",
"css-loader"
]
}]
}
}
也可以完整寫法:
module: {
rules: [{
test: /\.css$/, //(表示所有的css結尾的檔案都進行比對)
use: [
// 完整寫法,執行順序是由下往上
{ loader: "style-loader" },
{ loader: "css-loader" }
]
}]
}
D. 打包并測試
運作指令【npm run build】,運作結果如下:
4. less-loader
将less檔案轉換成css檔案,通常需要配合css-loader、style-loader一起使用
title.less
@textDecoration: underline;
.title {
text-decoration: @textDecoration;
}
需要将title.less導入對應的js檔案中
B. 安裝loader
【npm install less -D】
【npm install less-loader -D】
注:less-loader依賴less,所有需要先安裝less。
C. 進行配置 webpack.config.js, 代碼如下:
module: {
rules: [{
test: /\.css$/, //(表示所有的css結尾的檔案都進行比對)
use: [
// 完整寫法,執行順序是由下往上
{ loader: "style-loader" },
{ loader: "css-loader" }
]
},
{
test: /\.less$/, //(表示所有的less結尾的檔案都進行比對)
use: [
// 簡化寫法,執行順序是由下往上
"style-loader",
"css-loader",
"less-loader"
]
}
]
}
D. 打包測試
【npm run build】
補充:上面的less元件可以直接把less檔案轉換成css檔案,指令如下:
【npx lessc ./src/css/title.less title.css】
5. postcss-loader 和 插件autoprefixer
(1). 作用
postcss-loader:我們進行一些CSS的轉換和适配,比如自動添加浏覽器字首、css樣式的重置
autoprefixer:用于添加字首
(2). 實戰
A. 安裝loader
【npm install postcss postcss-cli -D】
【npm install autoprefixer -D】
【npm install postcss-loader -D】
B. 進行配置
module: {
rules: [
{
test: /\.css$/, //(表示所有的css結尾的檔案都進行比對)
use: [
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
require("autoprefixer")
]
}
}
}
]
}
]
},
C. 打包測試
【npm run build】
6. 補充:指令行使用postcss 和 postcss-preset-env
【npx postcss --use autoprefixer -o end.css ./src/css/style.css】
【npm install postcss-preset-env -D】
postcss-preset-env:postcss-preset-env也是一個postcss的插件;幫助我們将一些現代的CSS特性,轉成大多數浏覽器認識的CSS,并且會根據目标浏覽器或者運作時環境添加所需的polyfill,也包括會自動幫助我們添加autoprefixer(是以相當于已經内置了autoprefixer);
!
- 作 者 : Yaopengfei(姚鵬飛)
- 部落格位址 : http://www.cnblogs.com/yaopengfei/
- 聲 明1 : 如有錯誤,歡迎讨論,請勿謾罵^_^。
- 聲 明2 : 原創部落格請在轉載時保留原文連結或在文章開頭加上本人部落格位址,否則保留追究法律責任的權利。