官網(wǎng)
中文文檔
中文文檔
webpack
是目前前端工程化實(shí)踐中最常用的打包工具,學(xué)習(xí)webpack
兔毙,有利于我們掌握前端模塊化編程赶舆,也是我們?cè)趯W(xué)習(xí)React
,Vue
等框架時(shí)做為重要支撐。
以下是官方和中文文檔對(duì)webpack
的概括
At its core, webpack is a static module bundler for modern JavaScript applications. When webpack processes your application, it recursively builds a dependency graph that includes every module your application needs, then packages all of those modules into one or more bundles.
本質(zhì)上叙量,webpack 是一個(gè)現(xiàn)代 JavaScript 應(yīng)用程序的靜態(tài)模塊打包器(module bundler)九串。當(dāng) webpack 處理應(yīng)用程序時(shí)猪钮,它會(huì)遞歸地構(gòu)建一個(gè)依賴關(guān)系圖(dependency graph),其中包含應(yīng)用程序需要的每個(gè)模塊涯呻,然后將所有這些模塊打包成一個(gè)或多個(gè) bundle。
起步
安裝
創(chuàng)建目錄闯第,初始化npm。
mkdir webpack-demo && cd webpack-demo
cnpm init
cnpm install webpack --save-dev
說明:
-
cnpm是淘寶npm鏡像蛛淋,使用方法和
npm
一樣叛甫。可以幫助我們提升包的下載速度。 -
cnpm install {packeg_name} --save-dev
,package_name
為要下載的包名稱,--save-dev
勘天,表示將package-name
添加到package.json
的devDependencies
中。
創(chuàng)建兩個(gè)文件測(cè)試伏伐,index.html
堤器,index.js
辉川。
index.html
<html>
<head>
<title>Getting Started</title>
</head>
<body>
<script src="./dist/bundle.js"></script>
</body>
</html>
其中表蝙,bundle.js
是我們等會(huì)要生成的文件,先不用了解
index.js
function component() {
var element = document.createElement('div');
element.innerHTML = 'hello webpack'
return element;
}
document.body.appendChild(component());
此時(shí)的目錄結(jié)構(gòu)為:
webpack-demo
node_modules
src
index.js
index.html
package.json
將項(xiàng)目搭建成上述結(jié)構(gòu)乓旗,我們就能學(xué)習(xí)第一個(gè)命令webpack
府蛇。我們的目標(biāo)就是以index.js
為入口,生成一個(gè)bundle.js
文件屿愚,供index.html
使用汇跨。
webpack src/index.js dist/bundle.js
Hash: 629328b9dd2012d414f7
Version: webpack 3.10.0
Time: 59ms
Asset Size Chunks Chunk Names
bundle.js 2.64 kB 0 [emitted] main
[0] ./src/index.js 170 bytes {0} [built]
如果出現(xiàn)上訴回應(yīng),就說說明執(zhí)行成功妆距。此時(shí)我們的項(xiàng)目結(jié)構(gòu)是這樣的:
webpack-demo
dist
bundle.js
node_modules
src
index.js
index.html
package.json
可以看到dist/bundle.js
就是webpack
替我們生成的穷遂。
在瀏覽器中打開index.html
,可以看到hello webpack
毅厚。
我們來看bundle.js
究竟是個(gè)什么東西塞颁。
cat dist/bundle.js
//// 一堆被注釋掉的代碼
function component() {
var element = document.createElement('div');
element.innerHTML = 'hello webpack'
return element;
}
document.body.appendChild(component());
// 這段代碼是我們是從我們的index.js copy的。
可以看到吸耿,對(duì)于我們自己寫的函數(shù)祠锣,webpack
會(huì)原封不動(dòng)的copy過來。
配置文件
我們之前使用的webpack src/index.js dist/bundle.js
其實(shí)可以使用一個(gè)配置文件來表述咽安,比在終端中敲命令更加方便伴网。
創(chuàng)建文件 webpack.config.js
此時(shí):
node_modules
src
index.js
index.html
package.json
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
說明:
- 其中,
require
是node.js內(nèi)置函數(shù)表示引入模塊,path
是node.js內(nèi)置模塊。 - entry是入口文件妆棒,就是我們的
index.js
澡腾。 - outpath表示輸出目錄及文件名。
為了便于觀察糕珊,我們刪掉之前生成的dist目錄及其文件
动分。
我們執(zhí)行命令:
webpack --config webpack.config.js
Hash: 629328b9dd2012d414f7
Version: webpack 3.10.0
Time: 59ms
Asset Size Chunks Chunk Names
bundle.js 2.64 kB 0 [emitted] main
[0] ./src/index.js 170 bytes {0} [built]
此時(shí)目錄結(jié)構(gòu):
webpack-demo
dist
bundle.js
node_modules
src
index.js
index.html
package.json
在瀏覽器中查看index.html
,依然可以看到hello webpack
红选。
需要注意的是配置文件命名不一定是webpack.config.js
澜公,可以自由命名,如果為webpack.config.js
喇肋,在使用命令時(shí)坟乾,可以省略--config
。
如果覺得輸入webpack
比較麻煩或陌生蝶防,可以這樣來使用:
在package.json
中加入如下代碼:
{
"scripts":{
"build":"webpack"
}
}
以后我們?cè)诖虬鼤r(shí)甚侣,可以直接使用:
cnpm run build
以上是用webpack實(shí)現(xiàn)的最基本的構(gòu)建過程。
可以看到间学,我們的index.html
是我們自己創(chuàng)建的殷费,如果我們配置了多個(gè)入口文件或者修改了出口文件印荔,自己再來修改index.html
是很麻煩的,我們使用一個(gè)插件:
cnpm install --save-dev html-webpack-plugin
plugins:[
new HtmlWebpackPlugin({
title:'webpack-demo'
})
]
我們刪除根目錄下我們自己手寫的index.html
宗兼。
rm index.html
cnpm run build
dist
bundle.js
index.html
cat index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>webpack-demo</title>
</head>
<body>
<script type="text/javascript" src="bundle.js"></script></body>
</html>
我們發(fā)現(xiàn)躏鱼,我們剛才安裝的這個(gè)插件,已經(jīng)幫我們書寫好了index.html
殷绍。
且引入了打包產(chǎn)生的js文件染苛。這是非常方便的。
管理資源
除了javascript
主到,還可以通過loader
引入其他類型的文件茶行,如css
.
加載CSS
我們安裝style-loader
cnpm install --save-dev style-loader css-loader
修改webpack.config.js
:
module:{
rules:[
{
test:/\.csss$/,
use:[
'style-loader',
'css-loader'
]
}
]
}
要嚴(yán)格按照如上寫法,避免遇到問題登钥。
通過瀏覽器預(yù)覽畔师,我們發(fā)現(xiàn)hello webpack
變成了紅色。
加載圖片
cnpm install --save-dev file-loader
修改webpack.config.js
:
{
test: /\.(png|svg|jpg|gif)$/,
use :[
'file-loader'
]
}
放入一張圖片icon.png
到src
中牧牢。
修改index.js
:
import MyImg from './icon.png';
var img = new Image();
img.src = MyImg;
element.appendChild(img);
我們通過build
看锉,發(fā)現(xiàn)此時(shí)我們的頁面上顯示了剛才添加的圖片,這張圖片被放在了dist
中塔鳍。
管理輸出
因?yàn)榇a改的比較頻繁伯铣,我們的dist目錄中的文件會(huì)越來越多,有的文件可能不再需要轮纫,所以腔寡,在每次構(gòu)建前清理dist
目錄,是比較好的做法掌唾,因?yàn)橹粫?huì)生成用到的文件放前。
cnpm install clean-webpack-plugin --save-dev
修改webpack.config.js
:
const CleanWebpackPlugin = require('clean-webpack-plugin');
plugins:[
new CleanWebpackPlugin(['dist'])
]
此時(shí),執(zhí)行build
后糯彬,dist
中的文件就不會(huì)再有不需要的文件了凭语。
開發(fā)
現(xiàn)在我們有一個(gè)痛點(diǎn),每次修改代碼后撩扒,要手動(dòng)重新webpack,才能查看改動(dòng)后的情況
叽粹,其實(shí)webpack給我們提供了多個(gè)方案,讓我們?cè)诖a發(fā)生變化后自動(dòng)編譯代碼:
- webpack watch mode
- webpack dev server
- webpack dev middleware
需要指出的是却舀,這三種方案都比較常用,特別是在一些項(xiàng)目的腳手架中锤灿,都高頻使用這些項(xiàng)目挽拔,比如vue-cli
。
觀察者模式
修改package.json
:
{
scripts:{
"watch":"webpack --watch"
}
}
此時(shí)但校,我們?cè)诮K端中輸入:
`cnpm run watch`
> webpack-demo@1.0.0 watch /Users/liuhao/Desktop/webpack-demo
> webpack --watch
clean-webpack-plugin: /Users/liuhao/Desktop/webpack-demo/dist has been removed.
Webpack is watching the files…
Hash: a6eb44b735ce8b5f1f68
Version: webpack 3.10.0
Time: 689ms
Asset Size Chunks Chunk Names
22f56d054f6abc3b0683e95a6a3f5150.png 95.6 kB [emitted]
bundle.js 20.3 kB 0 [emitted] main
index.html 183 bytes [emitted]
[0] ./src/icon.png 82 bytes {0} [built]
[1] ./src/index.js 333 bytes {0} [built]
[2] ./src/style.css 1.04 kB {0} [built]
[3] ./node_modules/.0.28.9@css-loader!./src/style.css 330 bytes {0} [built]
+ 4 hidden modules
Child html-webpack-plugin for "index.html":
1 asset
[2] (webpack)/buildin/global.js 509 bytes {0} [built]
[3] (webpack)/buildin/module.js 517 bytes {0} [built]
+ 2 hidden modules
Hash: 0eb719c26b33a7a1afe0
Version: webpack 3.10.0
Time: 28ms
Asset Size Chunks Chunk Names
bundle.js 20.3 kB 0 [emitted] main
index.html 183 bytes [emitted]
+ 1 hidden asset
[1] ./src/index.js 337 bytes {0} [built]
+ 7 hidden modules
Child html-webpack-plugin for "index.html":
1 asset
4 modules
可以看到webpack
watch
模式開啟后螃诅,webpack
進(jìn)程沒有退出,一直在監(jiān)聽程序變動(dòng),我們手動(dòng)改動(dòng)某一個(gè)位置术裸,webpack
又會(huì)自動(dòng)編譯倘是。這種方式的弊端就是,我們要觀察頁面袭艺,還是得手動(dòng)刷新瀏覽器搀崭。
webpack-dev-server
如果說webpack --wacth
只是webpack
自帶的一個(gè)簡單工具,那么webpack-dev-server
就非常有用了猾编。它提供一個(gè)簡單的web服務(wù)器瘤睹,能夠?qū)崟r(shí)重新加載。webpack-dev-server
是webpack
的另外一個(gè)項(xiàng)目答倡,且出自于官方轰传。
cnpm install --save-dev webpack-dev-server
修改webpack.config.js
:
devServer:{
contentBase:'./dist'
}
修改package.json
:
{
scripts:{
"start":"webpack-dev-server --open"
}
}
此時(shí),我們執(zhí)行cnpm start
瘪撇,就會(huì)在8080
端口起來一個(gè)服務(wù)获茬。渲染出html頁面。當(dāng)我們修改代碼后倔既,server會(huì)自動(dòng)編譯恕曲,成功后會(huì)通知瀏覽器自動(dòng)刷新,此時(shí)我們不要受到刷新瀏覽器叉存,即可看到更新后的內(nèi)容码俩。
webpack-dev-middleware
與webpack-dev-server
一樣,webpack-dev-middleware
也是由webpack
官方進(jìn)行維護(hù)的歼捏,但是能進(jìn)行更多的自定義設(shè)置稿存。
安裝express
和 webpack-dev-middleware
其中,express
是node.js
中優(yōu)秀的web項(xiàng)目。
cnpm install --save-dev express webpack-dev-middleware
修改 webpack.config.js
:
output: {
publicPath:'/'
}
創(chuàng)建server.js
:
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);
// Tell express to use the webpack-dev-middleware and use the webpack.config.js
// configuration file as a base.
app.use(webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath
}));
// Serve the files on port 3000.
app.listen(3000, function () {
console.log('Example app listening on port 3000!\n');
});
node.js server會(huì)啟動(dòng)在3000端口瞳秽。
我們添加一項(xiàng)script來快速啟動(dòng)server.js
.
{
“scripts”:{
"server":"node server.js"
}
}
了解node.js
的同學(xué)都知道node
命令用來干啥瓣履,不在贅述。
現(xiàn)在我們執(zhí)行:
cnpm run server
此時(shí)也實(shí)現(xiàn)了自動(dòng)編譯练俐,如果還希望同步到瀏覽器袖迎,還需要使用另外一個(gè)項(xiàng)目,webpack-hot-middleware
腺晾。
以上燕锥,我們可以知道,webpack-dev-server
是使用起來最方便的悯蝉。
這些內(nèi)容归形,可以幫助我們?cè)陂_發(fā)中,做到心中有數(shù)鼻由,后面我將結(jié)合es6+vue.js+webpack
來演示單頁應(yīng)用的開發(fā)暇榴。