版權(quán)聲明:本文為博主原創(chuàng)文章摩渺,未經(jīng)博主允許不得轉(zhuǎn)載简烤。
webpack介紹和使用
一、webpack介紹
1摇幻、由來
由于前端之前js横侦、css挥萌、圖片文件需要單獨(dú)進(jìn)行壓縮和打包,這樣團(tuán)隊(duì)人員處理很繁瑣枉侧,然后 Instagram 團(tuán)隊(duì)就想讓這些工作自動(dòng)化引瀑,然后webpack應(yīng)運(yùn)而生。
2榨馁、介紹
webpack是一個(gè)模塊打包器(module bundler)憨栽,webpack視HTML,JS翼虫,CSS屑柔,圖片等文件都是一種 資源 ,每個(gè)資源文件都是一個(gè)模塊(module)文件珍剑,webpack就是根據(jù)每個(gè)模塊文件之間的依賴關(guān)系將所有的模塊打包(bundle)起來掸宛。
3、作用
- 對(duì) CommonJS 招拙、 AMD 唧瘾、ES6的語法做了兼容
- 對(duì)js、css迫像、圖片等資源文件都支持打包(適合團(tuán)隊(duì)化開發(fā))
- 比方你寫一個(gè)js文件劈愚,另外一個(gè)人也寫一個(gè)js文件,需要合并很麻煩闻妓,現(xiàn)在交給webpack合并很簡單
- 有獨(dú)立的配置文件webpack.config.js
- 可以將代碼切割成不同的chunk菌羽,實(shí)現(xiàn)按需加載,降低了初始化時(shí)間
- 具有強(qiáng)大的Plugin(插件)接口由缆,大多是內(nèi)部插件注祖,使用起來比較靈活
- ……
4、拓展說明
CommonJS均唉、AMD是晨、CMD是用于JavaScript模塊管理的三大規(guī)范,CommonJS定義的是模塊的同步加載舔箭,是一個(gè)更偏向于服務(wù)器端的規(guī)范(也可以在瀏覽器中使用)罩缴,主要用于Nodejs,根據(jù)CommonJS規(guī)范层扶,一個(gè)單獨(dú)的文件就是一個(gè)模塊箫章,加載模塊使用
require()
方法,該方法讀取一個(gè)文件并執(zhí)行镜会,最后返回文件內(nèi)部的exports對(duì)象檬寂。-
AMD和CMD則是定義模塊異步加載適用于瀏覽器端,都是為了 JavaScript 的模塊化開發(fā)戳表,(這里說一下為什要有異步加載桶至,因?yàn)闉g覽器如果使用common.js同步加載模塊的話昼伴,就會(huì)導(dǎo)致性能等問題,所以針對(duì)這個(gè)問題镣屹,又出了一個(gè)規(guī)范圃郊,這個(gè)規(guī)范可以實(shí)現(xiàn)異步加載依賴模塊)
AMD規(guī)范會(huì)提前加載依賴模塊,AMD規(guī)范是通過requireJs 在推廣過程中對(duì)模塊定義的規(guī)范化產(chǎn)出野瘦。(AMD 規(guī)范:https://github.com/amdjs/amdjs-api/wiki/AMD)
-
CMD規(guī)范會(huì)延遲加載依賴模塊描沟, CMD 規(guī)范是 SeaJs 在推廣過程中對(duì)模塊定義的規(guī)范化產(chǎn)出。
(CMD規(guī)范:https://github.com/seajs/seajs/issues/242)
-
AMD規(guī)范和CMD規(guī)范的區(qū)別
- 對(duì)于依賴的模塊鞭光,AMD 是提前執(zhí)行吏廉,CMD 是延遲執(zhí)行。不過 RequireJS 從 2.0 開始惰许,也改成可以延遲執(zhí)行(根據(jù)寫法不同席覆,處理方式不同)
- CMD 推崇依賴就近,AMD 推崇依賴前置
- AMD 的 API 默認(rèn)是一個(gè)當(dāng)多個(gè)用汹买,CMD 的 API 嚴(yán)格區(qū)分佩伤,推崇職責(zé)單一。比如 AMD 里晦毙,require 分全局 require 和局部 require生巡,都叫 require。CMD 里见妒,沒有全局 require孤荣,而是根據(jù)模塊系統(tǒng)的完備性,提供 seajs.use 來實(shí)現(xiàn)模塊系統(tǒng)的加載啟動(dòng)须揣。CMD 里盐股,每個(gè) API 都簡單純粹
-
webpack和gulp的區(qū)別
- gulp是前端自動(dòng)化構(gòu)建工具,強(qiáng)調(diào)的是前端開發(fā)的工作流程耻卡,我們可以通過配置一系列的task疯汁,定義task處理的事情(代碼壓縮、合并卵酪、編譯幌蚊、瀏覽器實(shí)時(shí)更新等),然后定義執(zhí)行順序溃卡,來讓gulp執(zhí)行這些task溢豆,從而構(gòu)建項(xiàng)目的整個(gè)前端開發(fā)流程,自動(dòng)化構(gòu)建工具并不能把所有模塊打包到一起塑煎,也不能構(gòu)建不同模塊之間的依賴關(guān)系沫换。
- webpack是 JavaScript 應(yīng)用程序的模塊打包器臭蚁,強(qiáng)調(diào)的是一個(gè)前端模塊化方案最铁,更側(cè)重模塊打包讯赏,我們可以把開發(fā)中的所有資源(圖片、js文件冷尉、css文件等)都看成模塊漱挎,通過loader(加載器)和plugins(插件)對(duì)資源進(jìn)行處理,打包成符合生產(chǎn)環(huán)境部署的前端資源雀哨。
5磕谅、webpack整體認(rèn)知
? (1)、webpack的核心概念分為 入口(Entry)雾棺、加載器(Loader)膊夹、插件(Plugins)、出口(Output);
?入口(Entry):入口起點(diǎn)告訴 webpack 從哪里開始捌浩,并根據(jù)依賴關(guān)系圖確定需要打包的文件內(nèi)容
-
加載器(Loader):webpack 將所有的資源(css, js, image 等)都看做模塊放刨,但是 webpack 能處理的只是 JavaScript,因此尸饺,需要存在一個(gè)能將其他資源轉(zhuǎn)換為模塊进统,讓 webpack 能將其加入依賴樹中的東西,它就是 loader浪听。loader用于對(duì)模塊的源代碼進(jìn)行轉(zhuǎn)換螟碎。loader 可以使你在 import 或"加載"模塊時(shí)預(yù)處理文件。因此迹栓,loader 類似于其他構(gòu)建工具中“任務(wù)(task)”掉分,并提供了處理前端構(gòu)建步驟的強(qiáng)大方法。
rules: [ { test: /\.(js|jsx)$/, use: 'babel-loader' } ]
-
插件(Plugins):loader 只能針對(duì)某種特定類型的文件進(jìn)行處理迈螟,而 plugin 的功能則更為強(qiáng)大叉抡。在 plugin 中能夠介入到整個(gè) webpack 編譯的生命周期,Plugins用于解決 loader 無法實(shí)現(xiàn)的其他事情答毫,也就是說loader是預(yù)處理文件褥民,那plugin 就是后處理文件。
對(duì)loader打包后的模塊文件(bundle.js)進(jìn)行二次優(yōu)化處理洗搂,例如:代碼壓縮從而減小文件體積
提供輔助開發(fā)的作用:例如:熱更新(瀏覽器實(shí)時(shí)顯示)
plugins: [ new webpack.optimize.UglifyJsPlugin(), new HtmlWebpackPlugin({template: './src/index.html'}) ]
二消返、webpack安裝
1、安裝node
使用 node -v
命令檢查版本
2耘拇、安裝cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
使用 cnpm -v
命令檢查版本
3撵颊、安裝nrm的兩種方法
https://www.npmjs.com/package/nrm
nrm
可以幫助我們切換不同的NPM源的快捷開關(guān),可以切換的NPM源包括:npm
惫叛,cnpm
倡勇,taobao
, rednpm
嘉涌, npmMirror
妻熊, edunpm
第一種方法(由于是外網(wǎng)訪問進(jìn)行安裝夸浅,可能會(huì)被墻) npm install -g nrm
-
第二種方法(國內(nèi)的淘寶鏡像,訪問穩(wěn)定扔役,推薦) cnpm install -g nrm
使用
nrm - V
命令檢查版本(注意這里的 V 是大寫的)- 使用
nrm ls
命令可以查看當(dāng)前可以可以切換的 NPM源 - 使用
npm use cnpm
命令 指定要使用的哪種NPM源
- 使用
4帆喇、安裝webpack
-
全局安裝
npm install --global webpack
-
在項(xiàng)目中安裝最新版本或特定版本,分別執(zhí)行以下命令:
npm install --save-dev webpack npm install --save-dev webpack@<version>
三亿胸、webpack配置
0坯钦、搭建項(xiàng)目結(jié)構(gòu)
webpack(項(xiàng)目總目錄)
dist
-
src
-
js
-
moudle1.js
function sum(x,y){ return x + y; } // 導(dǎo)出 sum 函數(shù) module.exports = sum;
-
main.js
// 1、獲取index.html中的dom對(duì)象 var first = document.getElementById('first'); var btn = document.getElementById('btn'); var two = document.getElementById('two'); var res = document.getElementById('res'); btn.onclick = function(){ var firstValue = parseFloat(first.value); var twoValue = parseFloat(two.value); //2侈玄、獲取 module1.js中的 sum函數(shù) //http://www.ruanyifeng.com/blog/2015/05/require.html var sum = require('./module1.js'); res.value = sum(firstValue,twoValue); }
-
-
-
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <input type="text" id="first"> <input type="button" id="btn" value="+"> <input type="text" id="two"> <input type="button" id="btn" value="="> <input type="text" id="res"> <script src="./dist/js/bulid.js"></script> </body> </html>
-
webpack.config.js(手動(dòng)創(chuàng)建)
const path = require('path'); // 首先要引入node.js中path 模塊婉刀,用于處理文件與目錄的路徑 // const 命令聲明一個(gè)只讀的常量,一旦聲明序仙,值不可以改變路星,改變會(huì)報(bào)錯(cuò);只聲明不賦值也會(huì)報(bào)錯(cuò) // 常量存儲(chǔ)的是一個(gè)不可以變化的變量诱桂。 // module.exports = { entry:'./src/./js/main.js', // 指定入口文件 output:{ path: path.resolve(__dirname, './dist/js'), // 指定出口文件的路徑目錄 filename: 'bulid.js' // 制定出口文件的名稱 },
1洋丐、初始化一個(gè)項(xiàng)目(會(huì)創(chuàng)建一個(gè)package.json文件)
npm init
2、在當(dāng)前的項(xiàng)目中安裝Webpack作為依賴包
npm install --save-dev webpack
說明:
--save
:將配置信息保存到package.json中挥等,同時(shí)
--save
:也是項(xiàng)目生產(chǎn)環(huán)境友绝,項(xiàng)目發(fā)布之后還依賴的東西,保存在dependencies例如:如果你用了 jQuery肝劲,由于發(fā)布之后還是依賴
jQuery
迁客,所以是dependencies
--save-dev
:是項(xiàng)目開發(fā)環(huán)境依賴的東西,保存在devDependencies中例如:寫 ES6 代碼辞槐,如果你想編譯成
ES5
發(fā)布那么babel
就是devDependencies
3掷漱、當(dāng)前項(xiàng)目結(jié)構(gòu)
4、實(shí)現(xiàn)CSS打包
npm install css-loader style-loader --save-dev 或者 cnpm install css-loader style-loader --save-dev
-
在src—>css目錄中新建main.css
#first{ border: 1px solid red; }
-
在webpack.config.js中配置相關(guān)的loader
const path = require('path'); // 首先要引入node.js中path 模塊榄檬,用于處理文件與目錄的路徑 // const 命令聲明一個(gè)只讀的常量卜范,一旦聲明,值不可以改變鹿榜,改變會(huì)報(bào)錯(cuò)海雪;只聲明不賦值也會(huì)報(bào)錯(cuò) // 常量存儲(chǔ)的是一個(gè)不可以變化的變量。 // module.exports = { entry:'./src/./js/main.js', // 指定入口文件 output:{ path: path.resolve(__dirname, './dist/js'), // 指定出口文件的路徑目錄 filename: 'bulid.js' // 制定出口文件的名稱 }, module:{ rules:[ // 在webpack2中舱殿,loaders 被替換成了 rules 其實(shí)就是loader的規(guī)則 { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] // test 說明了當(dāng)前 loader 能處理那些類型的文件 // use 則指定了 loader 的類型奥裸。 // 注意:數(shù)組中的loader不能省略擴(kuò)展名 } ] } }
-
在main.js中獲取css目錄中的main.css文件
// 1、獲取index.html中的dom對(duì)象 var first = document.getElementById('first'); var btn = document.getElementById('btn'); var two = document.getElementById('two'); var res = document.getElementById('res'); btn.onclick = function(){ var firstValue = parseFloat(first.value); var twoValue = parseFloat(two.value); //2沪袭、獲取 module1.js中的 sum函數(shù) //http://www.ruanyifeng.com/blog/2015/05/require.html var sum = require('./module1.js'); res.value = sum(firstValue,twoValue); } // 3湾宙、獲取css目錄中的main.css文件 require('../css/main.css');
- 在終端中輸入
webpack
命令進(jìn)行css文件打包
5、實(shí)現(xiàn)SCSS打包
-
在src目錄中新建 sass目錄--> scss1.scss
// scss1.scss文件 $color:purple; #two{ border:1px solid $color; }
-
安裝對(duì)應(yīng)的loader
npm install sass-loader node-sass webpack --save-dev
或者
cnpm install sass-loader css-loader style-loader node-sass webpack --save-dev
在webpack.config.js中配置相關(guān)的loader
const path = require('path'); // 首先要引入node.js中path 模塊,用于處理文件與目錄的路徑 // const 命令聲明一個(gè)只讀的常量侠鳄,一旦聲明嗡害,值不可以改變,改變會(huì)報(bào)錯(cuò)畦攘;只聲明不賦值也會(huì)報(bào)錯(cuò) // 常量存儲(chǔ)的是一個(gè)不可以變化的變量。 // module.exports = { entry:'./src/./js/main.js', // 指定入口文件 output:{ path: path.resolve(__dirname, './dist/js'), // 指定出口文件的路徑目錄 filename: 'bulid.js' // 制定出口文件的名稱 }, module:{ rules:[ // 在webpack2中十电,loaders 被替換成了 rules 其實(shí)就是loader的規(guī)則 // 實(shí)現(xiàn) css 打包 { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] // test 說明了當(dāng)前 loader 能處理那些類型的文件 // use 則指定了 loader 的類型知押。 // 注意:數(shù)組中的loader不能省略擴(kuò)展名 }, { test: /\.scss$/, // 注意 是sass-loader ,不是 scss-loader use: [ 'style-loader', 'css-loader', 'sass-loader' ] } ] } }
-
在js目錄中 main.js里面引入 scss1.scss
// 1鹃骂、獲取index.html中的dom對(duì)象 var first = document.getElementById('first'); var btn = document.getElementById('btn'); var two = document.getElementById('two'); var res = document.getElementById('res'); btn.onclick = function(){ var firstValue = parseFloat(first.value); var twoValue = parseFloat(two.value); //2台盯、獲取 module1.js中的 sum函數(shù) //http://www.ruanyifeng.com/blog/2015/05/require.html var sum = require('./module1.js'); res.value = sum(firstValue,twoValue); } // 3涡真、獲取css目錄中的main.css文件 require('../css/main.css'); // 4舔痪、獲取sass目錄中的scss1.scss文件 require('../sass/scss1.scss');
在終端中輸入
webpack
命令進(jìn)行scss文件打包
6、實(shí)現(xiàn)Less打包
-
安裝
cnpm install --save-dev
cnpm install less less-loder css-loader style-loader webpack --save-dev
或者
cnpm install less-loader less --save-dev在webpack.config.js中配置相關(guān)的loader
在在src目錄中新建less目錄--> less1.less
@color:blue; #res{ border:1px dashed blue; }
-
在webpack.config.js中配置相關(guān)的loader
const path = require('path'); // 首先要引入node.js中path 模塊予跌,用于處理文件與目錄的路徑 // const 命令聲明一個(gè)只讀的常量寝殴,一旦聲明蒿叠,值不可以改變,改變會(huì)報(bào)錯(cuò)蚣常;只聲明不賦值也會(huì)報(bào)錯(cuò) // 常量存儲(chǔ)的是一個(gè)不可以變化的變量市咽。 // module.exports = { entry:'./src/./js/main.js', // 指定入口文件 output:{ path: path.resolve(__dirname, './dist/js'), // 指定出口文件的路徑目錄 filename: 'bulid.js' // 制定出口文件的名稱 }, module:{ rules:[ // 在webpack2中,loaders 被替換成了 rules 其實(shí)就是loader的規(guī)則 // 實(shí)現(xiàn) css 打包 { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] // test 說明了當(dāng)前 loader 能處理那些類型的文件 // use 則指定了 loader 的類型抵蚊。 // 注意:數(shù)組中的loader不能省略擴(kuò)展名 }, // 實(shí)現(xiàn) scss 打包 { test: /\.scss$/, // 注意 是sass-loader 施绎,不是 scss-loader use: [ 'style-loader', 'css-loader', 'sass-loader' ] }, // 實(shí)現(xiàn) less 打包 { test: /\.less$/, use: [ 'style-loader', 'css-loader', 'less-loader' ] } ] } }
-
在js目錄中 main.js里面引入 less1.less文件
// 5、獲取less目錄中的less1.less文件 require('../less/less1.less');
7贞绳、實(shí)現(xiàn)打包url資源(圖片谷醉、gif、圖標(biāo)等)功能
在src 目錄中 新建imgs目錄冈闭,放入兩張不同大小的圖片
在index.html中新增
<div id="bg1"></div>
<div id="bg2"></div>
-
在mian.css中新增
// mian.css文件 #bg1{ width: 200px; height: 200px; background: url('../imgs/bxg.jpg'); } #bg2{ width: 200px; height: 200px; background: url('../imgs/web.jpg') no-repeat; }
-
前言
如果我們希望在頁面引入圖片(包括img的src和background的url)俱尼。當(dāng)我們基于webpack進(jìn)行開發(fā)時(shí),引入圖片會(huì)遇到一些問題萎攒。
? 其中一個(gè)就是引用路徑的問題号显。拿background樣式用url引入背景圖來說,我們都知道躺酒,webpack最終會(huì)將各個(gè)模塊打包成一個(gè)文件押蚤,因此我們樣式中的url路徑是相對(duì)入口html頁面的,而不是相對(duì)于原始css文件所在的路徑的羹应。這就會(huì)導(dǎo)致圖片引入失敗揽碘。這個(gè)問題是用file-loader解決的,file-loader可以解析項(xiàng)目中的url引入(不僅限于css),根據(jù)我們的配置雳刺,將圖片拷貝到相應(yīng)的路徑劫灶,再根據(jù)我們的配置,修改打包后文件引用路徑掖桦,使之指向正確的文件本昏。
? 另外,如果圖片較多枪汪,會(huì)發(fā)很多http請(qǐng)求涌穆,會(huì)降低頁面性能。這個(gè)問題可以通過url-loader解決雀久。url-loader會(huì)將引入的圖片編碼宿稀,生成dataURl。相當(dāng)于把圖片數(shù)據(jù)翻譯成一串字符赖捌。再把這串字符打包到文件中祝沸,最終只需要引入這個(gè)文件就能訪問圖片了。當(dāng)然越庇,如果圖片較大罩锐,編碼會(huì)消耗性能。因此url-loader提供了一個(gè)limit參數(shù)卤唉,小于limit字節(jié)的文件會(huì)被轉(zhuǎn)為DataURl唯欣,大于limit的還會(huì)使用file-loader進(jìn)行copy。
? url-loader和file-loader是什么關(guān)系呢搬味?簡答地說境氢,url-loader封裝了file-loader。url-loader不依賴于file-loader碰纬,即使用url-loader時(shí)萍聊,只需要安裝url-loader即可,不需要安裝file-loader悦析,因?yàn)閡rl-loader內(nèi)置了file-loader寿桨。通過上面的介紹,我們可以看到强戴,url-loader工作分兩種情況:1.文件大小小于limit參數(shù)亭螟,url-loader將會(huì)把文件轉(zhuǎn)為DataURL;2.文件大小大于limit骑歹,url-loader會(huì)調(diào)用file-loader進(jìn)行處理预烙,參數(shù)也會(huì)直接傳給file-loader。因此我們只需要安裝url-loader即可道媚。
-
安裝
cnpm install
cnpm install url-loader file-loader --save-dev
-
在webpack.config.js中配置相關(guān)的loader
const path = require('path'); // 首先要引入node.js中path 模塊扁掸,用于處理文件與目錄的路徑 // const 命令聲明一個(gè)只讀的常量翘县,一旦聲明,值不可以改變谴分,改變會(huì)報(bào)錯(cuò)锈麸;只聲明不賦值也會(huì)報(bào)錯(cuò) // 常量存儲(chǔ)的是一個(gè)不可以變化的變量。 // module.exports = { entry:'./src/./js/main.js', // 指定入口文件 output:{ path: path.resolve(__dirname, './dist/js'), // 指定出口文件的路徑目錄 filename: 'bulid.js' // 制定出口文件的名稱 publicPath:'dist/' // path:所有輸出文件的目標(biāo)路徑; // publicPath:輸出解析文件的目錄牺蹄,url 相對(duì)于 HTML 頁面 }, module:{ rules:[ // 在webpack2中忘伞,loaders 被替換成了 rules 其實(shí)就是loader的規(guī)則 // 實(shí)現(xiàn) css 打包 { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] // test 說明了當(dāng)前 loader 能處理那些類型的文件 // use 則指定了 loader 的類型。 // 注意:數(shù)組中的loader不能省略擴(kuò)展名 }, // 實(shí)現(xiàn) scss 打包 { test: /\.scss$/, // 注意 是sass-loader 沙兰,不是 scss-loader use: [ 'style-loader', 'css-loader', 'sass-loader' ] }, // 實(shí)現(xiàn) less 打包 { test: /\.less$/, use: [ 'style-loader', 'css-loader', 'less-loader' ] }, // 實(shí)現(xiàn) url 資源打包 { // 圖片和字體文件使用 url-loader 來處理 test: /\.(png|jpg|gif|ttf|eot|woff|woff2|svg)$/, use: [ { loader: 'url-loader', // options 為可以配置的選項(xiàng) options: { limit: 8192 // limit=8192表示將所有小于8kb的圖片都轉(zhuǎn)為base64形式(為什么 呢氓奈?因?yàn)橐粋€(gè)很小的圖片,不值當(dāng)?shù)娜グl(fā)送一個(gè)請(qǐng)求僧凰,減少請(qǐng)求次 數(shù)。) // (其實(shí)應(yīng)該說超過8kb的才使用 url-loader 來映射到文件熟丸,否 則轉(zhuǎn)為dataurl形式) } } ] //保證輸出的圖片名稱與之前命名的圖片名稱保持一致(目前只是支持這樣的寫法训措, webpack3 沒有響應(yīng)的options進(jìn)行配置) // use:'url-loader?limit=8192&name=imgs/[name].[ext]' } ] } }
-
在main.js中引入mui目錄中icons-extra.css的文件
// 5、獲取less目錄中的less1.less文件 require('../less/less1.less'); // 6光羞、獲取src目錄中的mui目錄中icons-extra.css的文件 require('../mui/css/icons-extra.css');
8绩鸣、Webpack-dev-server結(jié)合后端服務(wù)器的熱替換配置
webpack-dev-server
提供了一個(gè)簡單的 web 服務(wù)器,并且能夠?qū)崟r(shí)重新加載(live reloading)纱兑,同時(shí)把生成好的js和html構(gòu)建到我們的電腦內(nèi)存中呀闻,這樣的話,即使我們的目錄中沒有了相關(guān)js等文件潜慎,還能夠加載出來捡多,這樣能夠提高我們頁面運(yùn)行速度。
-
安裝
webpack-dev-server
插件// 先把之前依賴的包安裝 cnpm install
cnpm install webpack-dev-server --save-dev
// webpack.config.js const path = require('path'); // 首先要引入node.js中path 模塊铐炫,用于處理文件與目錄的路徑 // const 命令聲明一個(gè)只讀的常量垒手,一旦聲明,值不可以改變倒信,改變會(huì)報(bào)錯(cuò)科贬;只聲明不賦值也會(huì)報(bào)錯(cuò) // 常量存儲(chǔ)的是一個(gè)不可以變化的變量。 module.exports = { entry:'./src/./js/main.js', // 指定入口文件 output:{ path: path.resolve(__dirname, 'dist/js'), // 指定出口文件的路徑目錄 filename: 'bulid.js' // 制定出口文件的名稱 }, module:{ rules:[ // 在webpack2中鳖悠,loaders 被替換成了 rules 其實(shí)就是loader的規(guī)則 // 實(shí)現(xiàn) css 打包 { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] // test 說明了當(dāng)前 loader 能處理那些類型的文件 // use 則指定了 loader 的類型榜掌。 // 注意:數(shù)組中的loader不能省略擴(kuò)展名 }, // 實(shí)現(xiàn) scss 打包 { test: /\.scss$/, // 注意 是sass-loader ,不是 scss-loader use: [ 'style-loader', 'css-loader', 'sass-loader' ] }, // 實(shí)現(xiàn) less 打包 { test: /\.less$/, use: [ 'style-loader', 'css-loader', 'less-loader' ] }, // 實(shí)現(xiàn) url 資源打包 { // 圖片文件使用 url-loader 來處理 test: /\.(png|jpg|gif|ttf)$/, use: [ { loader: 'url-loader', // options 為可以配置的選項(xiàng) options: { limit: 8192 // limit=8192表示將所有小于8kb的圖片都轉(zhuǎn)為base64形式 // (其實(shí)應(yīng)該說超過8kb的才使用 url-loader 來映射到文件乘综,否則轉(zhuǎn)為data url形式) } } ] } ] }, devServer: { // contentBase: './dist', // 在 localhost:8080(默認(rèn)) 下建立服務(wù)憎账,將 dist 目錄下的文件,作為可訪問文件 contentBase:告訴服務(wù)器從哪里提供內(nèi)容 // 或者通過以下方式配置 contentBase: path.join(__dirname, "dist"), compress: true, // 當(dāng)它被設(shè)置為true的時(shí)候?qū)λ械姆?wù)器資源采用gzip壓縮 // 對(duì)JS卡辰,CSS資源的壓縮率很高鼠哥,可以極大得提高文件傳輸?shù)乃俾适旆疲瑥亩嵘齱eb性能 port: 9000, // 如果想要改端口,可以通過 port更改 hot: true, // 啟用 webpack 的模塊熱替換特性() inline: true, // 實(shí)現(xiàn)實(shí)時(shí)重載(實(shí)現(xiàn)自動(dòng)刷新功能)默認(rèn)情況下是 true朴恳。 host: "localhost" // 如果你希望服務(wù)器外部可訪問抄罕,指定使用一個(gè) host。默認(rèn)是 localhost(也就是你可以不寫這個(gè)host這個(gè)配置屬性)于颖。 } }
// package.json { "name": "mywebpack", "version": "1.0.0", "description": "", "main": "webpack.config.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack-dev-server --open" // "start": "webpack-dev-server --open --port 8080 --hot --inline" // 如果在這里配置了呆贿,就不用在webpack.config.js中配置devServer屬性了。 }, "author": "", "license": "ISC", "devDependencies": { "css-loader": "^0.28.7", "file-loader": "^1.1.5", "html-webpack-plugin": "^2.30.1", "less": "^3.0.0-alpha.3", "less-loader": "^4.0.5", "node-sass": "^4.5.3", "sass-loader": "^6.0.6", "style-loader": "^0.19.0", "url-loader": "^0.6.2", "webpack": "^3.8.1", "webpack-dev-server": "^2.9.3" } } ``` - 在命令行中運(yùn)行 `npm start`森渐,就會(huì)看到瀏覽器自動(dòng)加載頁面做入。如果現(xiàn)在修改和保存任意源文件,web 服務(wù)器就會(huì)自動(dòng)重新加載編譯后的代碼同衣,但是打開后發(fā)現(xiàn)竟块,打開的是 dist目錄,我們想要的是 index.html顯示我們的頁面耐齐,所以這是我們還要借助里另一個(gè) `html-webpack-plugin` 插件浪秘。
html-webpack-plugin
簡單創(chuàng)建 HTML 文件,用于服務(wù)器訪問埠况,其中包括使用script
標(biāo)簽的body中的所有webpack包耸携。-
安裝
html-webpack-plugin
插件cnpm install --save-dev html-webpack-plugin
webpack.config.js配置
const path = require('path'); // 首先要引入node.js中path 模塊,用于處理文件與目錄的路徑 // const 命令聲明一個(gè)只讀的常量辕翰,一旦聲明夺衍,值不可以改變,改變會(huì)報(bào)錯(cuò)喜命;只聲明不賦值也會(huì)報(bào)錯(cuò) // 常量存儲(chǔ)的是一個(gè)不可以變化的變量沟沙。 // 引入html-webpack-plugin 插件 const HtmlWebpackPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); module.exports = { entry: './src/./js/main.js', // 指定入口文件 output: { path: path.resolve(__dirname, 'dist/js'), // 指定出口文件的路徑目錄 filename: 'bulid.js' // 制定出口文件的名稱 }, module: { rules: [ // 在webpack2中,loaders 被替換成了 rules 其實(shí)就是loader的規(guī)則 // 實(shí)現(xiàn) css 打包 { test: /\.css$/, use: ['style-loader', 'css-loader'] // test 說明了當(dāng)前 loader 能處理那些類型的文件 // use 則指定了 loader 的類型壁榕。 // 注意:數(shù)組中的loader不能省略擴(kuò)展名 }, // 實(shí)現(xiàn) scss 打包 { test: /\.scss$/, // 注意 是sass-loader 尝胆,不是 scss-loader use: ['style-loader', 'css-loader', 'sass-loader'] }, // 實(shí)現(xiàn) less 打包 { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }, // 實(shí)現(xiàn) url 資源打包 { // 圖片文件使用 url-loader 來處理 test: /\.(png|jpg|gif|ttf)$/, use: [{ loader: 'url-loader', // options 為可以配置的選項(xiàng) options: { limit: 8192 // limit=8192表示將所有小于8kb的圖片都轉(zhuǎn)為base64形式 // (其實(shí)應(yīng)該說超過8kb的才使用 url-loader 來映射到文件,否則轉(zhuǎn)為data url形式) } }] } ] }, devServer: { // contentBase: './dist', // 在 localhost:8080(默認(rèn)) 下建立服務(wù)护桦,將 dist 目錄下的文件含衔,作為可訪問文件 contentBase:告訴服務(wù)器從哪里提供內(nèi)容 // 或者通過以下方式配置 contentBase: path.join(__dirname, "dist"), port: 9000, // 如果想要改端口,可以通過 port更改 hot: true, // 啟用 webpack 的模塊熱替換特性() inline: true, // 實(shí)現(xiàn)實(shí)時(shí)重載(實(shí)現(xiàn)自動(dòng)刷新功能)默認(rèn)情況下是 true二庵。 host: "localhost" // 如果你希望服務(wù)器外部可訪問贪染,指定使用一個(gè) host。默認(rèn)是 localhost(也就是你可以不寫這個(gè)host這個(gè)配置屬性)催享。 }, plugins: [ new HtmlWebpackPlugin({ title: '首頁', // 用于生成的HTML文檔的標(biāo)題 filename: 'index.html', //寫入HTML的文件杭隙。默認(rèn)為index.html。也可以指定一個(gè)子目錄(例如:)assets/admin.html template: 'index.html' // Webpack需要模板的路徑 }), new webpack.HotModuleReplacementPlugin() // 需要結(jié)合 啟用熱替換模塊(Hot Module Replacement)因妙,也被稱為 HMR ] }
再次使用
npm start
命令就可以實(shí)現(xiàn)瀏覽器自動(dòng)更新痰憎。-
問題來了票髓,HtmlWebpackPlugin中的 title并沒有顯示出來,原因是需要在定義的template模板中使用ejs語法铣耘,
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- EJS 語法 /* EJS是一個(gè)簡單高效的模板語言洽沟,通過數(shù)據(jù)和模板,可以生成HTML標(biāo)記文本蜗细●刹伲可以說EJS是一個(gè)JavaScript庫,EJS可以同時(shí)運(yùn)行在客戶端和服務(wù)器端炉媒,客戶端安裝直接引入文件即可 */ --> <title><%= htmlWebpackPlugin.options.title%></title> </head> <body> <input type="text" id="first"> <input type="button" id="btn" value="+"> <input type="text" id="two"> <input type="button" id="btn" value="="> <input type="text" id="res"> <div id="bg1"></div> <div id="bg2"></div> </body> </html>
再次使用
npm start
命令就可以啦踪区。
9、ES6轉(zhuǎn)換為ES5語法
-
安裝
-
cnpm install --save-dev babel-loader babel-core babel-preset-env
-
babel-core
如果某些代碼需要調(diào)用Babel的API進(jìn)行轉(zhuǎn)碼吊骤,就要使用babel-core
模塊 -
babel-preset-env
通過根據(jù)您的目標(biāo)瀏覽器或運(yùn)行時(shí)環(huán)境自動(dòng)確定您需要的Babel插件
-
-
babel 對(duì)一些公共方法使用了非常小的輔助代碼缎岗,比如
_extend
。 默認(rèn)情況下會(huì)被添加到每一個(gè)需要它的文件中,你可以引入 babel runtime 作為一個(gè)獨(dú)立模塊白粉,來避免重復(fù)引入传泊。- 你必須執(zhí)行
npm install babel-plugin-transform-runtime --save-dev
來把它包含到你的項(xiàng)目中,也要使用npm install babel-runtime --save
把babel-runtime
安裝為一個(gè)依賴
- 你必須執(zhí)行
-
配置
// 實(shí)現(xiàn) url 資源打包
{
// 圖片文件使用 url-loader 來處理
test: /\.(png|jpg|gif|ttf)$/,
use: [{
loader: 'url-loader',
// options 為可以配置的選項(xiàng)
options: {
limit: 8192
// limit=8192表示將所有小于8kb的圖片都轉(zhuǎn)為base64形式
// (其實(shí)應(yīng)該說超過8kb的才使用 url-loader 來映射到文件蜗元,否則轉(zhuǎn)為data url形式)
}
}]
},
// 實(shí)現(xiàn) ES6轉(zhuǎn) ES5
{
test: /\.js$/,
exclude: /(node_modules)/, // exclude 排除的意思或渤,把 node_modules文件夾排除編譯之外
use: {
loader: 'babel-loader',
options: {
// presets 預(yù)設(shè)列表(一組插件)加載和使用
presets: ['env'],
plugins: ['transform-runtime'] // 加載和使用的插件列表
}
}
}
-
把一些代碼改成ES6 語法的寫法
// moudule1.js function sum(x,y){ return x + y; } // 導(dǎo)出 sum 函數(shù) // module.exports = sum; // 改成ES6 的寫法語法 export default{ sum }
- ```js // main.js // 1系冗、獲取index.html中的dom對(duì)象 var first = document.getElementById('first'); var btn1 = document.getElementById('btn1'); var two = document.getElementById('two'); var res = document.getElementById('res'); console.log(1); btn1.onclick = function() { var firstValue = parseFloat(first.value); var twoValue = parseFloat(two.value); //2奕扣、獲取 module1.js中的 sum函數(shù) //http://www.ruanyifeng.com/blog/2015/05/require.html console.log(2); /* var sum = require('./module1.js'); res.value = sum(firstValue,twoValue);*/ res.value = sumObj.sum(firstValue, twoValue); } // 3、獲取css目錄中的main.css文件 // require('../css/main.css'); // 把步驟3 改為 ES6寫法,引入css目錄中的main.css文件 import '../css/main.css'; // 4掌敬、獲取sass目錄中的scss1.scss文件 require('../sass/scss1.scss'); // 5惯豆、獲取less目錄中的less1.less文件 require('../less/less1.less'); // 6、獲取src目錄中的mui目錄中icons-extra.css的文件 require('../mui/css/icons-extra.css'); // 把 var sum = require('./module1.js'); 寫成 ES6語法 import sumObj from './module1.js' ```
10奔害、防止文件緩存(生成帶有20位的hash值的唯一文件)
// webpack.config.js output: { path: path.resolve(__dirname, 'dist/js'), // 指定出口文件的路徑目錄 // filename: 'bulid.js' // 制定出口文件的名稱 filename: '[name].[hash].js' // 將入口文件重命名為帶有20位的hash值的唯一文件 }
11楷兽、抽取CSS為單獨(dú)文件
-
安裝插件從 build.js文件中提取文本(CSS)到單獨(dú)的文件
npm install --save-dev extract-text-webpack-plugin
-
在webpack.config.js中配置
const path = require('path'); // 首先要引入node.js中path 模塊,用于處理文件與目錄的路徑 // const 命令聲明一個(gè)只讀的常量华临,一旦聲明芯杀,值不可以改變,改變會(huì)報(bào)錯(cuò)雅潭;只聲明不賦值也會(huì)報(bào)錯(cuò) // 常量存儲(chǔ)的是一個(gè)不可以變化的變量揭厚。 // 引入html-webpack-plugin 插件 const HtmlWebpackPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); const ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { entry: './src/./js/main.js', // 指定入口文件 output: { path: path.resolve(__dirname, 'dist'), // 指定出口文件的路徑目錄 // filename: 'bulid.js' // 制定出口文件的名稱 // path指定了本地構(gòu)建地址,publicPath指定在瀏覽器中所引用的,指定的是構(gòu)建后在html里的路徑 // publicPath: './', // 將入口文件重命名為帶有20位的hash值的唯一文件 filename: '[name].[hash].js' }, module: { rules: [ // 在webpack2中扶供,loaders 被替換成了 rules 其實(shí)就是loader的規(guī)則 // 實(shí)現(xiàn) css 打包 /*{ test: /\.css$/, use: ['style-loader', 'css-loader'] // test 說明了當(dāng)前 loader 能處理那些類型的文件 // use 則指定了 loader 的類型筛圆。 // 注意:數(shù)組中的loader不能省略擴(kuò)展名 },*/ // 實(shí)現(xiàn) scss 打包 { test: /\.scss$/, // 注意 是sass-loader ,不是 scss-loader use: ['style-loader', 'css-loader', 'sass-loader'] }, // 實(shí)現(xiàn) less 打包 { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }, // 實(shí)現(xiàn) url 資源打包 { // 圖片文件使用 url-loader 來處理 test: /\.(png|jpg|gif|ttf)$/, use: [{ loader: 'url-loader', // options 為可以配置的選項(xiàng) options: { limit: 8192 // limit=8192表示將所有小于8kb的圖片都轉(zhuǎn)為base64形式 // (其實(shí)應(yīng)該說超過8kb的才使用 url-loader 來映射到文件椿浓,否則轉(zhuǎn)為data url形式) } }] //保證輸出的圖片名稱與之前命名的圖片名稱保持一致(目前只是支持這樣的寫法太援, webpack3 沒有響應(yīng)的options進(jìn)行配置) // use:'url-loader?limit=8192&name=imgs/[name].[ext]' }, // 實(shí)現(xiàn) ES6轉(zhuǎn) ES5 { test: /\.js$/, exclude: /(node_modules)/, // exclude 排除的意思闽晦,把 node_modules文件夾排除編譯之外 use: { loader: 'babel-loader', options: { // presets 預(yù)設(shè)列表(一組插件)加載和使用 presets: ['env'], plugins: ['transform-runtime'] // 加載和使用的插件列表 } } }, // 提取 css模塊(如果使用這個(gè)模塊的話,需要把之前的CSS打包模塊注釋掉提岔,不然會(huì)重復(fù)) { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: "css-loader" }) } ] }, devServer: { // contentBase: './dist', // 在 localhost:8080(默認(rèn)) 下建立服務(wù)仙蛉,將 dist 目錄下的文件,作為可訪問文件 contentBase:告訴服務(wù)器從哪里提供內(nèi)容 // 或者通過以下方式配置 contentBase: path.join(__dirname, "dist"), port: 9000, // 如果想要改端口唧垦,可以通過 port更改 hot: true, // 啟用 webpack 的模塊熱替換特性() inline: true, // 實(shí)現(xiàn)實(shí)時(shí)重載(實(shí)現(xiàn)自動(dòng)刷新功能)默認(rèn)情況下是 true捅儒。 host: "localhost" // 如果你希望服務(wù)器外部可訪問,指定使用一個(gè) host振亮。默認(rèn)是 localhost(也就是你可以不寫這個(gè)host這個(gè)配置屬性)巧还。 }, plugins: [ // 從 bundle 中提取文本(CSS)到單獨(dú)的文件 new ExtractTextPlugin({ // 提取css,并重名為帶有 20位的hash值的唯一文件 filename: '[name].[hash].css', // 將所有的獨(dú)立文件模塊(這里指的是css文件)合并成一個(gè)文件 allChunks: true }), new HtmlWebpackPlugin({ title: '首頁', // 用于生成的HTML文檔的標(biāo)題 filename: 'index.html', //寫入HTML的文件坊秸。默認(rèn)為index.html麸祷。也可以指定一個(gè)子目錄(例如:)assets/admin.html template: 'index.html' // Webpack需要模板的路徑 // template: 'index.ejs' // Webpack需要模板的路徑 }), // 需要結(jié)合webpack-dev-server 啟用熱替換模塊(Hot Module Replacement),也被稱為 HMR new webpack.HotModuleReplacementPlugin() ] }
12褒搔、開發(fā)環(huán)境和生產(chǎn)環(huán)境的分離
(1)開發(fā)環(huán)境與生產(chǎn)環(huán)境分離的原因如下:
- 在開發(fā)環(huán)境中阶牍,我們使用熱更新插件幫助我們實(shí)現(xiàn)瀏覽器的自動(dòng)更新功能,我們的代碼沒有進(jìn)行壓縮星瘾,如果壓縮了不方便我們調(diào)試代碼等等走孽,所以以上這些代碼不應(yīng)出現(xiàn)在生產(chǎn)環(huán)境中。
- 生產(chǎn)環(huán)境中琳状,我們把項(xiàng)目部署到服務(wù)器時(shí)磕瓷,我們會(huì)對(duì)代碼進(jìn)行各種各樣的優(yōu)化,比如壓縮代碼等等念逞,這時(shí)候我們不應(yīng)該把這些代碼放到開發(fā)環(huán)境中困食,不利于代碼開發(fā)和調(diào)試。
總結(jié):針對(duì)以上這些說明翎承,我們很有必要把區(qū)分開發(fā)環(huán)境與生產(chǎn)環(huán)境分離硕盹。
(2)開發(fā)環(huán)境的配置和生產(chǎn)換環(huán)境配置的區(qū)別。
- 開發(fā)環(huán)境有的配置叨咖,生產(chǎn)環(huán)境不一定有瘩例,比如說熱更新時(shí)使用到的
HotModuleReplacementPlugin
。- 生產(chǎn)環(huán)境有的配置甸各,開發(fā)環(huán)境不一定有垛贤,比如說用來壓縮js用的
UglifyJsPlugin
。
-
如何去做痴晦?
1> 因?yàn)閣ebpack 默認(rèn)找的是 webpack.config.js配置文件南吮,所以要把開發(fā)環(huán)境的webpack.config.js配置文件改為webpack.dev.config.js代表開發(fā)環(huán)境的配置文件。
2> 新建一個(gè)webpack.prod.config.js誊酌,再把開發(fā)環(huán)境中的webpack.config.js復(fù)制進(jìn)去(沒用的配置文件該刪除的刪除)
-
3> 修改package.json文件(在
scripts
標(biāo)簽中添加"dev"
和"prod"
屬性配置)"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack --config webpack.dev.config.js", "prod": "webpack --config webpack.prod.config.js" },
- 怎樣執(zhí)行命令
- 執(zhí)行開發(fā)環(huán)境的中配置
npm run dev
- 執(zhí)行生產(chǎn)環(huán)境的中配置
npm run prod
- 執(zhí)行開發(fā)環(huán)境的中配置
13部凑、在生產(chǎn)環(huán)境中配置代碼壓縮功能
-
配置webpack.prod.config.js 文件
// webpack.prod.config.js var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin; // …… plugins: [ // …… // js代碼 壓縮 new UglifyJsPlugin({ compress: { warnings: false } }) ]
- 執(zhí)行
npm run prod
命令
四露乏、webpack1和webpack2的區(qū)別
(webpack1.0已經(jīng)廢棄使用,建議使用webpack2.0+)
? webpack1和webpack2的區(qū)別:https://webpack.js.org/guides/migrating/
? 1涂邀、resolve.modulesDirectories
被重命名為 resolve.modules
? 2瘟仿、module.loaders 將繼續(xù)支持,但在未來它將被module.rules 替換比勉。
? 3劳较、……
-=-=-=-==-=-=-=-=-=-=-=-=-=-=over-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
博學(xué)谷:筱竹