webpack基于node,因此想要學(xué)習(xí)webpack首先要安裝node。
webpack4要安裝node8.2以上版本。
為什么選擇本地安裝,主要是由于以后介紹熱更新這一部分不會(huì)報(bào)錯(cuò),如果全局安裝熱更新就會(huì)報(bào)錯(cuò),以本部分為基礎(chǔ)依次介紹,保證各部分不會(huì)出錯(cuò)。
mkdir webpack-test cd webpack-test npm init //初始化npm,都選擇默認(rèn),文件夾自動(dòng)創(chuàng)建package.json npm i webpack webpack-cli -D // 本地安裝webpack
★ npm i -D 是 npm install --save-dev 的簡(jiǎn)寫,是指安裝模塊并保存到 package.json 的 devDependencies中,主要在開發(fā)環(huán)境中的依賴包
2、初試0配置打包webpack4可以支持0配置打包,這里所說(shuō)的0配置又是什么呢?當(dāng)然在開發(fā)者眼中0配置的東西,那根本是無(wú)法用的,因?yàn)椴粔蛑悄?,那么我們就?lái)看看做到了哪些0配置。
在使用webpack進(jìn)行打包的時(shí)候,默認(rèn)情況下會(huì)將src下的入口文件(index.js)進(jìn)行打包。
a. 根目錄下創(chuàng)建文件夾src,并創(chuàng)建index.js文件
document.write("Hello webpack!")
b. 打包測(cè)試
如果直接打包:
最后提示:
WARNING in configuration //配置警告
大體意思:是mode沒有設(shè)置,webpack生產(chǎn)環(huán)境無(wú)法獲取mode值,請(qǐng)?jiān)O(shè)置mode來(lái)確定開發(fā)環(huán)境還是生產(chǎn)環(huán)境
通過(guò)以下手段皆可以不報(bào)錯(cuò):
// node v8.2版本以后都會(huì)有一個(gè)npx // npx會(huì)執(zhí)行bin里的文件 npx webpack // 不設(shè)置mode的情況下 打包出來(lái)的文件自動(dòng)壓縮 npx webpack --mode development // 設(shè)置mode為開發(fā)模式,打包后的文件不被壓縮
當(dāng)執(zhí)行npx webpack命令的時(shí)候,webpack會(huì)自動(dòng)查找項(xiàng)目中src目錄下的index.js文件,然后進(jìn)行打包,生成一個(gè)dist目錄并存在一個(gè)打包好的main.js文件
這些算是0配置的操作了,名字都是定義好的,不能變,想想也很雞肋
目錄結(jié)構(gòu):
重新創(chuàng)建目錄:lesson_test
初始化:npm init //全部選擇默認(rèn)即可
創(chuàng)建webpack.config.js配置文件
webpack.config.js基本配置項(xiàng):
module.exports = { entry: "", // 入口文件 output: {}, // 出口文件 module: {}, // 處理對(duì)應(yīng)模塊 plugins: [], // 對(duì)應(yīng)的插件 devServer: {}, // 開發(fā)服務(wù)器配置 mode: "development" // 模式配置 }
a.根目錄下創(chuàng)建src文件夾,并在src目錄下創(chuàng)建index.js:
document.write("Hello webpack!")
b.配置文件webpack.config.js:
const path = require("path") module.exports = { entry: "./src/index.js", output: { filename: "bundle.js", path: path.resolve(__dirname, "./dist") }, mode: "development" }
c.執(zhí)行webpack
通過(guò)簡(jiǎn)單打包,在根目錄下多出一個(gè)文件夾
查看一下dist文件夾下bundle.js可見以下代碼,證明打包成功
友情提示:
在我們每次npm run build的時(shí)候都會(huì)在dist目錄下創(chuàng)建很多打好的包,如果積累過(guò)多可能也會(huì)混亂,所以應(yīng)該在每次打包之前將dist目錄下的文件都清空,然后再把打好包的文件放進(jìn)去
這里提供一個(gè)clean-webpack-plugin插件
npm i clean-webpack-plugin -D
webpack.config.js中添加以下配置代碼:
let CleanWebpackPlugin = require("clean-webpack-plugin"); module.exports = { plugins: [ // 打包前先清空 new CleanWebpackPlugin("dist") ] }4、配置開發(fā)環(huán)境/生產(chǎn)環(huán)境
上邊部分我們測(cè)試已經(jīng)發(fā)現(xiàn),直接打包會(huì)警告配置環(huán)境,本部分著重介紹一下。
環(huán)境配置在package.json文件:
{ "name": "lesson_test", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1", "dev": "webpack --mode development", // 開發(fā)環(huán)境,和上部分npx webpack --mode development對(duì)比我們可以發(fā)現(xiàn)點(diǎn)端倪 "build": "webpack --mode production" // 生產(chǎn)環(huán)境 }, "author": "", "license": "ISC" }
開發(fā)環(huán)境和生產(chǎn)環(huán)境打包會(huì)有什么區(qū)別呢?
"dev": "webpack --mode development", // 開發(fā)環(huán)境,打包后文件是未壓縮的文件
"build": "webpack --mode production" // 生產(chǎn)環(huán)境,打包后文件是壓縮過(guò)的文件
配置完成后,通過(guò)執(zhí)行命令:
a. 執(zhí)行 npm run dev
打包后文件為非壓縮文件
b. 執(zhí)行 npm run build
打包后文件為壓縮文件
5、多文件入口配置假如src目錄下多個(gè)文件入口,又該如何配置webpack.config.js文件呢。
具體方案:
一種是沒有關(guān)系的但是要打包到一起去的,可以寫一個(gè)數(shù)組,實(shí)現(xiàn)多個(gè)文件打包
另一種就是每一個(gè)文件都多帶帶打包成一個(gè)文件的
下面就來(lái)看看這兩種方式的寫法,配置代碼:
const path = require("path") module.exports = { // 1.寫成數(shù)組的方式就可以打出多入口文件,不過(guò)這里打包后的文件都合成了一個(gè) // entry: ["./src/index.js", "./src/login.js"], // 2.真正實(shí)現(xiàn)多入口和多出口需要寫成對(duì)象的方式 entry: { index: "./src/index.js", login: "./src/login.js" }, output: { // 1. filename: "bundle.js", // 2. [name]就可以將出口文件名和入口文件名一一對(duì)應(yīng) //filename: "[name].js", // 打包后會(huì)生成index.js和login.js文件 filename: "[name].[hash:16].js", //生成文件名含有16位哈希值 path: path.resolve(__dirname, "dist") }, mode: "development" }
執(zhí)行npm run dev結(jié)果
目錄結(jié)構(gòu)(生成文件的名字帶有16位哈希值):
6、打包html配置webpack的核心功能是打包js的,html、style、css、less、sass、img等等需要引入各種loader,到達(dá)這一部分,每一步都需要引入對(duì)應(yīng)的插件。
html需要安裝html-webpack-plugin插件,開始引入:
npm i html-webpack-plugin -D // 本地安裝
因?yàn)槭莻€(gè)插件,所以需要在webpack.config.js里引用一下。
a. 單文件入口配置
const path = require("path") const HtmlWebpackPlugin = require("html-webpack-plugin") // 引入html打包插件 module.exports = { entry: "./src/index.js", output: { filename: "index.js", path: path.resolve(__dirname, "dist") }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", hash: true // 在html模板中自動(dòng)添加?20位哈希值 }) ], mode: "development" }
執(zhí)行npm run dev 生成目錄
打開index.html文件,可見js文件后添加了“?20位哈希值”
b. 多文件入口配置
const path = require("path") const HtmlWebpackPlugin = require("html-webpack-plugin") module.exports = { entry: { main: "./src/index.js", login: "./src/login.js" }, output: { filename: "[name].js", path: path.resolve(__dirname, "dist") }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", filename: "index.html", chunks: ["main"], // 對(duì)應(yīng)關(guān)系,main.js對(duì)應(yīng)的是index.html,這里特意修改為main,方便理解,以下會(huì)和目錄文件作對(duì)比就一目了然了 hash: true // 在html模板中自動(dòng)添加?20位哈希值 }), new HtmlWebpackPlugin({ template: "./src/login.html", filename: "login.html", chunks: ["login"], // 對(duì)應(yīng)關(guān)系,index.js對(duì)應(yīng)的是index.html hash: true // 在html模板中自動(dòng)添加?20位哈希值 }) ], mode: "development" }
由目錄可見,dist文件夾下生成index.html對(duì)應(yīng)main.js、login.html對(duì)應(yīng)login.js
上面基本介紹完了html和js的打包配置了,現(xiàn)在我們還缺一個(gè)好兄弟css,webpack對(duì)css的解析需要用到loader,所以我們先提前安裝好,待會(huì)好方便使用
7、引入css文件這里涉及到兩種樣式:
html頁(yè)面內(nèi)style樣式 ,本部分介紹
html引入外部樣式表 第8部分介紹
npm i style-loader css-loader -D // stylecss // 引入less文件的話,也需要安裝對(duì)應(yīng)的loader npm i less less-loader -D
文件目錄結(jié)構(gòu)
a. 配置樣式
b. 在js文件中引入樣式
c. 配置webpack.config.js文件
說(shuō)明:配置module添加規(guī)則,本部分添加可css、less的匹配打包規(guī)則
const path = require("path") const HtmlWebpackPlugin = require("html-webpack-plugin") module.exports = { entry: { main: "./src/index.js", login: "./src/login.js" }, output: { filename: "[name].js", path: path.resolve(__dirname, "dist") }, module: { rules: [ { test: /.css$/, use: ["style-loader", "css-loader"] }, { test: /.less$/, use: ["style-loader", "css-loader", "less-loader"] } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", filename: "index.html", chunks: ["main"], // 對(duì)應(yīng)關(guān)系,index.js對(duì)應(yīng)的是index.html hash: true // 在html模板中自動(dòng)添加?20位哈希值 }), new HtmlWebpackPlugin({ template: "./src/login.html", filename: "login.html", chunks: ["login"], // 對(duì)應(yīng)關(guān)系,index.js對(duì)應(yīng)的是index.html hash: true // 在html模板中自動(dòng)添加?20位哈希值 }) ], mode: "development" }
d. 執(zhí)行npm run dev打包
生成靜態(tài)文件index.html
生成靜態(tài)文件login.html
此時(shí)打包后的css文件是以行內(nèi)樣式style的標(biāo)簽寫進(jìn)打包后的html頁(yè)面中,如果樣式很多的話,我們更希望直接用link的方式引入進(jìn)去,這時(shí)候需要把css拆分出來(lái)
extract-text-webpack-plugin插件相信用過(guò)的人都知道它是干什么的,它的功效就在于會(huì)將打包到j(luò)s里的css文件進(jìn)行一個(gè)拆分
8、拆分css文件本部分也就是將css文件拆分出來(lái),html頁(yè)面以的方式引入。
// @next表示可以支持webpack4版本的插件 npm i extract-text-webpack-plugin@next -D
配置webpack.config.js
const path = require("path") const HtmlWebpackPlugin = require("html-webpack-plugin") const ExtractTextWebpackPlugin = require("extract-text-webpack-plugin") // 引入插件 module.exports = { entry: { main: "./src/index.js", login: "./src/login.js" }, output: { filename: "[name].js", path: path.resolve(__dirname, "dist") }, module: { rules: [ { test: /.css$/, use: ExtractTextWebpackPlugin.extract({ // 將css用link的方式引入就不再需要style-loader了 use: "css-loader" }) } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", filename: "index.html", chunks: ["main"], hash: true }), new HtmlWebpackPlugin({ template: "./src/login.html", filename: "login.html", chunks: ["login"], hash: true }), new ExtractTextWebpackPlugin("css/style.css") // 拆分后會(huì)把css文件放到dist目錄下的css/style.css ], mode: "development" }
配置中只對(duì)index.html文件引入樣式,而login.html沒有引入,因此要注釋掉login.js引入的樣式
// import "./less/style.less" // 注釋掉這句代碼 document.write("Welcome to webpack!
")
執(zhí)行npm run dev,生成dist目錄
首頁(yè)靜態(tài)頁(yè)面代碼,可見以link的方式引入了css樣式
9、拆分多個(gè)css文件配置webpack.config.js文件
const path = require("path") const HtmlWebpackPlugin = require("html-webpack-plugin") const ExtractTextWebpackPlugin = require("extract-text-webpack-plugin") // 樣式處理 const styleCss = new ExtractTextWebpackPlugin("./css/style.css") const styleLess = new ExtractTextWebpackPlugin("./css/style2.css") module.exports = { entry: { main: "./src/index.js", login: "./src/login.js" }, output: { filename: "[name].js", path: path.resolve(__dirname, "dist") }, module: { rules: [ { test: /.css$/, use: styleCss.extract({ use: "css-loader" }) }, { test: /.less$/, use: styleLess.extract({ use: ["css-loader", "less-loader"], // 一定要注意這里 fallback: "style-loader" // 缺少這里也是無(wú)法編譯less }) } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", filename: "index.html", chunks: ["main"], // 對(duì)應(yīng)關(guān)系,index.js對(duì)應(yīng)的是index.html hash: true // 在html模板中自動(dòng)添加?20位哈希值 }), new HtmlWebpackPlugin({ template: "./src/login.html", filename: "login.html", chunks: ["login"], // 對(duì)應(yīng)關(guān)系,index.js對(duì)應(yīng)的是index.html hash: true // 在html模板中自動(dòng)添加?20位哈希值 }), styleCss, styleLess ], mode: "development" }
index.js文件
import "./css/style.css" import "./less/style.less" // 引入style.less document.write("Hello webpack!
測(cè)試less樣式是否引入
")
執(zhí)行 npm run dev ,獲取靜態(tài)頁(yè)面截圖,可見全部正常引入
執(zhí)行效果
生成文件目錄:
10、樣式表引用圖片處理圖片方面,也需要loader
npm i file-loader url-loader -D
這里著重介紹一下file-loader和url-loader:
本部分介紹url-loader(增強(qiáng)的file-loader);
url-loader作用:根據(jù)需求選擇性的把某些小圖片編碼成base64格式寫進(jìn)頁(yè)面;從而減少服務(wù)器請(qǐng)求。優(yōu)化性能。
url-loader解決的問(wèn)題:
如果圖片較多,會(huì)發(fā)很多http請(qǐng)求,會(huì)降低頁(yè)面性能。url-loader會(huì)將引入的圖片編碼,生成dataURl。相當(dāng)于把圖片數(shù)據(jù)翻譯成一串字符。再把這串字符打包到文件中,最終只需要引入這個(gè)文件就能訪問(wèn)圖片了。當(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)系呢?
簡(jiǎn)答地說(shuō),url-loader封裝了file-loader。url-loader不依賴于file-loader,即使用url-loader時(shí),只需要安裝url-loader即可,不需要安裝file-loader,因?yàn)閡rl-loader內(nèi)置了file-loader。
通過(guò)上面的介紹,我們可以看到,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即可。
如果是在css文件里引入的如背景圖之類的圖片,就需要指定一下相對(duì)路徑
webpack.config.js配置:
const path = require("path") const HtmlWebpackPlugin = require("html-webpack-plugin") const ExtractTextWebpackPlugin = require("extract-text-webpack-plugin") // 樣式處理 const styleCss = new ExtractTextWebpackPlugin("./css/style.css") const styleLess = new ExtractTextWebpackPlugin("./css/style2.css") module.exports = { entry: { main: "./src/index.js", login: "./src/login.js" }, output: { filename: "[name].js", path: path.resolve(__dirname, "dist") }, module: { rules: [ { test: /.css$/, use: styleCss.extract({ use: "css-loader", publicPath: "../" // 樣式根據(jù)相對(duì)路徑引用到圖片資源 }) }, { test: /.less$/, use: styleLess.extract({ use: ["css-loader", "less-loader"], fallback: "style-loader" }) }, { test: /.(jpe?g|png|gif)$/, use: [ { loader: "url-loader", options: { limit: 8192, // 小于8k的圖片自動(dòng)轉(zhuǎn)成base64格式,并且不會(huì)存在實(shí)體圖片 outputPath: "images" // 圖片輸出路徑 } } ] } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", filename: "index.html", chunks: ["main"], hash: true }), new HtmlWebpackPlugin({ template: "./src/login.html", filename: "login.html", chunks: ["login"], hash: true }), styleCss, styleLess ], mode: "development" }
樣式style.css代碼:
/* style.css */ @charset "utf-8"; .logo { display: block; width: 222px; height: 222px; background: url(../images/logo.png) no-repeat; // 這里的logo.png大小大于8K,以下生成在dist文件夾下images目錄 } .color-red { color: #f00; }
在css中指定了publicPath路徑這樣就可以根據(jù)相對(duì)路徑引用到圖片資源了,如下圖所示
執(zhí)行npm run dev 生成目錄結(jié)構(gòu):
11、js文件引入圖片url-loader能自動(dòng)識(shí)別CSS代碼中的圖片路徑并將其打包至指定目錄,但是JS就不同了,我們來(lái)看下面的例子。
// index.js var img = new Image(); img.src = "./images/logo.png"; document.body.appendChild(img);
如果不使用Webpack打包,正常情況下只要路徑正確圖片是能夠正常顯示的。然而,當(dāng)使用Webpack打包后,我們會(huì)發(fā)現(xiàn)圖片并未被成功打包到dist目錄,自然圖片也無(wú)法顯示出來(lái)。
這其實(shí)是因?yàn)閃ebpack并不知道"../images/logo.png"是一張圖片,如果要正常打包的話需要先將圖片資源加載進(jìn)來(lái),然后再將其作為圖片路徑添加至圖片對(duì)象。具體代碼如下:
// index.js import imgUrl from "./images/logo.png" // 引入圖片(路徑),如果小于8K格式為base64,大于8K為設(shè)置路徑dist目錄下"./images/logo.png" const img = new Image() // 實(shí)例一個(gè)圖片對(duì)象 img.src = imgUrl; document.body.appendChild(img); // 添加到dom節(jié)點(diǎn)中
完整index.js文件:
import "./css/style.css" import "./less/style.less" import imgUrl from "./images/logo.png" // 引入圖片 const img = new Image() img.src = imgUrl document.body.appendChild(img) // document.write(imgUrl) // "./images/logo.png" document.write("Hello webpack!
測(cè)試第二個(gè)css樣式是否引入
")
完整webpack.config.js配置文件(相比第10部分無(wú)任何變化):
const path = require("path") const HtmlWebpackPlugin = require("html-webpack-plugin") const ExtractTextWebpackPlugin = require("extract-text-webpack-plugin") // 樣式處理 const styleCss = new ExtractTextWebpackPlugin("./css/style.css") const styleLess = new ExtractTextWebpackPlugin("./css/style2.css") module.exports = { entry: { main: "./src/index.js", login: "./src/login.js" }, output: { filename: "[name].js", path: path.resolve(__dirname, "dist") }, module: { rules: [ { test: /.css$/, use: styleCss.extract({ use: "css-loader", publicPath: "../" // 樣式根據(jù)相對(duì)路徑引用到圖片資源 }) }, { test: /.less$/, use: styleLess.extract({ use: ["css-loader", "less-loader"], fallback: "style-loader" }) }, { test: /.(jpe?g|png|gif)$/, use: [ { loader: "url-loader", options: { limit: 8192, outputPath: "images", // 圖片輸出路徑 name: "[name].[ext]" } } ] } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", filename: "index.html", chunks: ["main"], // 對(duì)應(yīng)關(guān)系,index.js對(duì)應(yīng)的是index.html hash: true // 在html模板中自動(dòng)添加?20位哈希值 }), new HtmlWebpackPlugin({ template: "./src/login.html", filename: "login.html", chunks: ["login"], // 對(duì)應(yīng)關(guān)系,index.js對(duì)應(yīng)的是index.html hash: true // 在html模板中自動(dòng)添加?20位哈希值 }), styleCss, styleLess ], mode: "development" }
執(zhí)行npm run dev生成文件目錄
生成靜態(tài)文件
可見圖片在js中正常加載到頁(yè)面中,由于logo.png大于8K,被打包到dist文件目錄的images文件中。如果圖片小于8K,則以base64編碼格式寫入頁(yè)面進(jìn)項(xiàng)渲染。
頁(yè)面中經(jīng)常會(huì)用到img標(biāo)簽,img引用的圖片地址也需要一個(gè)loader來(lái)進(jìn)行處理
npm i html-withimg-loader -D
完整wabpack.config.js配置:
const path = require("path") const HtmlWebpackPlugin = require("html-webpack-plugin") const ExtractTextWebpackPlugin = require("extract-text-webpack-plugin") // 樣式處理 const styleCss = new ExtractTextWebpackPlugin("./css/style.css") const styleLess = new ExtractTextWebpackPlugin("./css/style2.css") module.exports = { entry: { main: "./src/index.js", login: "./src/login.js" }, output: { filename: "[name].js", path: path.resolve(__dirname, "dist") }, module: { rules: [ { test: /.css$/, use: styleCss.extract({ use: "css-loader", publicPath: "../" // 樣式根據(jù)相對(duì)路徑引用到圖片資源 }) }, { test: /.less$/, use: styleLess.extract({ use: ["css-loader", "less-loader"], fallback: "style-loader" }) }, { test: /.(jpe?g|png|gif)$/, use: [ { loader: "url-loader", options: { limit: 8192, outputPath: "images", // 圖片輸出路徑 name: "[name].[ext]" } } ] }, { test: /.(htm|html)$/, use: "html-withimg-loader" // 引入html-withimg-loader } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", filename: "index.html", chunks: ["main"], // 對(duì)應(yīng)關(guān)系,index.js對(duì)應(yīng)的是index.html hash: true // 在html模板中自動(dòng)添加?20位哈希值 }), new HtmlWebpackPlugin({ template: "./src/login.html", filename: "login.html", chunks: ["login"], // 對(duì)應(yīng)關(guān)系,index.js對(duì)應(yīng)的是index.html hash: true // 在html模板中自動(dòng)添加?20位哈希值 }), styleCss, styleLess ], mode: "development" }
打包后生成對(duì)應(yīng)目錄:
13、引入字體圖片和SVG圖片字體圖標(biāo)和svg圖片都可以通過(guò)file-loader來(lái)解析,在第11部分已經(jīng)進(jìn)行安裝。
webpack.config.js引入loader
module.exports = { module: { rules: [ { test: /.(eot|ttf|woff|svg)$/, use: [ { loader: "file-loader", options: { outputPath: "iconfont" // 打包到指定文件夾 } } ] } ] } }
這樣即使樣式中引入了這類格式的圖標(biāo)或者圖片都沒有問(wèn)題了,img如果也引用svg格式的話,配合上面寫好的html-withimg-loader就都沒有問(wèn)題了。
在index.js引入樣式:
import "./css/style.css" import "./less/style.less" import "./iconfont/iconfont.css" // 引入字體圖片 import imgUrl from "./images/pic.jpg" // 引入圖片鏈接 const img = new Image() img.src = imgUrl document.body.appendChild(img) // document.write(imgUrl) // "./images/logo.png" document.write("Hello webpack!
測(cè)試第二個(gè)css樣式是否引入
")
完整的webpack.config.js配置:
const path = require("path") const HtmlWebpackPlugin = require("html-webpack-plugin") const ExtractTextWebpackPlugin = require("extract-text-webpack-plugin") // 樣式處理 const styleCss = new ExtractTextWebpackPlugin("./css/style.css") const styleLess = new ExtractTextWebpackPlugin("./css/style2.css") module.exports = { entry: { main: "./src/index.js", login: "./src/login.js" }, output: { filename: "[name].js", path: path.resolve(__dirname, "dist") }, module: { rules: [ { test: /.css$/, use: styleCss.extract({ use: "css-loader", publicPath: "../" // 樣式根據(jù)相對(duì)路徑引用到圖片資源 }) }, { test: /.less$/, use: styleLess.extract({ use: ["css-loader", "less-loader"], fallback: "style-loader" }) }, { test: /.(jpe?g|png|gif)$/, use: [ { loader: "url-loader", options: { limit: 8192, outputPath: "images", // 圖片輸出路徑 name: "[name].[ext]" } } ] }, { test: /.(eot|ttf|woff|svg)$/, use: [ { loader: "file-loader", options: { outputPath: "iconfont" // 打包到指定文件夾 } } ] }, { test: /.(htm|html)$/, use: "html-withimg-loader" // 引入html-withimg-loader,將圖片轉(zhuǎn)化為base64圖片 } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", filename: "index.html", chunks: ["main"], hash: true }), new HtmlWebpackPlugin({ template: "./src/login.html", filename: "login.html", chunks: ["login"], hash: true }), styleCss, styleLess ], mode: "development" }
打包后目錄文件:
對(duì)應(yīng)靜態(tài)文件
14、添加CSS3前綴通過(guò)postcss中的autoprefixer可以實(shí)現(xiàn)將CSS3中的一些需要兼容寫法的屬性添加響應(yīng)的前綴,這樣省去我們不少的時(shí)間
npm i postcss-loader autoprefixer -D // 安裝postcss-loader 和 autoprefixer
安裝后,我們還需要像webpack一樣寫一個(gè)config的配置文件,在項(xiàng)目根目錄下創(chuàng)建一個(gè)postcss.config.js文件,配置如下:
const Autoprefixer = require("autoprefixer") module.exports = { plugins : [ Autoprefixer ] }
然后在webpack里配置postcss-loader,webapack.config.js完整代碼:
const path = require("path") const HtmlWebpackPlugin = require("html-webpack-plugin") const ExtractTextWebpackPlugin = require("extract-text-webpack-plugin") // 樣式處理 const styleCss = new ExtractTextWebpackPlugin("./css/style.css") const styleLess = new ExtractTextWebpackPlugin("./css/style2.css") module.exports = { entry: { main: "./src/index.js", login: "./src/login.js" }, output: { filename: "[name].js", path: path.resolve(__dirname, "dist") }, module: { rules: [ { test: /.css$/, use: styleCss.extract({ use: ["css-loader", "postcss-loader"], // 配置postcss-loader fallback: "style-loader", publicPath: "../" }) }, { test: /.less$/, use: styleLess.extract({ use: ["css-loader", "less-loader"], fallback: "style-loader" }) }, { test: /.(jpe?g|png|gif)$/, use: [ { loader: "url-loader", options: { limit: 8192, outputPath: "images", name: "[name].[ext]" } } ] }, { test: /.(eot|ttf|woff|svg)$/, use: [ { loader: "file-loader", options: { outputPath: "iconfont" } } ] }, { test: /.(htm|html)$/, use: "html-withimg-loader" } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", filename: "index.html", chunks: ["main"], hash: true }), new HtmlWebpackPlugin({ template: "./src/login.html", filename: "login.html", chunks: ["login"], hash: true }), styleCss, styleLess ], mode: "development" }
index.js添加測(cè)試元素
樣式表style.css,簡(jiǎn)單書寫了animation動(dòng)畫效果,沒有添加兼容瀏覽器的前綴
/* style.css */ @charset "utf-8"; .logo { display: block; width: 222px; height: 222px; background: url(../images/logo.png) no-repeat; } .color-red { color: #f00; } .test-css3 { position: absolute; left: 500px; top: 0; width: 100px; height: 100px; background-color: #f00; animation: myfirst 5s linear 2s infinite alternate running; } @keyframes myfirst { 0% { background: #f00; left: 500px; top: 0; } 25% { background: #ff0; left: 900px; top: 0; } 50% { background: #f0f; left: 900px; top: 400px; } 75% { background: #000; left: 500px; top: 400px; } 100% { background: #0f0; left: 500px; top: 0; } }
執(zhí)行npm run dev 后生成的style.css代碼自動(dòng)添加了-webkit-前綴
15、轉(zhuǎn)義ES6在實(shí)際開發(fā)中,我們?cè)诖罅康氖褂弥鳨S6及之后的api去寫代碼,這樣會(huì)提高我們寫代碼的速度,不過(guò)由于低版本瀏覽器的存在,不得不需要轉(zhuǎn)換成兼容的代碼,于是就有了常用的Babel。
bable可以將ES6代碼轉(zhuǎn)義ES5代碼,安裝如下:
npm i babel-core babel-loader babel-preset-env babel-preset-stage-0 -D
babel兼容ES6和草案api,通過(guò)一個(gè).babelrc文件來(lái)配置一下,對(duì)這些版本的支持
// .babelrc { "presets": ["env", "stage-0"] // 從右向左解析 }
我們?cè)僭趙ebpack里配置一下babel-loader既可以做到代碼轉(zhuǎn)成ES5了
module.exports = { module: { rules: [ { test:/.js$/, use: "babel-loader", include: /src/, // 只轉(zhuǎn)化src目錄下的js exclude: /node_modules/ // 排除掉node_modules,優(yōu)化打包速度 } ] } }
添加本部分配置,完整wabpack.config.js代碼:
const path = require("path") const HtmlWebpackPlugin = require("html-webpack-plugin") const ExtractTextWebpackPlugin = require("extract-text-webpack-plugin") const CleanWebpackPlugin = require("clean-webpack-plugin") // 樣式處理 const styleCss = new ExtractTextWebpackPlugin("./css/style.css") const styleLess = new ExtractTextWebpackPlugin("./css/style2.css") module.exports = { entry: { main: "./src/index.js", login: "./src/login.js" }, output: { filename: "[name].js", path: path.resolve(__dirname, "dist") }, module: { rules: [ { test: /.css$/, use: styleCss.extract({ use: ["css-loader", "postcss-loader"], fallback: "style-loader", publicPath: "../" // 樣式根據(jù)相對(duì)路徑引用到圖片資源 }) }, { test: /.less$/, use: styleLess.extract({ use: ["css-loader", "less-loader"], fallback: "style-loader" }) }, { test: /.js$/, use: "babel-loader", include: "/src/", exclude: "/node_modules/" }, { test: /.(jpe?g|png|gif)$/, use: [ { loader: "url-loader", options: { limit: 8192, outputPath: "images", // 圖片輸出路徑 name: "[name].[ext]" } } ] }, { test: /.(eot|ttf|woff|svg)$/, use: [ { loader: "file-loader", options: { outputPath: "iconfont" // 打包到指定文件夾 } } ] }, { test: /.(htm|html)$/, use: "html-withimg-loader" // 引入html-withimg-loader,將圖片轉(zhuǎn)化為base64圖片 } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", filename: "index.html", chunks: ["main"], // 對(duì)應(yīng)關(guān)系,index.js對(duì)應(yīng)的是index.html hash: true // 在html模板中自動(dòng)添加?20位哈希值 }), new HtmlWebpackPlugin({ template: "./src/login.html", filename: "login.html", chunks: ["login"], // 對(duì)應(yīng)關(guān)系,index.js對(duì)應(yīng)的是index.html hash: true // 在html模板中自動(dòng)添加?20位哈希值 }), styleCss, styleLess, new CleanWebpackPlugin("dist") ], mode: "development" }16、啟動(dòng)靜態(tài)服務(wù)器和熱更新
A.啟動(dòng)靜態(tài)服務(wù)
啟動(dòng)一個(gè)靜態(tài)服務(wù)器,默認(rèn)會(huì)自動(dòng)刷新,就是說(shuō)你對(duì)html,css,js文件做了修改并保存后,瀏覽器會(huì)默認(rèn)刷新一次展現(xiàn)修改后的效果
module.exports = { devServer: { contentBase: "./dist", host: "localhost", // 默認(rèn)是localhost port: 8080, // 端口 open: true, // 自動(dòng)打開瀏覽器 // hot: true // 開啟熱更新 } }
此時(shí)我們要對(duì)pakage.json文件進(jìn)行修改:
"scripts": { "test": "echo "Error: no test specified" && exit 1", "build": "webpack --mode production", "dev": "webpack-dev-server --mode development --open" // 使用webpack-dev-server }
執(zhí)行npm run dev 會(huì)自動(dòng)打開默認(rèn)瀏覽器,打開http://localhost:8080頁(yè)面,html,css,js修改保存后頁(yè)面會(huì)自動(dòng)實(shí)時(shí)更新。
之前各部分我們每次執(zhí)行npm run dev都會(huì)在根目錄生成靜態(tài)文件目錄dist,啟動(dòng)靜態(tài)服務(wù)器,生成dist會(huì)儲(chǔ)存到內(nèi)存當(dāng)中,根目錄下不再生成dist文件夾。
B.熱更新
在配置devServer的時(shí)候,如果hot為true,就代表開啟了熱更新
module.exports = { devServer: { contentBase: "./dist", host: "localhost", // 默認(rèn)是localhost port: 8080, // 端口 open: true, // 自動(dòng)打開瀏覽器 hot: true // 開啟熱更新 } }
但是熱更新是指定某個(gè)js文件的更新,只需在指定的js文件添加以下代碼,表示本文件實(shí)現(xiàn)熱更新,修改文件后手動(dòng)刷新頁(yè)面,會(huì)看到修改后的內(nèi)容;如果不添加以下代碼,js文件還是自動(dòng)刷新
if (module.hot) { // 實(shí)現(xiàn)熱更新 module.hot.accept(); }
熱更新和自動(dòng)刷新的區(qū)別:
js文件被檢測(cè)到module.hot,就實(shí)現(xiàn)熱更新,檢測(cè)不到就是自動(dòng)刷新;
熱更新需要手動(dòng)刷新獲取修改后效果,自動(dòng)刷新是修改保存,頁(yè)面自動(dòng)更新。
完整webpack.config.js代碼:
const path = require("path") const webpack = require("webpack") // 引入webpack const HtmlWebpackPlugin = require("html-webpack-plugin") const ExtractTextWebpackPlugin = require("extract-text-webpack-plugin") const CleanWebpackPlugin = require("clean-webpack-plugin") // 樣式處理 const styleCss = new ExtractTextWebpackPlugin("./css/style.css") const styleLess = new ExtractTextWebpackPlugin("./css/style2.css") module.exports = { entry: { main: "./src/index.js", login: "./src/login.js" }, output: { filename: "[name].js", path: path.resolve(__dirname, "dist") }, module: { rules: [ { test: /.css$/, use: styleCss.extract({ use: ["css-loader", "postcss-loader"], fallback: "style-loader", publicPath: "../" }) }, { test: /.less$/, use: styleLess.extract({ use: ["css-loader", "less-loader"], fallback: "style-loader" }) }, { test: /.js$/, use: "babel-loader", include: "/src/", exclude: "/node_modules/" }, { test: /.(jpe?g|png|gif)$/, use: [ { loader: "url-loader", options: { limit: 8192, outputPath: "images", name: "[name].[ext]" } } ] }, { test: /.(eot|ttf|woff|svg)$/, use: [ { loader: "file-loader", options: { outputPath: "iconfont" } } ] }, { test: /.(htm|html)$/, use: "html-withimg-loader" } ] }, plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", filename: "index.html", title: "首頁(yè)測(cè)試", chunks: ["main"], hash: true }), new HtmlWebpackPlugin({ template: "./src/login.html", filename: "login.html", title: "登錄頁(yè)測(cè)試", chunks: ["login"], hash: true }), styleCss, styleLess, new CleanWebpackPlugin("dist"), new webpack.HotModuleReplacementPlugin() ], devServer: { contentBase: path.join(__dirname, "dist"), host: "localhost", port: 8080, open: true, hot: true // 實(shí)現(xiàn)頁(yè)面熱更新 }, resolve: { extensions: [".js", ".json", ".css"] }, mode: "development" }
index.js文件代碼:
import "./css/style.css" import "./less/style.less" import "./iconfont/iconfont.css" import imgUrl from "./images/pic.jpg" // 引入圖片 const img = new Image() img.src = imgUrl document.body.appendChild(img) // document.write(imgUrl) // "./images/logo.png" document.write("17、resolve解析Hello webpack!
測(cè)試第二個(gè)css樣式是否引入
") if (module.hot) { module.hot.accept() }
在webpack的配置中,resolve我們常用來(lái)配置別名和省略后綴名
module.exports = { resolve: { // 別名 alias: { $: "./src/jquery.js" }, // 省略后綴 extensions: [".js", ".json", ".css"] }, }
未完待續(xù)
參考鏈接:
1、https://juejin.im/post/5adea0...
2、https://www.cnblogs.com/cisum...
3、https://www.cnblogs.com/golov...
4、https://www.webpackjs.com/loa...
5、https://www.cnblogs.com/golov...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/101245.html
摘要:前段時(shí)間又發(fā)布了新版本我接觸的時(shí)候已經(jīng)版本了支持的版本必須打包速度大小比較以及粗淺的試了一下下圖所示,黃色為版本綠色為我寫的配置,跟基本相似,具體不同下面會(huì)介紹藍(lán)色是自帶的模式紅色為具體大小速度大家可以比較一下,還是很給力的關(guān)于配置方面,應(yīng) 前段時(shí)間webpack又發(fā)布了新版本webpack4我接觸的時(shí)候已經(jīng)4.1版本了node支持的版本必須node: >=6.11.5 webpack...
摘要:一前言文章介紹了一個(gè)現(xiàn)代化的項(xiàng)目的環(huán)境是什么樣的。其中一個(gè)就是引用路徑的問(wèn)題。擴(kuò)展將單獨(dú)打包詳細(xì)介紹見這是一個(gè)插件,可以簡(jiǎn)化創(chuàng)建文件以便為包提供服務(wù)。兩種環(huán)境的配置在中都支持的配置具體的默認(rèn)配置查詢可以移步這里的默認(rèn)設(shè)置。 一 前言 文章介紹了一個(gè)現(xiàn)代化的項(xiàng)目的webpack4環(huán)境是什么樣的。這里只是介紹了基礎(chǔ)的功能,如果需要詳細(xì)的相關(guān)只是可以去webpack官網(wǎng)去查閱。代碼地址:gi...
摘要:比如傳遞給時(shí),使用。為所有的及其預(yù)處理文件開啟。在生產(chǎn)環(huán)境下為和使用在多核機(jī)器下會(huì)默認(rèn)開啟。是否使用分割供應(yīng)的包也可以是一個(gè)在包中引入的依賴的顯性的數(shù)組。查閱配置行為。 之前因?yàn)閜arcel的出現(xiàn),webpack也跟進(jìn)了零配置vue-cli自然也不能落下,cli3.0也升級(jí)到webpack4,并增加許多新特性 安裝并創(chuàng)建一個(gè)項(xiàng)目 支持npm和yarn npm install -g @v...
摘要:適用于主要入口頁(yè)面生成多頁(yè),子頁(yè)面和次要頁(yè)面使用單頁(yè)形式的項(xiàng)目。文件用來(lái)存放固定的數(shù)據(jù),而文件可更加自由的處理并返回?cái)?shù)據(jù)。 VUE2的單頁(yè)應(yīng)用框架有人分享了,多頁(yè)應(yīng)用框架也有人分享了,這里分享一個(gè)單頁(yè)+多頁(yè)的混合應(yīng)用框架吧,node.js寫了一個(gè)簡(jiǎn)單的mock服務(wù)也集成在里面,整體初現(xiàn)雛形,還有很多需要優(yōu)化和改善的地方。。。 項(xiàng)目結(jié)構(gòu) │ ├─build ...
摘要:技術(shù)前端布局推進(jìn)劑間距規(guī)范化利用變量實(shí)現(xiàn)令人震驚的懸浮效果很棒,但有些情況不適用布局說(shuō)可能是最全的圖片版學(xué)習(xí)網(wǎng)格布局使用的九大誤區(qū)圖解布局布局揭秘和中新增功能探索版本迭代論基礎(chǔ)談?wù)雇麑?duì)比探究繪圖中撤銷功能的實(shí)現(xiàn)方式即將更改的生命周期幾道高 技術(shù) CSS 前端布局推進(jìn)劑 - 間距規(guī)范化 利用CSS變量實(shí)現(xiàn)令人震驚的懸浮效果 Flexbox 很棒,但有些情況不適用 CSS布局說(shuō)——可能是最...
閱讀 1754·2021-11-25 09:43
閱讀 2700·2019-08-30 15:53
閱讀 1852·2019-08-30 15:52
閱讀 2925·2019-08-29 13:56
閱讀 3350·2019-08-26 12:12
閱讀 596·2019-08-23 17:58
閱讀 2185·2019-08-23 16:59
閱讀 965·2019-08-23 16:21