沈陽(yáng)建設(shè)工程信息網(wǎng) 最佳中項(xiàng)網(wǎng)公眾號(hào)seo排名優(yōu)化
1 初識(shí)Webpack
1.1 什么是Webpack
Webpack打包工具對(duì)項(xiàng)目中的復(fù)雜文件進(jìn)行打包處理,可以實(shí)現(xiàn)項(xiàng)目的自動(dòng)化構(gòu)建,并且給前端開發(fā)人員帶來(lái)了極大的便利。
目前,企業(yè)中的絕大多數(shù)前端項(xiàng)目是基于Webpack打包工具來(lái)進(jìn)行開發(fā)的。
1.2 Webpack的安裝與使用
使用npm包管理工具安裝webpack和webpack-cli兩個(gè)模塊。
npm install webpack webpack-cli -D
目錄下新建webpack.config.js
文件
// 使用module.exports方式導(dǎo)出配置對(duì)象。
// mode用來(lái)指定構(gòu)建模式
module.exports = {mode: 'development'
};
// package.json
// 設(shè)置dev為webpack
// 表示當(dāng)我們使用npm run dev命令時(shí)
// 就可以執(zhí)行script節(jié)點(diǎn)下dev選項(xiàng)的腳本來(lái)啟動(dòng)Webpack對(duì)項(xiàng)目進(jìn)行打包處理。
"dev": "webpack"
在Webpack的4.x版本中,默認(rèn)約定entry打包的入口文件為src下的index.js;output打包的輸出文件為dist下的main.js。
1.3 手動(dòng)配置入口和出口文件
配置Webpack默認(rèn)入口和出口文件配置是通過(guò)手動(dòng)設(shè)置webpack.config.js文件中的配置對(duì)象的entry和output屬性來(lái)定義新的入口和出口文件。
// webpack.config.js
// 導(dǎo)入操作文件路徑的模塊
const path = require('path');
module.exports = {mode: 'development',// 打包入口文件的路徑entry: path.join(__dirname, './src/index.js'),output: {path: path.join(__dirname, './dist'), // 輸出文件的存放路徑filename: 'bundle.js' // 輸出文件的名稱}
};
1.4 使用Webpack實(shí)現(xiàn)列表隔行換色效果
利用Webpack中jQuery插件來(lái)實(shí)現(xiàn)列表隔行換色的頁(yè)面效果。
- 安裝jQuery插件
npm install jquery -S
- 使用
$.css()
方法實(shí)現(xiàn)頁(yè)面效果 - 打包index.js
- 新建index.html文件
- 查看列表隔行換色效果
// index.js
// 使用ES6模塊化語(yǔ)法導(dǎo)入jquery插件
import $ from 'jquery';
$(function() {$('li:odd').css('backgroundColor', 'lightgreen');$('li:even').css('backgroundColor', 'lightblue');
});
1.5 Webpack與Gulp對(duì)比
- gulp是工具鏈、構(gòu)建工具??梢耘浜细鞣N插件做js壓縮,css壓縮,less編譯等,可以替代手工實(shí)現(xiàn)自動(dòng)化工作;而webpack是文件打包工具,可以把項(xiàng)目的各種js文件、css文件等打包合并成一個(gè)或多個(gè)文件,主要用于模塊化方案,預(yù)編譯模塊的方案。
- 在定義和使用類比中兩者都有各的用途,同時(shí)webpack為初級(jí)編譯程序,gulp為高級(jí)編譯程序,在功能上要比webpack應(yīng)用程序中多。
- webpack可以很方便使用node_module、es6或者樣式注入等功能,作為最初級(jí)的功能定位性價(jià)比最高,webpack輸入輸出都以js為主,對(duì)html兼顧較少,可用組件不多很難達(dá)到可用的程度。gulp在編程方面較為復(fù)雜,但是可用的組件也會(huì)更多,手動(dòng)編譯的情況下耗時(shí)較長(zhǎng),同時(shí)此軟件不適合初級(jí)入門者使用。
- Gulp側(cè)重于前端開發(fā)的整個(gè)過(guò)程的控制管理(像是流水線),我們可以通過(guò)給gulp配置不通的task(通過(guò)Gulp中的gulp.task()方法配置,比如啟動(dòng)server、sass/less預(yù)編譯、文件的合并壓縮等等)來(lái)讓gulp實(shí)現(xiàn)不同的功能,從而構(gòu)建整個(gè)前端開發(fā)流程。
- Webpack,模塊打包機(jī) ,由此也可以看出Webpack更側(cè)重于模塊打包,當(dāng)然我們可以把開發(fā)中的所有資源(圖片、js文件、css文件等)都可以看成模塊,最初Webpack本身就是為前端JS代碼打包而設(shè)計(jì)的,后來(lái)被擴(kuò)展到其他資源的打包處理。Webpack是通過(guò)loader(加載器)和plugins(插件)對(duì)資源進(jìn)行處理的。
| | Gulp | Webpack |
| — | — | — |
| 定位 | 基于流的自動(dòng)化構(gòu)建工具 | 一個(gè)萬(wàn)能模塊打包器 |
| 目標(biāo) | 自動(dòng)化和優(yōu)化開發(fā)工作流,為通用 website 開發(fā)而生 | 通用模塊打包加載器,為移動(dòng)端大型 SPA 應(yīng)用而生 |
| 學(xué)習(xí)難度 | 易于學(xué)習(xí),易于使用, api 總共只有 5 個(gè)方法 | 有大量新的概念和 api ,學(xué)習(xí)成本高 |
| 適用場(chǎng)景 | 基于流的作業(yè)方式適合多頁(yè)面應(yīng)用開發(fā) | 一切皆模塊的特點(diǎn)適合單頁(yè)面應(yīng)用開發(fā) |
| 作業(yè)方式 | 對(duì)輸入( gulp.src )的 js,ts,scss,less等源文件一次執(zhí)行打包(bundle)、編譯(complie)、壓縮、重命名等處理后輸出(gulp.dest)到指定目錄中去,為了構(gòu)建而打包 | 對(duì)入口文件( entry )遞歸解析生成依賴關(guān)系圖,然后將所有依賴打包在一起,在打包之前會(huì)將所有依賴轉(zhuǎn)譯成可打包的 js 模塊,為了打包而構(gòu)建 |
| 使用方式 | 常規(guī) js 開發(fā),編寫一系列構(gòu)建任務(wù)( task ) | 編輯各種 JSON 配置項(xiàng)優(yōu)點(diǎn) |
| 優(yōu)點(diǎn) | 適合多頁(yè)面開發(fā),易于學(xué)習(xí),易于使用,接口優(yōu)雅 | 可以打包一切資源,適配各種模塊系統(tǒng) |
| 缺點(diǎn) | 單頁(yè)面應(yīng)用方面輸出乏力,而且對(duì)流行的單頁(yè)技術(shù)有些難以處理(比如 Vue 單文件組件,使用 gulp 處理就會(huì)很困難,而webpack 一個(gè) Ioader 就能輕松搞定)
| 不適合多頁(yè)應(yīng)用開發(fā),靈活度高但同時(shí)配置很繁瑣復(fù)雜?!按虬磺小边@個(gè)優(yōu)點(diǎn)對(duì)于 HTTP/1.1 尤其重要,因?yàn)樗匈Y源打包在一起能明顯減少瀏覽器訪問(wèn)頁(yè)面時(shí)的資源請(qǐng)求數(shù)量,從而減少應(yīng)用程序必須等待的時(shí)間。但這個(gè)優(yōu)點(diǎn)可能會(huì)隨著 HTTP/2 的流行而變得不那么突出,因?yàn)?HTTP/2 的多路復(fù)用可以有效解決客戶端并行請(qǐng)求時(shí)的瓶頸問(wèn)題。 |
| 結(jié)論 | 瀏覽器多頁(yè)面應(yīng)用(MPA)首選方案 | 瀏覽器單頁(yè)面(SPA)首選方案 |
2 Webpack自動(dòng)打包
2.1 配置webpack-dev-server
webpack-dev-server
可以支持項(xiàng)目自動(dòng)打包的工具,可以啟動(dòng)一個(gè)實(shí)時(shí)打包的HTTP服務(wù)器,使用webpack-dev-server來(lái)實(shí)現(xiàn)項(xiàng)目的自動(dòng)打包功能。
- 安裝
webpack-dev-server
插件npm install webpack-dev-server -D
- 修改
package.json
中scripts
選項(xiàng)中的dev命令"dev": "webpack-dev-server"
- 自動(dòng)打包
bundle.js
npm run dev
- 在命令執(zhí)行后,會(huì)自動(dòng)生成bundle.js文件,它不會(huì)放到物理磁盤上,而是放到了內(nèi)存中,是一個(gè)虛擬的看不見的bundle.js文件。
- 在
index.html
文件中引入bundle.js
<script?src="/bundle.js"></script>
- 引入的根目錄下的bundle.js,bundle.js文件可以通過(guò)
localhost:8080/bundle.js
可以訪問(wèn)到代碼。
- 查看頁(yè)面效果
2.2 配置html-webpack-plugin
html-webpack-plugin插件用來(lái)生成預(yù)覽的頁(yè)面。
- 安裝
html-webpack-plugin
插件npm install html-webpack-plugin -D
- 實(shí)例化
HtmlWebpackPlugin()
- 配置
html-webpack-plugin
插件 - 重新進(jìn)行打包
- 查看頁(yè)面效果
// webpack.config.js
// 導(dǎo)入生成預(yù)覽頁(yè)面的插件,得到一個(gè)構(gòu)造函數(shù)
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 創(chuàng)建插件的實(shí)例對(duì)象
const htmlPlugin = new HtmlWebpackPlugin({// 指定要用到的模板文件template: './src/index.html', // 指定生成的文件的名稱,該文件存在于內(nèi)存中,在目錄中不顯示filename: 'index.html'
});
// plugins數(shù)組是webpack打包期間會(huì)用到的一些插件列表
module.exports = {// 原代碼plugins: [ htmlPlugin ]
};
// package.json
// 修改scripts選項(xiàng)中的dev命令
// --open參數(shù)用來(lái)實(shí)現(xiàn)打包完成后自動(dòng)打開瀏覽器頁(yè)面功能
// --host參數(shù)用來(lái)配置IP地址127.0.0.1
// --port參數(shù)用來(lái)配置端口號(hào)3000。
"dev": "webpack-dev-server --open --host 127.0.0.1 --port 3000"
3 Webpack中的加載器
3.1 css-loader和style-loader加載器
在默認(rèn)的情況下,Webpack能打包處理一些以.js后綴名結(jié)尾的簡(jiǎn)單模塊,而其他非.js后綴名結(jié)尾的復(fù)雜模塊是不能打包處理的,需要通過(guò)調(diào)用特定的加載器來(lái)打包處理相應(yīng)文件模塊,否則會(huì)報(bào)錯(cuò)。
常用加載器:
- css-loader加載器和style-loader加載器
- sass-loader加載器
- less-loader加載器
- postcss-loader加載器
- url-loader加載器
- babel-loader加載器
在Webpack中,同時(shí)使用css-loader和style-loader加載器來(lái)打包處理CSS文件。
- 新建index.css
- 初始化li元素的默認(rèn)樣式
li?{list-style:?none;}
- 引入index.css
- 引入當(dāng)前目錄下的css目錄中的index.css模塊
- 打開index.js文件,在該文件的頭部區(qū)域添加代碼
import?'./css/index.css';
- 報(bào)錯(cuò)是因?yàn)闆]有安裝處理CSS文件的相關(guān)loader加載器
- 運(yùn)行報(bào)錯(cuò)
- 保存文件后,查看運(yùn)行結(jié)果
- 配置loader
- 安裝style-loader和css-loader加載器,并配置loader規(guī)則
npm install style-loader css-loader -D
- 查看頁(yè)面效果
- 保存文件后,使用
npm run dev
命令重新啟動(dòng)服務(wù)器 - 打開webpack.config.js文件,添加module屬性
“/\.css$/”
表示匹配文件名后綴為.css的文件;use表示調(diào)用對(duì)應(yīng)的loader加載器。
- 保存文件后,使用
module: {rules: [{test: /\.css$/, use: ['style-loader', 'css-loader']},]
}
3.2 sass-loader加載器
Sass(Syntactically Awesome Stylesheets)是一個(gè)成熟、穩(wěn)定、功能強(qiáng)大的專業(yè)級(jí)CSS擴(kuò)展語(yǔ)言。使用Sass語(yǔ)言以及Sass的樣式庫(kù)(如?Compass)有助于更好地組織管理樣式文件,并更高效地開發(fā)項(xiàng)目。
在Webpack中,sass-loader加載器可以用來(lái)打包處理Sass文件。
- 在css目錄中,新建index.scss文件,編寫Sass代碼。
ul?{font-size:?12px; li{line-height: 30px;}}
- 安裝處理.scss文件的sass-loader加載器和node-sass模塊
npm install sass-loader node-sass -D
- node-sass是sass-loader的內(nèi)置依賴項(xiàng),當(dāng)使用sass-loader時(shí)必須同時(shí)安裝node-sass模塊。
- 在rules數(shù)組列表中添加處理index.scss文件的loader規(guī)則
- 打開webpack.config.js文件
{test: /\.scss$/,use: ['style-loader', 'css-loader', 'sass-loader']},
“/\.scss$/”
表示匹配文件名后綴為.scss的文件;use中的sass-loader首先被調(diào)用處理匹配到的Sass文件,然后將返回結(jié)果依次向前傳遞,直到結(jié)束。
- 打開index.js文件,在該文件的頭部區(qū)域添加代碼
import?'./css/index.scss';
- 使用
npm run dev
命令重新啟動(dòng)服務(wù)器
3.3 less-loader加載器
Less(Leaner Style Sheets)是一門CSS擴(kuò)展語(yǔ)言,也稱為CSS預(yù)處理器。作為CSS的一種形式的擴(kuò)展,它并沒有減少CSS的功能,而是在現(xiàn)有的CSS語(yǔ)法上,為CSS加入程序式語(yǔ)言的特性。
在Webpack中可以使用less-loader加載器來(lái)打包處理Less文件。
- 在css目錄中,新建index.less文件,編寫less代碼。
body?{margin:?0;padding:?0; ul?{padding:?0;margin:?0;}}
- 安裝處理.less文件的less-loader加載器和less模塊
npm install less-loader less -D
- less模塊是less-loader加載器的內(nèi)置依賴項(xiàng),當(dāng)使用less-loader時(shí)必須同時(shí)安裝less模塊。
- 在rules數(shù)組列表中添加處理index.less文件的loader規(guī)則
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader']},
“/\.less$/”
表示匹配文件名后綴為.less的文件,less-loader加載器用來(lái)處理匹配到的.less文件
- 打開index.js文件,在該文件的頭部區(qū)域添加代碼
import?'./css/index.less';
- 使用
npm run dev
命令重新啟動(dòng)服務(wù)器
3.4 postcss-loader加載器
PostCSS是一個(gè)用JavaScript工具和插件轉(zhuǎn)換CSS代碼的工具,類似于Babel對(duì)JavaScript的處理。
PostCSS的功能如下:
- 使用下一代CSS語(yǔ)法
- 自動(dòng)補(bǔ)全瀏覽器的前綴
- 自動(dòng)把px單位轉(zhuǎn)換成rem
- 壓縮CSS代碼
autoprefixer
是一個(gè)后處理程序(插件),它經(jīng)常與postcss-loader
加載器一起配合使用,會(huì)自動(dòng)為普通的CSS添加瀏覽器前綴,并且支持W3C最新的規(guī)范。
- 定義input搜索框
<body><input type="text" placeholder="搜索"/></body>
- 設(shè)置input輸入框的placeholder屬性的值為“搜索”
- 定義占位文本的字體顏色為紅色效果
::placeholder{color: red;}
- 偽元素
::placeholder
選擇器用來(lái)選擇一個(gè)表單元素的占位文本
- 運(yùn)行程序
- Chome瀏覽器中的“搜索”字體顏色顯示為紅色
- IE11瀏覽器中的“搜索”字體顏色顯示為灰色
- 安裝
postcss-loader
加載器和autoprefixer
插件npm install postcss-loader autoprefixer -D
postcss-loader
和autoprefixer
可以自動(dòng)添加CSS的瀏覽器兼容性前綴
- 引入
autoprefixer
插件,配置插件autoprefixer
插件- 新建
postcss.config.js
文件,編寫JavaScript代碼 - 設(shè)置屬性的值為數(shù)組列表,并在數(shù)組列表掛載一個(gè)
autoprefixer
插件
- 新建
const autoprefixer = require('autoprefixer'); // 導(dǎo)入自動(dòng)添加前綴的插件
module.exports = {plugins: [ autoprefixer ] // 掛載插件
};
- 修改處理index.css文件的loader規(guī)則
- 打開
webpack.config.js
文件,編寫代碼 { test: /\.css$/, use: ['style-loader', 'css-loader', 'postcss-loader']},
- 在use數(shù)組的最后添加一個(gè)
postcss-loader
加載器用來(lái)自動(dòng)為普通的CSS添加瀏覽器前綴
- 打開
- 使用
npm run dev
命令重新啟動(dòng)服務(wù)器
3.5 url-loader加載器
url-loader加載器用來(lái)打包處理CSS中與URL路徑地址相關(guān)的圖片和字體文件,并將圖片和字體文件轉(zhuǎn)換成為base64圖片形式。
- 定義背景圖片
- 定義id值為box的div元素
<body><div id="box"></div></body>
- 設(shè)置id值為box的div元素的背景圖片
#box{width:?580px;height:?340px;background:?url('../images/1.jpg');}
- 配置
url-loader
規(guī)則- 安裝
url-loader
和file-loader
加載器 npm install url-loader file-loader -D
url-loader
和file-loader
能處理圖片和字體文件- 添加處理圖片和字體文件的loader規(guī)則
- 打開
webpack.config.js
文件,編寫代碼 {test: /\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/,use: 'url-loader?limit=16940'},
- test的值表示匹配不同格式的圖片和字體文件;“?”符號(hào)與參數(shù)項(xiàng)“l(fā)imit=16940”連接。limit參數(shù)用來(lái)指定圖片的大小,單位是字節(jié)(byte)。當(dāng)圖片小于16940時(shí),才會(huì)被轉(zhuǎn)為base64圖片
- 安裝
- 查看圖片效果
- 使用
npm run dev
命令重新啟動(dòng)服務(wù)器
- 使用
3.6 babel-loader加載器
項(xiàng)目開發(fā)過(guò)程中,當(dāng)編寫JavaScript代碼時(shí),有時(shí)候會(huì)使用JavaScript高級(jí)語(yǔ)法,這些高級(jí)語(yǔ)法存在兼容性的問(wèn)題。我們可以使用babel-loader加載器對(duì)JavaScript高級(jí)語(yǔ)法進(jìn)行打包處理,如class語(yǔ)法。
- 創(chuàng)建Person類
- 使用class關(guān)鍵字創(chuàng)建Person類
class?Person?{static?name?=?'張三'};console.log(Person.name);
- 保存文件后,運(yùn)行結(jié)果
- 報(bào)錯(cuò)是因?yàn)闆]有安裝處理JavaScript高級(jí)語(yǔ)法的
babel-loader
加載器和插件
- 配置babel-loader規(guī)則
- 安裝
babel-loader
、@babel/core
等插件 npm install babel-loader @babel/core @babel/runtime -D
- 安裝處理JavaScript高級(jí)語(yǔ)法的插件
npm install @babel/preset-env @babel/plugin-transform-runtime @babel/plugin-proposal-class-properties -D
- @babel/preset-env 是一個(gè)智能預(yù)設(shè),可讓開發(fā)人員使用最新的JavaScript,而無(wú)須微觀管理目標(biāo)環(huán)境所需的語(yǔ)法轉(zhuǎn)換。
- @babel/plugin-transform-runtime 是Babel 轉(zhuǎn)換器相關(guān)的插件。
- @babel/plugin-proposal-class-properties 插件用于編譯class。
- 初始化babel基本配置,新建babel.config.js文件,編寫JavaScript代碼
- 配置對(duì)象中的presets屬性的值為數(shù)組列表,并在數(shù)組中添加安裝后的
@babel/preset-env
智能預(yù)設(shè)
- 安裝
module.exports = {presets: [ '@babel/preset-env' ],plugins: [ '@babel/plugin-transform-runtime', '@babel/plugin-proposal-class-properties' ]
};
- 添加處理JavaScript高級(jí)語(yǔ)法的loader規(guī)則
{ test: /\.js$/, use: 'babel-loader', exclude: /node_modules/},
“/\.js$/”
表示匹配文件名后綴為.js的文件,設(shè)置exclude屬性的值為“/node_modules/”,表示babel-loader加載器不需要處理node_modules中的JavaScript文件。- 查看控制臺(tái)打印結(jié)果
- 使用
npm run dev
命令重新啟動(dòng)服務(wù)器 - index.html文件中已經(jīng)手動(dòng)引入過(guò)
bundle.js
- 使用