一橄霉、什么是webpack
官方定義:
webpack is a module bundler lets you write any module format(mixed also), compiles then for the browser. And it supports static async bundling.
簡(jiǎn)單的說(shuō)webpack是一個(gè)構(gòu)建工具,什么是構(gòu)建工具呢鹊奖,我們?cè)陂_發(fā)環(huán)境的代碼店展,是為了方便閱讀與開發(fā)养篓,生產(chǎn)環(huán)境的代碼則是為了代碼更好的運(yùn)行。開發(fā)環(huán)境的代碼赂蕴,要進(jìn)行壓縮編譯以后柳弄,才能放在線上執(zhí)行,這樣代碼體積更小概说,加載起來(lái)更快碧注,所以構(gòu)建工具一般有以下幾種作用:
1、代碼壓縮
將JS糖赔、CSS代碼混淆壓縮萍丐,讓代碼體積更小,加載更快
2放典、編譯語(yǔ)法
編寫CSS時(shí)使用Less逝变、Sass,編寫JS時(shí)使用ES6奋构、TypeScript等壳影,這些標(biāo)準(zhǔn)目前都無(wú)法被瀏覽器兼容,因此需要構(gòu)建工具編譯弥臼,例如使用Babel編譯ES6語(yǔ)法宴咧。
3、處理模塊化:
CSS和JS的模塊化語(yǔ)法径缅,目前都無(wú)法被瀏覽器兼容掺栅。因此開發(fā)環(huán)境可以使用既定的模塊化語(yǔ)法箱吕,但是需要構(gòu)建工具將模塊化語(yǔ)法編譯為瀏覽器可識(shí)別形式。例如使用webpack柿冲、Rollup等處理JS模塊化茬高。
二、why webpack
模塊化
之前寫過一篇關(guān)于模塊化的文章假抄,不管是AMD還是CMD怎栽,都是runtime的時(shí)候進(jìn)行的,且瀏覽器的支持性還不是特別好宿饱,需要一個(gè)東西來(lái)進(jìn)行轉(zhuǎn)化熏瞄。
loader
一個(gè)web不止有js,還有css和各種靜態(tài)資源谬以,webpack提供了各種loader來(lái)處理css和less强饮、sass。
轉(zhuǎn)載一個(gè)關(guān)于webpack誕生的故事:
2012年为黎,一個(gè)叫做Tobias的邮丰,在Newberg(美國(guó)一個(gè)城市)讀master的德國(guó)人要寫一片學(xué)位論文。他之前是寫c#的铭乾,從來(lái)沒有寫過一個(gè)web界面剪廉。他在一些特定的場(chǎng)景需要用到Google Web Toolkit中的一個(gè)叫做code splitting的功能。而在他的論文中他需要寫一個(gè)web app炕檩,他就想找一個(gè)包含這個(gè)功能的庫(kù)來(lái)用斗蒋。他找到的這個(gè)庫(kù)叫webmake,這也是一個(gè)bundler笛质。但是卻沒有code splitting這個(gè)功能泉沾,于是他提了一個(gè)issue,并且寫了一堆如何實(shí)現(xiàn)這個(gè)功能的代碼妇押,希望維護(hù)者能夠加入這個(gè)功能跷究。在一番討論過后維護(hù)者拒絕了他,于是在經(jīng)過同意之后舆吮,他把這個(gè)庫(kù)fork到了了過去并自己加上了這個(gè)功能揭朝,給新的庫(kù)取名為webpack。
2014年色冀,Dan Abramov在Stack Overflow上提了一個(gè)關(guān)于hot module replacement的問題潭袱,Tobias用很大的篇幅給他介紹了這個(gè)還在開發(fā)的功能,詳細(xì)解釋了這個(gè)功能怎么在webpack里工作的锋恬,以及這個(gè)功能有多棒屯换,你可以不用刷新瀏覽器了!
2015年,這時(shí)在Instagram工作的Pete Hunt通過一次演講告訴了世界他們是如何使用webpack打包發(fā)布他們的react app的彤悔。然后你懂得嘉抓,webpack就火了。像Facebook這樣的公司也開始使用webpack了晕窑。但是其實(shí)Tobias只是每周大概花5 6個(gè)小時(shí)在webpack中抑片。
是的,在這兩個(gè)討論中杨赤,webpack徹底火了敞斋,走向了世界。
三疾牲、搭建環(huán)境
創(chuàng)建項(xiàng)目
創(chuàng)建一個(gè)項(xiàng)目目錄并生成 package.json植捎。npm 使用它來(lái)管理項(xiàng)目依賴項(xiàng)。以下是基本命令:
mkdir webpack-demo
cd webpack-demo npm init -y
安裝 Webpack
npm install webpack webpack-cli --save-dev
運(yùn)行webpack
在src目錄下新建一個(gè)index.js
console.log(111)
執(zhí)行命令:
webpack
自動(dòng)會(huì)生成一個(gè)dist文件夾阳柔,main.js里面會(huì)生成一個(gè)
console.log(111)
四焰枢、配置 html-webpack-plugin
可以借助html-webpack-plugin來(lái)新建一個(gè)HTML文件在瀏覽器看效果
npm install html-webpack-plugin --save-dev
新建一個(gè)webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
plugins: [
new HtmlWebpackPlugin({
title: 'Webpack demo'
})
]
}
修改index.js
document.write('你好世界!!!')
執(zhí)行命令:webpack,會(huì)看到dist文件下會(huì)多出來(lái)一個(gè)index.html舌剂,在瀏覽器打開index.html就出現(xiàn)熟悉的頁(yè)面了
五济锄、配置webpack-dev-server
WDS 是在內(nèi)存中運(yùn)行的開發(fā)服務(wù)器,這意味著打包內(nèi)容不會(huì)寫入文件而是存儲(chǔ)在內(nèi)存中架诞。這一區(qū)別在調(diào)試代碼和樣式時(shí)非常重要拟淮。
默認(rèn)情況下干茉,WDS 會(huì)在您開發(fā)應(yīng)用程序時(shí)自動(dòng)在瀏覽器中刷新內(nèi)容谴忧,因此您無(wú)需親自執(zhí)行此操作。但它也支持高級(jí) Webpack 功能——熱模塊更換(HMR)角虫。
安裝
npm install webpack-dev-server --save-dev
配置
我們需要用npm script來(lái)啟動(dòng)他沾谓,按照npm的約定,我們定義一個(gè)命令戳鹅,在package.json文件里面:
"scripts": {
"start": "webpack-dev-server --mode development",
"build": "webpack --mode production"
},
這肯定是非常眼熟了均驶,我們?cè)谑褂胿ue-cli的時(shí)候一定會(huì)有類似的命令
啟動(dòng)
正常情況下,輸入命令npm start或者npm run start就可以啟動(dòng)項(xiàng)目了
但是一般情況下都會(huì)報(bào)這個(gè)錯(cuò)枫虏,因?yàn)閣ebpack和WDS對(duì)于版本的兼容性要求很高妇穴,這一點(diǎn)也非常的惡心
[圖片上傳失敗...(image-197bda-1610333237812)]
我的解決方案是在package.json文件里面:
"webpack": "^4.17.1",
"webpack-cli": "^3.3.9",
"webpack-dev-server": "^3.8.2"
然后重新npm install,再次啟動(dòng)項(xiàng)目就好了
如果你嘗試修改代碼隶债,你應(yīng)該會(huì)在終端里看到一些輸出信息腾它。瀏覽器也會(huì)根據(jù)變動(dòng)做一些強(qiáng)制更新。
基礎(chǔ)配置 WDS
webpack.config.js
devServer: {
// 僅顯示錯(cuò)誤級(jí)別的輸出,從而減少輸出信息
stats: "errors-only",
// 從環(huán)境變量中傳入 host 和 port,從而達(dá)到可配置
//
// 如果你使用 Docker, Vagrant 或者 Cloud9, 那么把
// host 設(shè)置為 "0.0.0.0";
//
// 0.0.0.0 對(duì)于所有的網(wǎng)絡(luò)設(shè)備都是可用的
// 而默認(rèn)的 `localhost` 不行.
host: process.env.HOST, // 默認(rèn)為 `localhost`
port: process.env.PORT, // 默認(rèn)為 8080
open: true, // 在瀏覽器中打開
},
通過網(wǎng)絡(luò)訪問開發(fā)服務(wù)器
webpack.config.js
host: '0.0.0.0',
package.json
"start": "webpack-dev-server --host 0.0.0.0 --mode development",
此時(shí)啟動(dòng)以后就可以用過本機(jī)IP地址訪問本地服務(wù)了
修改配置文件熱更新
當(dāng)打包文件發(fā)生變化時(shí)死讹,開發(fā)服務(wù)器會(huì)自動(dòng)重啟瞒滴;但是,當(dāng) Webpack 配置變化了呢?如果說(shuō)妓忍,每次配置變動(dòng)你就要手動(dòng)重啟開發(fā)服務(wù)器虏两,沒過一會(huì)兒,你就會(huì)厭煩不堪了世剖。如 GitHub 中所討論的那樣定罢,我們可以使用 nodemon 監(jiān)視工具自動(dòng)執(zhí)行該過程。
安裝nodemon
npm install nodemon --save-dev
package.json
"start": "nodemon --watch webpack.config.js --host 0.0.0.0 --exec \"webpack-dev-server --mode development\"",
輪詢而不是監(jiān)測(cè)文件
這個(gè)選項(xiàng)適合有時(shí)候熱更新不管用了旁瘫,可以試一下這個(gè)選項(xiàng)引颈,基本都能解決
devServer: {
watchOptions: {
// 首次更改后延遲多少時(shí)間再重新構(gòu)建
aggregateTimeout: 300,
// 輪詢的時(shí)間間隔 (單位 ms, 接受 Boolean 類型的值)
poll: 1000,
},
},
六、Webpack Dev Middleware
webpack-dev-middleware是一個(gè)包裝程序境蜕,它將通過webpack處理的文件發(fā)送到服務(wù)器蝙场。它在webpack-dev-server內(nèi)部使用,但是如果需要粱年,它可以作為單獨(dú)的軟件包使用售滤,以允許進(jìn)行更多自定義設(shè)置。我們將看一個(gè)webpack-dev-middleware與Express服務(wù)器結(jié)合的示例台诗。
安裝
npm install --save-dev express webpack-dev-middleware
webpack.config.js的output新增一個(gè)輸出地址
module.exports = {
devServer: {
// 僅顯示錯(cuò)誤級(jí)別的輸出,從而減少輸出信息
stats: "errors-only",
// 從環(huán)境變量中傳入 host 和 port,從而達(dá)到可配置
//
// 如果你使用 Docker, Vagrant 或者 Cloud9, 那么把
// host 設(shè)置為 "0.0.0.0";
//
// 0.0.0.0 對(duì)于所有的網(wǎng)絡(luò)設(shè)備都是可用的
// 而默認(rèn)的 `localhost` 不行.
host: '0.0.0.0', // 默認(rèn)為 `localhost`
port: process.env.PORT, // 默認(rèn)為 8080
useLocalIp: true,
open: false, // 在瀏覽器中打開
watchOptions: {
// 首次更改后延遲多少時(shí)間再重新構(gòu)建
aggregateTimeout: 300,
// 輪詢的時(shí)間間隔 (單位 ms, 接受 Boolean 類型的值)
poll: 1000,
},
},
output: {
publicPath: '/',
},
plugins: [
new HtmlWebpackPlugin({
title: 'Webpack demo'
})
]
}
新建一個(gè)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');
});
package.json加一個(gè)命令
"scripts": {
"start": "nodemon --watch webpack.config.js --host 0.0.0.0 --exec \"webpack-dev-server --mode development\"",
"build": "webpack --mode production",
"server": "node server.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
運(yùn)行
npm run server
在localhost:3000就可以看到輸出的服務(wù)了
記在最后
webpack內(nèi)容非常多完箩,接下來(lái)還會(huì)繼續(xù)記錄loader和分包加載以及各種插件