今天學(xué)習(xí)了一下 Webpack ,只是入門荸型,對其有了一個初步的概念盹靴,大致只是到官方文檔的概念這里。這里將我所學(xué)習(xí)到的這一些皮毛做一個整理瑞妇,以加深自己的理解稿静,并幫助其他和我一樣正在學(xué)習(xí)的同學(xué)。
前置知識 至少對前端開發(fā)有些了解
閱讀時間 10 ~ 20 min
demo 倉庫地址:https://github.com/doooooit/hello-webpack
一辕狰、什么是 Webpack改备,用它來干嘛
每一個 Web App,即便是最簡單的一個頁面蔓倍,也會使用一些其他資源悬钳,比如*.js
,*.css
等等偶翅。不使用 Webpack 前默勾,我們只能自己手動在 HTML
頁面里管理這些依賴,寫一堆<link ... />
, <script src="..."></script>
聚谁,一個兩個還好灾测,但現(xiàn)代的 Web 每一個都有一大堆依賴,而且不光是數(shù)量的問題垦巴,資源有可能是多種類型的,有可能是.js
或者.ts
铭段,可能是.css
或者.less
骤宣,這些文件還需要編譯。如果這些資源用手動管理將是一場災(zāi)難序愚,不僅重復(fù)簡單低效的勞動憔披,還容易出錯,既然是程序員爸吮,那就應(yīng)該盡可能將任務(wù)交給計算機自動處理芬膝。
Webpack 正是為此而生,作為一個現(xiàn)代 JavaScript 應(yīng)用程序的模塊打包器(module bundler)而存在形娇。它將每一個資源文件都視為一個模塊(module)锰霜,當(dāng) webpack 處理應(yīng)用程序時,它會遞歸地構(gòu)建一個依賴關(guān)系圖(dependency graph)桐早,其中包含應(yīng)用程序需要的每個模塊癣缅,然后將所有這些模塊打包成少量的捆包(bundle)厨剪。bundle 通常只有一個,由瀏覽器加載友存。
這張從 Webpack 官網(wǎng)首頁截取的圖片基本可以直觀地看出它是干啥的了祷膳。
在模塊打包這一基本功能的基礎(chǔ)上,Webpack 還有很多令人欣喜的特性屡立,但這不在本文的討論范圍直晨,請參考官方文檔。
二膨俐、它是怎么工作的
Webpack 依照配置文件進行工作勇皇,文件名為webpack.config.js
。在配置文件中吟策,有四個 Webpack 的核心概念儒士,如果不了解這些概念,就不能了解 Webpack檩坚。
1. 入口(Entry)
為了能夠打包所有模塊着撩,Webpack 會構(gòu)建一個依賴關(guān)系圖,而這個圖需要一個入口匾委,來告訴 Webpack 從哪里開始構(gòu)建拖叙。可以將它理解為運行 app 時第一個執(zhí)行的文件赂乐。
module.exports = {
entry: './path/to/my/entry/file.js'
};
入口可以有多個
2. 出口(Output)
既然是打包薯鳍,那把所有東西捆起來之后就會生成(emit)一個捆包(bundle),這個就是出口挨措。在配置文件中挖滤,出口需要兩個屬性,一個是路徑浅役,一個是文件名斩松。
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'), // 路徑
filename: 'my-webpack-output.bundle.js' // 文件名
}
};
3. Loader
Webpack 的目標(biāo)是將所有模塊都打包起來,而使瀏覽器不必關(guān)注這些事情觉既。這些模塊包括但不限于.js
, .css
, .sass
, .png
, etc惧盹,但是 Webpack 只能理解 JavaScript 不能理解其他文件模塊類型可咋辦。上帝說要有光瞪讼,于是便有了 Loader钧椰。它的作用就是把所有非 JavaScript 的模塊轉(zhuǎn)換成 Webpack 能夠理解的模塊。
不同類型的模塊有不同的 Loader符欠,比如.css
可能會用到 css-loader
嫡霞,而.txt
可能會用到raw-loader
。
在配置文件中背亥,對 Loader 需要配置兩個必須的屬性:
1. 識別出是哪種文件( test
屬性)
2. 對識別出的文件使用對應(yīng)的 Loader 以轉(zhuǎn)換它( use
屬性)
const path = require('path');
const config = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-webpack-output.bundle.js'
},
module: { // Loader 模塊轉(zhuǎn)換
rules: [ // test 和 use 要寫在 rules 中秒际,而 rules 要寫在 module 中
{
test: /\.txt$/, // test 屬性悬赏,可以使用正則表達式
use: 'raw-loader' // .txt 文件對應(yīng)的 Loader
}
]
}
};
module.exports = config;
Loader 通常是第三方的,要使用哪個必須先安裝娄徊,比如上文中的 raw-loader
:
npm install --save-dev raw-loader
Loader 的特性
- loader 支持鏈?zhǔn)絺鬟f闽颇。能夠?qū)Y源使用流水線(pipeline)。loader 鏈?zhǔn)降匕凑障群箜樞蜻M行編譯寄锐。loader 鏈中的第一個 loader 返回值給下一個 loader兵多。在最后一個 loader,返回 webpack 所預(yù)期的 JavaScript橄仆。
- loader 可以是同步或異步函數(shù)剩膘。
- loader 運行在 Node.js 中,并且能夠執(zhí)行任何可能的操作盆顾。
- loader 接收查詢參數(shù)怠褐。用于 loader 間傳遞配置。
- loader 也能夠使用 options 對象進行配置您宪。
- 除了使用 package.json 常見的 main 屬性奈懒,還可以將普通的 npm 模塊導(dǎo)出為 loader,做法是在 package.json 里定義一個 loader 字段宪巨。
- 插件(plugin)可以為 loader 帶來更多特性磷杏。
- loader 能夠產(chǎn)生額外的任意文件。
4. 插件(plugins)
Loader 通常只做轉(zhuǎn)換捏卓,但有時候我們會需要進行一些更多的操作极祸,最簡單的比如添加一些注釋信息,這時我們就可以使用插件怠晴,它可以完成 Loader 不能完成的任務(wù)遥金。
Webpack 本身內(nèi)置了一些插件,同時還可以安裝第三方插件或自己寫蒜田。使用 npm 進行安裝汰规。
const HtmlWebpackPlugin = require('html-webpack-plugin'); //通過 npm 安裝
const webpack = require('webpack'); //訪問內(nèi)置的插件
const path = require('path');
const config = {
entry: './path/to/my/entry/file.js',
output: {
filename: 'my-first-webpack.bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader'
}
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin(), // 使用 Webpack 內(nèi)置插件
new HtmlWebpackPlugin({template: './src/index.html'}) // 使用第三方插件
]
};
// 以上插件功能請查閱相應(yīng)文檔
module.exports = config;
三、使用
1. 安裝
Webpack 可以全局安裝物邑,也可以在項目內(nèi)安裝,推薦后者滔金。
npm install --save-dev webpack // 安裝最新版
npm install --save-dev webpack@<version> // 安裝特定版本
2. 編寫配置文件
配置文件名為 webpack.config.js
色解,位于項目的根目錄下。對于本 demo 餐茵,配置文件內(nèi)容如下
const webpack = require('webpack'); // webpack 內(nèi)置插件
const path = require('path'); // 路徑處理
module.exports = {
entry: './entry.js', // 入口
output: {
path: path.resolve(__dirname, 'dist'), // 生成到當(dāng)前目錄的 dist 目錄下
filename: 'bundle.js' // 生成文件名
},
module: { // Loader 寫在 module.rules 中
rules: [
{
test: /\.css$/,
use: [
// 對一個模塊可以使用多個 Loader 科阎,順序傳遞
{ loader: 'style-loader' },
{ loader: 'css-loader',
option: {
modules: true
}
}
]
}
]
}
}
3. 打包
執(zhí)行打包有多種方法,推薦使用在 package.json
中添加 script
字段實現(xiàn)忿族,前提是你已經(jīng)使用 npm 安裝了 Webpack 锣笨。如下
...
"script": {
"build": "webpack"
},
...
然后在終端執(zhí)行命令
npm run build
然后 Webpack 會輸出打包過程的一些信息蝌矛,執(zhí)行完后會在我們指定的 __dirname + dist
目錄下生成 bundle.js 文件。
原來我們的 HTML 文件結(jié)構(gòu)是這樣的:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>Hello Webpack</title>
<link href="./src/css/main.css" rel="stylesheet">
</head>
<body>
<h1>Hello Webpack</h1>
<script src="./src/js/main.js"></script>
</body>
</html>
現(xiàn)在我們只需要這樣:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>Hello Webpack</title>
</head>
<body>
<h1>Hello Webpack</h1>
<script src="dist/bundle.js"></script>
</body>
</html>
后記
本人也是初學(xué)错英,所以可能有錯誤疏漏入撒,歡迎大家指正。
引用
本文中部分文字描述和代碼引用了 Webpack 中文官網(wǎng) 的相關(guān)內(nèi)容椭岩。
版權(quán)聲明 自由轉(zhuǎn)載 - 保持署名 - 不可商用 - 不可演繹 (CC3.0 創(chuàng)意共享3.0許可證)