非常感謝胖哥的博客和掘金小冊的技術(shù)分享,希望大家去下面的鏈接去查看原文启具,他們寫的非常好本讥,都是多個項目經(jīng)驗的總結(jié)!B撤搿拷沸!感謝
本篇文章是?技術(shù)胖?博客學(xué)習(xí)筆記整理,供后續(xù)查閱使用
在如今大前端的時代薯演,webpack可以說是肩負重任撞芍,在項目中不可或缺;练隆(嚴肅臉)
學(xué)習(xí)webpack您需要的設(shè)備:
1米罚、電腦(能上網(wǎng))
2碗降、編輯器
3、一杯星巴克
什么是webpack:
webpack可以看做是模塊打包機,它做的事情是,分析你的項目結(jié)構(gòu),找到j(luò)s模塊以及其他的一些瀏覽器不能運行的拓展語言(sass、less、typescript)邑蒋,并將其轉(zhuǎn)換和打包為合適的格式供瀏覽器使用卿堂。在3.0出現(xiàn)后策严,webpack還肩負起了優(yōu)化項目的責(zé)任
從上面這段話中抽取出來三個重點:
1倔韭、打包:可以把JavaScript文件打包成一個文件硕蛹,減少服務(wù)器壓力和下載帶寬
2、轉(zhuǎn)換:把拓展語言轉(zhuǎn)換成普通的JavaScript,讓瀏覽器順利運行
3、優(yōu)化:前端變得越來越復(fù)雜后,性能也會遇到問題,而webpack也開始肩負起了優(yōu)化和提升性能的責(zé)任
我們可以通過下圖了解webpack的作用
安裝webpack
默認你的電腦已經(jīng)裝過了node(不會的该互,出門右拐找google)
新建一個webpack學(xué)習(xí)目錄 webpackpro
安裝命令區(qū)別:
? ? 1、npm i webpack -g? ? ? ? ? ? ? ? ? ? 全局安裝
? ? 2、npm i webpack --save? ? ? ? ? ? 保存安裝包信息到package.json中
? ? 3蜒车、 npm i webpack --save-dev? ?在開發(fā)環(huán)境中使用這個包 development
? ? 4嬉挡、npm i webpack -D? ? ? ? ? ? ? ? ? ? 是第三個命令的縮寫
注意基括!注意!注意!:::這個教程里用的是3.0版本媳维,但是最新版是4.0侥啤,不要裝錯了
使用? npm i webpack@3.11.0 -D? 命令安裝3.11.0版本
文章最后會有怎么安裝模塊特殊版本的說明
開發(fā)環(huán)境和生產(chǎn)環(huán)境
開發(fā)環(huán)境:在開發(fā)時需要的環(huán)境醉箕,這里指在開發(fā)時需要依賴的包
生產(chǎn)環(huán)境:程序開發(fā)完成,開始運行后的環(huán)境,這里指要使項目運行所需要的依賴包
如果安裝失敗(出現(xiàn)了報錯信息)笆焰,一般有三種可能:
1未檩、node版本過低,升級版本
2、網(wǎng)絡(luò)問題,用cnpm(淘寶的npm實時更新鏡像)
3、權(quán)限問題遗增,在Liux和Mac上是需要安裝權(quán)限的,如果是win系統(tǒng),使用管理員方式安裝
全局安裝時可以的铣除,但是webpack官方不推薦,這回將你項目中的webpack鎖定到指定版本辑鲤,并且在使用不同的webpack版本的項目中,可能會導(dǎo)致構(gòu)建失敗
初始化項目
npm init
一路回車到底
npm i webpack --save-dev
查看webpack版本哆窿,也是檢查webpack是否安裝好的一種方法
webpack -v
建立項目結(jié)構(gòu)
在webpackpro目錄下,新建src和dist文件夾硼瓣,在src下新建entry.js作為入口文件,在dist文件下新建一個index.html文件(暫時的镜沽,以后會自動生成),寫入以下內(nèi)容
此時的項目目錄應(yīng)為
? ?此時在webpackpro目錄下運行命令
webpack src/entry.js dist/bundle.js
? ?再來看下項目目錄,自動生成了bundle.js文件
? ?這時可以在瀏覽器中查看index.html的運行效果
配置文件:入口和出口
配置文件? webpack.config.js
webpack.config.js就是webpack的配置文件呻待,需要自己在項目根目錄下創(chuàng)建
entry
多入口、多出口的配置
很簡單瑞妇,只需要多加個入口entry、把出口改成活的即可
服務(wù)和熱更新
安裝webpack-dev-server
npm i?webpack-dev-server -D
webpack-dev-server主要提供兩個功能
1、偽靜態(tài)文件提供服務(wù)
2形娇、自動刷新和熱替換(HMR)
配置devServer
contnetBase:配置服務(wù)器基本運行路徑屡立,用于找到程序打包地址
host:服務(wù)運行地址檩坚,建議使用本機IP挨措,這里為了方便,所以用localhsot
compress:服務(wù)器端壓縮選型嫡霞,一般設(shè)置為開啟
port:服務(wù)運行端口寄锐,不建議使用80您宪,很容易被占用
最后在package.json中配置啟動命令
"server": "webpack-dev-server"
這里東西比較多怠晴,打算新開一個webpack-dev-server文章講解
css文件打包
簡單介紹loaders
loaders是webpack最重要的功能之一,通過不同的loader對不同格式的文件進行特定的處理
配置項:
test:用于匹配處理文件的擴展名的表達式锣笨,這個選項是必須進行配置的
use:loader名稱判哥,就是你要使用的模塊名稱,這個選項也必須進行配置窍箍,否則報錯
include/exclude:手動添加必須處理的文件(文件夾)或屏蔽不需要處理的文件(可選)
query:為loaders提供額外的設(shè)置選項(可選)
安裝loader
在src文件夾下建立css/index.css,并輸入以下內(nèi)容
body{????background-color: red;????color: white;}
在entry.js中引入
import css from './css/index.css';
打包css要用到兩個loader:
style-loader:處理css文件中的url()
css-loader:將css插入到頁面的style標(biāo)簽
npm i style-loader css-loader -D
loaders配置
這三種寫法效果是相同的
壓縮js代碼
uglifyjs-webpack-plugin是js壓縮插件碍脏,在webpack中默認已經(jīng)集成,不需要安裝
引入
const uglify = require('uglifyjs-webpack-plugin');
在plugins配置里new一個uglify對象就可以了:
此時在頁面中查看js文件就是壓縮過的
html文件的發(fā)布
文件結(jié)構(gòu)的變更說明:把dist下的index.html文件移動到src下门驾,并刪除引入的js文件
安裝html-webpack-plugin插件
npm i?html-webpack-plugin -D
在webpack.config.js中引入
const htmlPlugin= require('html-webpack-plugin');
配置
minify:對html文件進行壓縮房铭,removeAttrubuteQuotes是去掉屬性的雙引號
hash:避免開發(fā)中js有緩存效果
template:要打包的html模板路徑和文件名稱
此時,在命令行中運行webpack后蒂窒,注意目錄結(jié)構(gòu)中自動生成了index.html和bundle.js文件
css中的圖片處理
首先在index.html中添加一個標(biāo)簽比如:
安裝loaders
npm i file-loader url-loader -D
file-loader:解決引用路徑的問題劫乱,拿background樣式用url引入背景圖來說蔚润,我們都知道,webpack最終會將各個模塊打包成一個文件,因此我們樣式中的url路徑是相對入口html頁面的猾担,而不是相對于原始css文件所在的路徑的趁冈。這就會導(dǎo)致圖片引入失敗旺坠。這個問題是用file-loader解決的璧疗,file-loader可以解析項目中的url引入(不僅限于css)淌喻,根據(jù)我們的配置,將圖片拷貝到相應(yīng)的路徑,再根據(jù)我們的配置配深,修改打包后文件引用路徑,使之指向正確的文件嫁盲。
url-loader:如果圖片較多篓叶,會發(fā)很多http請求,會降低頁面性能羞秤。這個問題可以通過url-loader解決缸托。url-loader會將引入的圖片編碼,生成dataURl瘾蛋。相當(dāng)于把圖片數(shù)據(jù)翻譯成一串字符俐镐。再把這串字符打包到文件中,最終只需要引入這個文件就能訪問圖片了哺哼。當(dāng)然佩抹,如果圖片較大,編碼會消耗性能取董。因此url-loader提供了一個limit參數(shù)棍苹,小于limit字節(jié)的文件會被轉(zhuǎn)為DataURl,大于limit的還會使用file-loader進行copy茵汰。
在配置文件中引入
limit:是把小于500000B的文件達成base64的格式枢里,寫入js
css分離與圖片路徑處理
這里課程兩個目的:
1、把css從JavaScript中分離出來
2、處理分離出來的css中圖片路徑不對問題
css分離:extract-text-webpack-plugin
安裝 extract-text-webpack-plugin
npm install --save-dev extract-text-webpack-plugin
引入
const extractTextPlugin = require("extract-text-webpack-plugin");
new extractTextPlugin("/css/index.css")
/css/index.css? ?是指分離后的路徑位置
修改loader
處理HTML中的圖片? ?html-withimg-loader
把圖片放到指定的文件夾下
安裝命令
npm i html-withimg-loader -D
配置loader
Less栏豺、Sass文件打包和分離
less:npm i less less-loader -D
sass: npm i sass-loader node-sass -D
和上面的寫法一樣
自動處理css3屬性前綴
通過postcss-loader給css3屬性自動添加前綴
npm i postcss-loader autoprefixer -D
先在項目根目錄下新建postcss.config.js文件彬碱,寫入以下內(nèi)容
編寫loader
消除未使用的css
如果在項目中使用想bootstrap這樣的框架會有很多css是用不上的,或者項目開發(fā)周期久了就會有很多無用的css樣式造成css冗雜
PurifyCSS
使用PurifyCSS可以大大減少css冗雜奥洼,比如我們經(jīng)常使用的bootstrap104kb就可以減少到只有35kb
安裝PurifyCSS-webpack
npm i purifycss-webpack purify-css -D
在webpack.config.js頭部引入purifycss-webpack
const PurifyCSSPlugin = require('purifycss-webpack');
引入glob
因為我們需要同步檢查html模板巷疼,所以我們需要引入node的glob對象使用
在webpack.config.js頭部引入glob
const glob = require('glob');
這里配置了一個paths,主要是找html模板溉卓,purifycss根據(jù)這個配置會遍歷你的文件皮迟,查找哪些css被使用了
注意:使用這個插件必須配合extract-text-webpack-plugin
這時在css/index.css中加入一些多余css樣式,重新運行webpack桑寨,就能看到效果
支持ES6語法
Babel:是一個編譯JavaScript的平臺伏尼,它可以做到
1、使用ES6尉尾、ES7爆阶。。沙咏。新語法辨图,及時這些標(biāo)準(zhǔn)目前并未被當(dāng)前的瀏覽器支持
2、使用基于JavaScript擴展的語言肢藐,比如React的JSX
Babel的安裝和配置
Babel其實是幾個模塊化的包井辜,其核心功能位于稱為babel-core的npm包中踩官,webpack可以把其不同的包整合在一起使用棱烂,對于每一個你需要的功能或拓展占遥,你都需要安裝單獨的包(用得最多的是解析ES6的babel-preset-es2015包和解析JSX的babel-preset-react包)
安裝loader
cnpm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
配置babel
.babelrc配置
雖然Babel可以直接在webpack.config.js中進行配置,但是考慮到babel具有非常多的配置選項痘煤,如果寫在webpack.config.js中不易閱讀凑阶,所以單獨寫在.babelrc文件中
{????"presets":["react","es2015"]? }
webpack.config.js里loader的配置
ENV
現(xiàn)在比較流行配置env
安裝env
npm install --save-dev babel-preset-env
修改.babelrc里的配置文件,只要把es2015換成env就可以了
{????"presets":["react","env"]? }
打包后調(diào)試
(這節(jié)都是理論的東西宙橱,直接copy來)
由于打包后html、js蘸拔、css都壓縮了师郑,給調(diào)試帶來了麻煩,webpack支持Source Maps來方便調(diào)試
四種選項
在配置devtool時调窍,webpack給我們提供了四種選項呕乎。
source-map:在一個單獨文件中產(chǎn)生一個完整且功能完全的文件。這個文件具有最好的source map,但是它會減慢打包速度陨晶;
cheap-module-source-map:在一個單獨的文件中產(chǎn)生一個不帶列映射的map,不帶列映射提高了打包速度,但是也使得瀏覽器開發(fā)者工具只能對應(yīng)到具體的行先誉,不能對應(yīng)到具體的列(符號),會對調(diào)試造成不便湿刽。
?eval-source-map:使用eval打包源文件模塊,在同一個文件中生產(chǎn)干凈的完整版的sourcemap褐耳,但是對打包后輸出的JS文件的執(zhí)行具有性能和安全的隱患诈闺。在開發(fā)階段這是一個非常好的選項,在生產(chǎn)階段則一定要不開啟這個選項铃芦。
cheap-module-eval-source-map:這是在打包文件時最快的生產(chǎn)source map的方法雅镊,生產(chǎn)的 Source map 會和打包后的JavaScript文件同行顯示,沒有影射列刃滓,和eval-source-map選項具有相似的缺點仁烹。
四種打包模式,有上到下打包速度越來越快咧虎,不過同時也具有越來越多的負面作用卓缰,較快的打包速度的后果就是對執(zhí)行和調(diào)試有一定的影響。
個人意見是砰诵,如果大型項目可以使用source-map征唬,如果是中小型項目使用eval-source-map就完全可以應(yīng)對,需要強調(diào)說明的是茁彭,source map只適用于開發(fā)階段总寒,上線前記得修改這些調(diào)試設(shè)置。
簡單的配置:
module.exports = {
??devtool: 'eval-source-map',
??entry:??__dirname + "/app/main.js",
??output: {
????path: __dirname + "/public",
????filename: "bundle.js"
??}
}
總結(jié):調(diào)試在開發(fā)中也是必不可少的理肺,但是一定要記得在上線前一定要修改webpack配置摄闸,在打出上線包
下一篇文章總結(jié)胖哥博客里的實戰(zhàn)技巧
安裝模塊特殊版本
npm install --save 模塊名稱(例如react-native-scrollable-tab-view)@版本號(例如0.5.3)
有些模塊不指定版本號會出現(xiàn)一些詭異的bug,比如上述的react-native-scrollable-tab-view,我在安裝時沒指定版本號,默認0.8.0,結(jié)果報錯,改了半天后索性刪除這個模塊,重新指定0.5.3版本的安裝.
另說明:查看package.json中已安裝的庫的時候,會發(fā)現(xiàn)他們的版本號之前都會加一個符號哲嘲,有的是插入符號(^)贪薪,有的是波浪符號(~),那么他們到底有什么區(qū)別呢眠副?
比如
~1.15.2 := ?>=1.15.2 <1.16.0 ? ??
^3.3.4 := >=3.3.4 <4.0.0
波浪符號(~):他會更新到當(dāng)前minor version(也就是中間的那位數(shù)字)中最新的版本画切。放到我們的例子中就是:body-parser:~1.15.2,這個庫會去匹配更新到1.15.x的最新版本囱怕,如果出了一個新的版本為1.16.0霍弹,則不會自動升級。波浪符號是曾經(jīng)npm安裝時候的默認符號娃弓,現(xiàn)在已經(jīng)變?yōu)榱瞬迦敕枴?/p>
插入符號(^):這個符號就顯得非常的靈活了典格,他將會把當(dāng)前庫的版本更新到當(dāng)前major version(也就是第一位數(shù)字)中最新的版本。放到我們的例子中就是:bluebird:^3.3.4台丛,這個庫會去匹配3.x.x中最新的版本耍缴,但是他不會自動更新到4.0.0砾肺。
package.json 版本號說明
1.版本號基本格式
?? 主號.次號.修補號
2.版本號規(guī)則
1)version? 指定版本號
"vue-clipboard2": "0.0.8"http://指定所依賴的該組件必須是 0.0.8 版本的
2)>version 大于該版本號
"vue-clipboard2": ">0.0.8"http://指定所依賴的該組件必須是大于 0.0.8 版本的
3)>=version 大于等于該版本號
"vue-clipboard2": ">=0.0.8"http://指定所依賴的該組件必須是 大于或等于0.0.8 版本的
4)<version小于該版本號
"vue-clipboard2": "<0.0.8"http://指定所依賴的該組件必須是小于 0.0.8 版本的
5)<=version 小于等于該版本號
"vue-clipboard2": "<=0.0.8"http://指定所依賴的該組件必須是小于等于 0.0.8 版本的
6)~version 右側(cè)任意
"vue-clipboard2": "~0.2.1"http://該組件版本號 要>=0.2.1,并修補號為 >=1 的任意值
"vue-clipboard2": "~0.2"http://該組件版本號 要>=0.2防嗡,并修補號為 >=0 的任意值
"vue-clipboard2": "~1"http://該組件版本號 要>=1.0.0变汪,次版本號任意,并修補號任意
7)^version 非0右側(cè)任意? 從左向右蚁趁,第一個非0號的右側(cè)任意
"vue-clipboard2": "^0.1.2"http://該組件版本號 要>=0.1.2 主版本號為0固定裙盾,次版本號為 1 固定,并修補號 >=2 任意值
"vue-clipboard2": "^1.1.2"http://該組件版本號 要>=1.1.2 主版本號為1固定他嫡,次版本號為 >=1任意值番官,并修補號為任意值,但次版本號為1時钢属,修補號要>=2徘熔,即要滿足總版本號>=1.1.2
"vue-clipboard2": "^0.1"http://該組件版本號 要>=0.1 缺少的版本號位位置為任意值
8)x-version x位置任意
"vue-clipboard2": "0.1.x"http://x位置任意
9)“”|| * ?? version 表示版本任意
"vue-clipboard2": ""http://版本任意
"vue-clipboard2": "*"http://版本任意
10)version1-version2 表示版本區(qū)間范圍 包含首尾版本號
"vue-clipboard2": "1.1.1-1.2.9"http://版本要求 1.1.1<=版本號<=1.2.9
11)version1||version2||...version 表示或,或version1或version2署咽,支持多個
"vue-clipboard2": "1.1.1-1.2.9 || >=3.5.0 || ^0.1.2"http://版本要求滿足其一即可