佛山建站專寧波抖音seo搜索優(yōu)化軟件
為什么需要使用打包工具?
開發(fā)時(shí)使用的框架、es6 語(yǔ)法 、less 等瀏覽器無法識(shí)別。
需要經(jīng)過編譯成瀏覽器能識(shí)別的css、js才可以運(yùn)行。
打包工具可以幫我們編譯,號(hào)可以做代碼壓縮、兼容處理、性能優(yōu)化。
常見的打包工具有什么?
vite、webpack、glup、grunt
webapck最基本的使用?
是一個(gè)靜態(tài)資源打包工具,以一個(gè)或多個(gè)文件為打包入口,將項(xiàng)目中所有文件編譯組合成輸入一個(gè)或多個(gè)文件。這個(gè)輸出的文件我們交budle,他就是經(jīng)過編譯可以在瀏覽器運(yùn)行的文件。
webpack本身的功能是有限的?
開發(fā)模式:僅僅編譯js modle語(yǔ)法
生產(chǎn)模式:編譯js modle語(yǔ)法、壓縮js代碼
package.json 是什么文件?
通常我們需要安裝一些依賴包,而在下載這個(gè)包之前,我們需要包描述文件。通常描述這個(gè)項(xiàng)目所需要的各種模塊,以及項(xiàng)目的配置信息(比如名稱、版本、許可證、如何啟動(dòng)項(xiàng)目、運(yùn)行腳本等元數(shù)據(jù)。
package.json 一般在項(xiàng)目創(chuàng)建之初創(chuàng)建。創(chuàng)建方式可以手動(dòng)(直接在項(xiàng)目根目錄新建一個(gè) package.json 文件)、也可以npm init -y 初始化一個(gè),y 就是要使用配置的默認(rèn)值
package.json文件就是一個(gè)JSON對(duì)象,該對(duì)象的每一個(gè)成員就是當(dāng)前項(xiàng)目的一項(xiàng)設(shè)置
練習(xí)步驟:
1、新建一個(gè)包,名稱不能和webpack重復(fù)
2、創(chuàng)建基本的mani.js 文件、src、public文件、寫入es6 模塊化語(yǔ)法,報(bào)錯(cuò),瀏覽器無法識(shí)別。
3、試試使用webpack 后能否識(shí)別呢?無法解析modle語(yǔ)法
4、引入之前需要初始化一個(gè)包描述文件 npm init -y
5、npm install webpack webpack-cli --save-dev
6、安裝成功后執(zhí)行npx webpack ./src/main.js --mode=development ,npx 會(huì)將node—module 的bin 下面的內(nèi)容臨時(shí)添加到環(huán)境變量。
7、執(zhí)行上面即可打包了。默認(rèn)輸出到dist,可以觀察輸出文件,是編譯后的文件。
8、npx webpack ./src/main.js --mode=production 生產(chǎn)模式,會(huì)壓縮代碼
webapck的五大核心概念
入口entry
輸入output
loader webpack本身只能處理js、json等資源,其他資源需要借助loader
plugin 拓展功能
mode 模式:生產(chǎn)、開發(fā)
練習(xí)步驟:
1、安裝好之后建一個(gè)webpack的配置文件,在根路徑下,并且文件名必須是webpack.config.js
2、添加基本配置
3、我們之前打包執(zhí)行的是npx webpack ./src/main.js --mode=development 這個(gè)命令,寫了webpack的配置文件中設(shè)置了入口后,可以直接使用npx webpack 執(zhí)行了。上面是使用cli的方式運(yùn)行本地的webpack,但這樣還是有些麻煩。
4、在 package.json 文件中添加一個(gè) npm script: “build”: “webpack”
現(xiàn)在,可以使用 npm run build 命令替代之前使用的 npx 命令。注意,使用 npm scripts 便可以像使用 npx 那樣通過模塊名引用本地安裝的 npm packages。
拓展,可以學(xué)習(xí)下npm中文文檔
資源管理
1、使用style樣式,需要借助loader
2、npm install --save-dev style-loader css-loader
3、添加配置,參考官網(wǎng)
1、使用less資源
2、npm install less less-loader --save-dev
3、添加配置,參考官網(wǎng)
1、圖片資源的使用
2、不需要要下載,使用內(nèi)置的asset即可。資源模塊(asset module)是一種模塊類型,它允許使用資源文件(字體,圖標(biāo)等)而無需配置額外 loader。``關(guān)于這塊配置webpack官網(wǎng)介紹
3、添加配置,
{
test: /.(png|svg|jpg|jpeg|gif)$/i,
type: ‘a(chǎn)sset/resource’,
},
1、對(duì)文件的加載,如 JSON 文件、CSV、TSV 和 XML。
2、npm install --save-dev csv-loader xml-loader
3、添加配置,參考官網(wǎng)
調(diào)整文件打包輸出目錄
每一次打包都會(huì)在dist下多一些文件,而且很混亂。我們?cè)谙乱淮未虬笆謩?dòng)刪除dist,再重新打包。
并設(shè)置輸出路徑,文件資源可設(shè)置輸出路徑。
generator: {filename: 'asset/[hash:10][ext][query]'}
可不可以不每次都需要手動(dòng)刪除呢?
能不能自動(dòng)清除dist文件上次內(nèi)容?可以,在output 對(duì)象中配置clean:true 即可。
處理js資源
webpack對(duì)于js資源的處理是有限的,只能處理model語(yǔ)法,對(duì)于es6新語(yǔ)法不兼容,我們需要使用babel
在轉(zhuǎn)換之前先介紹一下eslint ,用于檢查jx和jsx語(yǔ)法的工具。更多介紹eslint官網(wǎng)
在webpack中使用eslint
1、npm install eslint-webpack-plugin --save-dev
2、npm install eslint --save-dev
3、添加配置,參考官網(wǎng)
const ESLintPlugin = require('eslint-webpack-plugin');module.exports = {// ...plugins: [new ESLintPlugin({context:path.resolve(__dirname,'src'),})]// ...
};
4、運(yùn)行起來報(bào)錯(cuò),缺少eslint的配置文件。我們?cè)诟夸浵滦陆?.eslintrc.js 文件名不能改。
然后具體的配置可以參考官網(wǎng),可以繼承推薦的默認(rèn)配置。
5、發(fā)現(xiàn)dist下定義的文件也被eslint 檢查了,但我們并不需要檢查這些文件。在根目錄下創(chuàng)建一個(gè) .eslintignore 文件,寫上需要忽略的文件路徑即可。
在webpack中使用babel
關(guān)于bable的介紹可以看bable官網(wǎng)
1、npm install -D babel-loader @babel/core @babel/preset-env webpack
2、配置,參考官網(wǎng) bable配置
3、配置可以直接寫在webpack的配置文件中,也可以在根目錄創(chuàng)建 babel.config.js 配置。
處理html資源
1、原本html中引入的js資源是這么寫的
<script src="../dist/main.js"></script>
引入的是打包后的文件,如果更改入口起點(diǎn)的名稱,或者添加一個(gè)新的入口,那么會(huì)在構(gòu)建時(shí)重新命名生成的 bundle,但是 index.html 仍然在引用舊的名稱!而且如果需要引入很多資源,手動(dòng)維護(hù)非常困難。
我們可以使用 HtmlWebpackPlugin 來解決這個(gè)問題。
安裝:
npm install --save-dev html-webpack-plugin
配置:
new HtmlWebpackPlugin({title: '管理輸出',// 模板:以public/index.html 文件創(chuàng)建新的html 這樣打包之后的html不會(huì)把之前的東西丟掉template:path.resolve(__dirname,'public/index.html')}),
使用了這個(gè)插件,我們無需在html中手動(dòng)引入,他會(huì)自動(dòng)幫我們引入并且在輸出文件中新增一個(gè)html文件。
搭建開發(fā)服務(wù)器
我們之前每次改動(dòng)了src的內(nèi)容,都需要編譯之后才能看到效果,需要手動(dòng)執(zhí)行npx webapck ,我們希望webpack能自動(dòng)化,可以使用
webpack-dev-server,他相當(dāng)于webpack 啟動(dòng)了一個(gè)服務(wù)器,他會(huì)幫我們監(jiān)聽src下所有的改動(dòng),只有有改動(dòng)會(huì)幫我們自動(dòng)打包編譯。
安裝
npm install --save-dev webpack-dev-server
配置
devServer:{host:'localhost',// 啟動(dòng)服務(wù)器的域名port:'8080',// 啟動(dòng)服務(wù)器端口號(hào),open:true,// 是否自動(dòng)打開瀏覽器static: './dist', // 將 dist 目錄下的文件 serve 噠服務(wù)器},
執(zhí)行命令
npx webpack serve
添加一個(gè)可以直接運(yùn)行 dev server 的 script:
"scripts": {"test": "echo \"Error: no test specified\" && exit 1","watch": "webpack --watch","start": "webpack serve --open","build": "webpack"},
在命令行中運(yùn)行 npm start,會(huì)看到瀏覽器自動(dòng)加載頁(yè)面。
eee,報(bào)錯(cuò)了!
報(bào)錯(cuò)內(nèi)容:
Error: Cannot find module ‘a(chǎn)jv/dist/compile/codegen’
解決辦法:
npm i ajv
npm install ajv-errors@1.0.1
再次啟動(dòng)
eee,又報(bào)錯(cuò)了!
報(bào)錯(cuò)內(nèi)容:
Error: Conflict: Multiple chunks emit assets to the same filename static/js/bundle.js (chunks main and vendors-node_modules_react-hot-loader_patch_js-node_modules_react_jsx-dev-runtime_js-node_mod-4610d2)
解決辦法:
讓它工作不得不改變filename: "static/js/bundle.js"至filename: "static/js/[name].js"output: {path: undefined,publicPath: "/",filename: "static/js/[name].js",chunkFilename: "static/js/[name].chunk.js",
}
再次啟動(dòng)可以了
webpack-dev-server 在編譯之后不會(huì)寫入到任何輸出文件,而是將 bundle 文件保留在內(nèi)存中,然后將它們 serve 到 server 中,就好像它們是掛載在 server 根路徑上的真實(shí)文件一樣。如果你的頁(yè)面希望在其他不同路徑中找到 bundle 文件,可以通過 dev server 配置中的 devMiddleware.publicPath 選項(xiàng)進(jìn)行修改。
意思就是開發(fā)模式下不會(huì)生成打包后的文件,嘗試把dist刪除,保存后自動(dòng)打包確實(shí)沒有生成dist文件了
修改js文件內(nèi)容頁(yè)面自動(dòng)更新了。
生產(chǎn)和開發(fā)環(huán)境兩套配置
首先我們新建一個(gè)config文件夾,分別新建webpack.dev.js 和 webpack.prod.js 兩個(gè)文件
將文件中使用相對(duì)路徑的地方加個(gè)…/
template:path.resolve(__dirname,'../public/index.html')
但是入口文件路徑不改變,因?yàn)榕渲梦募\(yùn)行時(shí)在根目錄
entry:'./src/main.js',
生產(chǎn)環(huán)境不需要dev-server
分別添加兩個(gè)命令
"build": "webpack --config ./config/webpack.prod.js","start": "webpack serve --config ./config/webpack.dev.js"
執(zhí)行對(duì)應(yīng)的命令,生產(chǎn)環(huán)境下的budle 有壓縮。
提取css成單獨(dú)文件
我們可以看到,現(xiàn)在我們的css文件,是被打包到了js中,當(dāng)js文件加載時(shí),會(huì)創(chuàng)建一個(gè)style 標(biāo)簽來生產(chǎn)樣式。
只有js加載完了,頁(yè)面才會(huì)出現(xiàn)樣式,給用戶閃屏的感覺,體驗(yàn)不好。
應(yīng)該是將樣式抽離到單獨(dú)的css文件中,通過link標(biāo)簽引入,加載的性能才好
借助插件MiniCssExtractPlugin來實(shí)現(xiàn),官網(wǎng)介紹
1、安裝:
npm install --save-dev mini-css-extract-plugin
2、配置
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
將styel-loader 替換為MiniCssExtractPlugin.loader,因?yàn)椴寮?huì)將 CSS 提取到單獨(dú)的文件中,
為每個(gè)包含 CSS 的 JS 文件創(chuàng)建一個(gè) CSS 文件,并且支持 CSS 和 SourceMaps 的按需加載。
不再需要?jiǎng)?chuàng)建style 標(biāo)簽了use: [MiniCssExtractPlugin.loader, 'css-loader'],
現(xiàn)在已經(jīng)被打包到main.scc 中了
css 兼容性處理
postcss-loader 官網(wǎng)介紹
可以幫我們處理一些樣式兼容性問題
1、安裝
npm install --save-dev postcss-loader postcss postcss-preset-env
2、配置,必須寫在css-loder 后面
{loader: 'postcss-loader',options: {postcssOptions: {plugins: [['postcss-preset-env',{// 其他選項(xiàng)},],],},},
3、在package.json 中添加配置
設(shè)置瀏覽器兼容需要做到什么程度。
"browserslist" :["last 2 version","< 1%","not dead"]
css壓縮處理
通過觀察可以發(fā)現(xiàn),我們dist目錄下的資源,js和html都?jí)嚎s了。但css文件沒有壓縮處理。
我們可以借助CssMinimizerWebpackPlugin 插件,官網(wǎng)介紹
1、安裝
npm install css-minimizer-webpack-plugin --save-dev
2、配置
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");optimization: {minimizer: [// 在 webpack@5 中,你可以使用 `...` 語(yǔ)法來擴(kuò)展現(xiàn)有的 minimizer(即 `terser-webpack-plugin`),將下一行取消注釋// `...`,new CssMinimizerPlugin(),],},
再次打包已經(jīng)被壓縮了
打包優(yōu)化
1、提升開發(fā)體驗(yàn)
2、提升打包構(gòu)建速度
3、減少代碼體積
4、優(yōu)化代碼性能
sourceMap
開發(fā)時(shí)我們運(yùn)行的代碼是編譯之后的,如果有報(bào)錯(cuò),只能定位到編譯后的位置,不便于我們排查問題。
sourceMap(源代碼映射) 是一個(gè)用來生成源代碼和映射代碼構(gòu)建的方案
他會(huì)生成xx.map 文件,里面包含源代碼碼和構(gòu)建好的代碼每一行,每一列的關(guān)系。從而讓瀏覽器提示源文件的出錯(cuò)位置,從而幫我們快速定位錯(cuò)誤。
使用devtool?
配置
開發(fā)模式:mode:'development',devtool:'cheap-module-source-map',生成模式:
mode:'production',devtool:'source-map',
經(jīng)過測(cè)試,已經(jīng)定位到具體一行了
HotModlueReplcaement
當(dāng)我們?cè)陂_發(fā)時(shí)只修改了某一個(gè)模塊的代碼,webpack在打包時(shí)會(huì)重新打包,速度很慢,頁(yè)面整體重新刷新了。我們希望她值編譯需要打包的模塊,其他模塊不變。
HotModlueReplcaement(熱模塊替換)在程序運(yùn)行中,替換、添加、刪除模塊,而無需加載整頁(yè)面,
如何使用?
devServer:{host:'localhost',// 啟動(dòng)服務(wù)器的域名port:'8080',// 啟動(dòng)服務(wù)器端口號(hào),open:true,// 是否自動(dòng)打開瀏覽器static: './dist',hot:true // 只應(yīng)用與開發(fā)環(huán)境,生產(chǎn)環(huán)境不需要,默認(rèn)開啟},
但是css/html 可以做到,對(duì)于js 需要在入庫(kù)文件manjs中
if(module.hot) {// 判斷是否支持熱模塊替換功能,有的話需要一個(gè)個(gè)js文件添加
module.hot.accept('./js/sum.js')
}
當(dāng)然了,vue-loader,react-hot-loder 已經(jīng)幫我們做了這些事情。
oneOf
打包時(shí)每個(gè)文件都會(huì)經(jīng)過所以loader處理,我們希望她找到對(duì)應(yīng)的loader之后剩下的就不匹配了