本質上,webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(module bundler)。當 webpack 處理應用程序時,它會遞歸地構建一個依賴關係圖(dependency graph),其中包含應用程序須要的每一個模塊,而後將全部這些模塊打包成一個或多個 bundle。
簡單說,webpack能夠看作是一個模塊打包機,主要做用就是: 分析你的項目結構,找到JavaScript模塊以及一些瀏覽器不能直接運行的拓展語言(sass、less、typescript等),而後將它們打包爲合適的格式以供瀏覽器使用。
webpack主要實現的功能:javascript
代碼轉換(如: ES6轉換ES五、sass和less轉換爲css等)
文件優化(如: 將模塊內容進行壓縮)
代碼分割(如: 多頁面應用公共模塊的抽離、路由懶加載)
模塊合併(如: 按照不一樣的功能將多個模塊合併爲一個模塊)
自動刷新(如: 啓動本地服務,代碼更新後進行自動刷新)
代碼校驗(如: 添加eslint進行代碼規範檢查)
自動發佈(如: 應用打包完成後,自動發佈)
在webpack 3中,webpack自己和它的CLI之前都是在同一個包中的,但在第4版以後,已經將二者分開來更好地管理它們,因此安裝webpack4以後的版本,要同時安裝webpack和webpack-clicss
注意,安裝webpack的時候, 必須進行本地安裝才能生效,不然會報錯,如:
可是全局安裝了也有一個好處,那就是 能夠在項目根目錄下直接執行webpack便可完成項目的打包,若是沒有進行全局安裝,那麼能夠經過npx直接執行項目本地安裝的模塊,即 npx webpack也能夠完成項目的打包。
webpack是支持零配置的,即不須要配置文件便可完成打包,其默認入口文件爲項目根目錄下的src目錄下的index.js文件,其默認出口爲項目根目錄下的dist目錄的main.jshtml
若是沒有給webpack添加配置文件,那麼webpack的打包能力就會很是弱,webpack執行的時候默認會加載項目根目錄下的webpack.config.js文件,注意, 該配置文件是一個js文件,而不是json文件,而且其是經過node去執行的,因此其徹底支持node語法,即node中能用的,在配置文件中均可以用
webpack配置文件必需要對外暴露一個對象,即經過module.exports進行對外暴露,其中的全部配置都必須寫在這個對外暴露的對象中。
① context
context屬性表示的是webpack的上下文目錄,配置入口文件的時候,若是入口文件使用的是相對路徑,那麼就是相對於context所在的目錄。java
context默認值爲執行webpack命令時所在的當前工做目錄,一般是在項目根目錄下執行webpack命令,因此能夠認爲其值默認爲項目根目錄,因此若是入口文件路徑寫成相對路徑,最好將context配置成context: path.resolve(__dirname),以防止在非項目根目錄下執行webpack命令時找不到入口文件路徑而報錯。
② entrynode
entry用於配置模塊的入口文件,能夠配置多個,webpack將從入口文件開始搜索以及遞歸解析全部入口文件依賴的模塊,其是 必填的,若是配置文件中沒有entry則會報錯。entry的屬性值能夠是 表示路徑的單個字符串, 也能夠是數組,數組中的元素爲入口文件的路徑, 還能夠是對象,對象的屬性名爲入口文件的chunk名,即打包後輸出文件的名字,屬性值爲入口文件的路徑。注意,入口文件的路徑 能夠是絕對路徑, 也能夠是相對路徑,相對路徑默認是以 配置文件中的context屬性值表示的路徑
module.exports = { entry: "./foo.js" // 屬性值爲一個表示路徑的字符串 }
其輸出結果文件取決於配置文件的output配置,若是output.filename沒有配置,則默認輸出爲main.js,若是output.filename值爲指定的名稱,則輸出結果爲output.filename的屬性值
module.exports = { entry: [ "./foo.js", "./bar.js"] // 屬性值爲一個數組 }
其輸出結果文件也是取決於配置文件的output配置,只不過,其會將foo.js和bar.js一塊兒打包輸出爲一個文件,若是output.filename沒有配置,則默認輸出爲main.js,若是output.filename值爲指定的名稱,則輸出結果爲output.filename的屬性值
module.exports = { entry: { // 屬性值爲一個對象 a: "./src/bar.js", b: "./src/foo.js", c: "./src/index.js" } }
其輸出結果再也不取決於output.filename的配置,由於entry已經指定好了模塊輸出的chunk名,即會分別輸出a.js、b.js和c.js三個文件,而且此時 output.filename屬性值不能配置爲一個固定名稱的輸出文件,由於 入口文件有多個,必然輸出文件也會有多個
chunk和module的區別,兩者都是表示模塊,可是module能夠看作是具備獨立功能的小模塊,即 小塊,也就是打包以前,程序員編寫的一個一個的文件,每一個文件稱爲一個module;而chunk則能夠看作是由多個小module打包成的大模塊,即 大塊
③ output
output配置的是如何輸出最終想要的代碼,output是一個object。jquery
path: 用於配置打包後輸出文件的本地存放目錄,必須是絕對路徑,固然也能夠不配置,由於若是沒有配置path,那麼會自動在執行webpack命令時所在的目錄下自動建立dist目錄並將打包結果輸出到dist目錄下,與context的配置路徑無關webpack
module.exports = { output: { path: path.resolve(__dirname, "./dist") // 必須是絕對路徑 } }
filename: 用於配置輸出文件的名稱,若是隻有一個輸出文件,那麼能夠配置成靜態不變的文件名,如:程序員
module.exports = { output: { filename: "bundle.js" } }
可是,若是有多個chunk要輸出時,即入口文件配置了多個時,那麼filename就不能配置成靜態不變的了,就必須藉助模板和變量了,常見的兩個變量,如:
[name]: 能夠自動獲取到入口文件配置的chunk名稱;
[hash]: 能夠自動生成hash值,hash值的長度是能夠指定的,默認爲20位;web
module.exports = { output: { filename: "[name][hash:8].js" // 以入口文件設置的chunk做爲輸出名,而且指定hash值爲8位 } }
library和libraryTarget: 用於指定將模塊的輸出結果掛載到哪一個地方或者以什麼樣的方式導出庫(模塊輸出結果)。兩者一般要搭配一塊兒使用。
libraryTarget一般用於指定以何種方式導出庫,library一般用於指定接收庫的名稱。
咱們將入口的一個或多個js文件打包輸出後的結果也是一個js文件,在沒有配置library和libraryTarget的時候,這個輸出的js文件中包含了一個匿名自執行函數, 即輸出文件的執行結果沒有被任何東西接收,咱們引入輸出文件執行後不會獲得任何結果。 如:正則表達式
(function(){ console.log("foo"); return "foo"; // 雖然有返回值,可是匿名自執行函數執行完畢後拿不到任何結果 })(); // 咱們以var 變量 的方式來接收函數的返回值 var foo = (function(){ // 匿名自執行函數執行完畢後就會將函數返回值保存到foo變量上 console.log("foo"); return "foo"; })(); console.log(`foo is ${foo}`);
打包後的輸出文件的輸出結果(導出結果),就是入口文件的輸出結果(導出結果),即入口文件經過export、exports、module.exports等輸出(導出)的結果
var: 將libraryTarget設置爲var, 同時指定一個自定義的變量名來接收模塊的輸出,這個自定義的變量名就是library的屬性值
module.exports = { output: { filename: "bundle.js", path: path.resolve(__dirname, "./dist/"), libraryTarget: "var", library: "test" } }
模塊的輸出結果將會賦值給test變量,其輸出文件bundle.js內容大體以下:
var test = (function(modules){ return result; // 返回值result將會被賦值給test變量 })();
commonjs: 將libraryTarget設置爲commonjs, 即經過commonjs規範導出,同時指定一個自定義的變量名來接收模塊的輸出,這個自定義的變量名就是library的屬性值, 只不過這個自定義的變量名是exports的屬性名,如:
module.exports = { output: { filename: "bundle.js", path: path.resolve(__dirname, "./dist/"), libraryTarget: "commonjs", library: "test" } }
模塊的輸出結果將會賦值給exports["test"]上,其輸出文件bundle.js內容大體以下:
exports["test"] = (function(modules){ return result; // 返回值result將會被賦值給exports["test"] })();
commonjs2: 將libraryTarget設置爲commonjs2,即經過commonjs2規範導出,此時library的配置將無心義,由於commonjs2的輸出是固定的module.exports,因此不須要指定library了,如:
module.exports = { output: { filename: "bundle.js", path: path.resolve(__dirname, "./dist/"), libraryTarget: "commonjs2" } }
模塊的輸出結果將會被賦值到module.exports上,其輸出文件bundle.js內容大體以下:
module.exports = (function(modules){ return result; // 返回值result將會被賦值給module.exports })();
commonjs和commonjs2的區別在於,commonjs只能使用exports進行導出,而commonjs2在commonjs的基礎上增長了module.exports進行導出;
this: 將libraryTarget設置爲this, 那麼此時library配置的變量名將做爲this的屬性名來接收模塊的導出結果,如:
module.exports = { output: { filename: "bundle.js", path: path.resolve(__dirname, "./dist/"), libraryTarget: "this", library: "test" } }
模塊的輸出結果將會被賦值到this["test"] 上,其輸出文件bundle.js內容大體以下:
this["test"] = (function(modules){ return result; // 返回值result將會被賦值給this["test"] })();
同理libraryTarget的屬性值還能夠是window、global,這裏就不一一列舉了。
publicPath
publicPath用於配置打包資源發佈到線上時服務器的url地址,打包完成後,html文件中若是引入了js、image、css等資源,那麼都會在前面加上publicPath所表示的路徑
module.exports = { output: { filename: "bundle.js", path: path.resolve(__dirname, "./dist/"), publicPath: "http://www.lihb.com/" } }
// index.html
<!DOCTYPE html> <html lang="en"> <body> <script type="text/javascript" src="http://www.lihb.com/index.js"></script></body> </html>
webpack打包輸出後的結果默認是一個匿名自執行函數,匿名自執行函數傳遞的參數爲一個對象,對象的屬性名爲入口文件的路徑名,屬性值爲一個函數,函數體內部經過會執行eval(),eval()方法的參數爲入口文件的內容字符串,而這個匿名自執行函數,內部有一個自定義的__webpack_require__方法,該方法須要傳入入口文件的路徑名做爲參數,匿名自執行函數執行完成後會返回__webpack_require__的結果,而__webpack_require__()方法內部執行的時候,會首先建立一個module對象,module對象裏面有exports屬性,屬性值爲一個空的對象,用於接收入口文件的模塊輸出,如:
(function(modules) { function __webpack_require__(moduleId) { // 傳入入口文件的路徑 var module = installedModules[moduleId] = { // 建立一個module對象 i: moduleId, l: false, exports: {} // exports對象用於保存入口文件的導出結果 }; modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // 執行入口文件 return module.exports; // 返回模塊輸出結果 } return __webpack_require__(__webpack_require__.s = "./src/bar.js"); // 返回入口文件 })({ "./src/bar.js": (function(module, exports) { eval("module.exports = \"bar\";"); }) });
因此無論入口文件是以ES6模塊的方式輸出仍是以commonjs模塊的方式輸出, 最終入口文件的模塊輸出結果都會被綁定到__webpack_require__方法中定義的module對象的exports屬性上,只不過,若是是以commonjs的方式輸出,那麼 入口文件的輸出結果將會直接替換掉__webpack_require__方法中定義的module對象的exports屬性;若是是以ES6模塊的方式輸出,則是 在__webpack_require__方法中定義的module對象的exports屬性值中添加一個default屬性或者具體變量名來保存入口文件的輸出。
爲了更方便調試,咱們須要用到webpack的本地http服務器功能,要想使用webpack提供的Web服務器功能,咱們須要安裝webpack-dev-server模塊,webpack-dev-server會啓動一個web服務器用於實現網頁請求,也能夠監聽文件的變化自動刷新網頁。
webpack-dev-server模塊安裝完成後,咱們能夠在項目根目錄下運行 npx webpack-dev-server,其和webpack命令同樣,若是沒有配置文件,則使用內置默認配置進行打包輸出,若是有則使用配置文件中的配置,只不過其不會將打包結果輸出到指定的目錄中,由於webpack-dev-server會忽略配置文件中的output.path配置,其會將打包輸出結果保存到內存中。 webpack-dev-server啓動後會默認將啓動devServer時所在的目錄做爲根目錄,即執行npx webpack-dev-server命令時所在的目錄。
webpack提供了一個devServer屬性用於配置啓動的服務器的一些參數,固然webpack自己是沒法識別devServer屬性配置的,只有經過webpack-dev-server去啓動webpack時,devServer的配置纔會生效。
module.exports = { devServer: { port: 3000, // 讓devServer監聽3000端口 contentBase: "./dist", // 將當前項目的dist目錄做爲devServer的根目錄 progress: true, // 顯示打包進度條 compress: true // 是否啓用Gzip壓縮,默認爲false } }
webpackDevServer啓動後, 默認會自動監聽打包源文件的變化,若是修改了打包源文件,那麼會自動從新打包到內存,而且會自動刷新瀏覽器,可是 自動刷新瀏覽器功能必須將target設置成web,不然自動刷新功能將會失效,好比target爲node就沒法起做用。
在不使用插件的時候,webpack默認只能打包輸出js文件,若是咱們想要輸出其餘格式的文件到輸出目錄中,那麼咱們必須使用插件。webpack提供了一個plugins屬性用於配置使用到的插件,其屬性值爲一個數組,數組中的元素爲插件對象,一般插件都是一個類,咱們須要經過插件類來建立一個插件對象。
① html-webpack-plugin
該插件能夠指定一個html文件,webpack會將該html文件打包輸出到輸出目錄中,同時會將打包輸出後的文件自動插入到該html文件中,即讓該html文件自動引入打包後的js文件。
module.exports = { plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", // 要打包輸出哪一個文件,可使用相對路徑 filename: "index.html", // 打包輸出後該html文件的名稱 minify: { removeAttributeQuotes: true, // 去除html文件中的引號 collapseWhitespace: true // 合併空格,即將html進行單行顯示 }, hash: true // 向html文件中引入打包後的js時候帶上hash值 }) ] }
html插件中配置了hash爲true, 是在引入打包後的js的時候帶上hash值,如:
<script type="text/javascript" src="main.js?c7086a400fa368e84ad6"></script></body>
webpack默認將全部格式的文件都當作模塊進行處理,可是wepback默認只能處理js模塊。若是在js中經過require引入了其餘格式的模塊(文件),那麼webpack就必須經過安裝合適的模塊加載器,才能正確解析對應的模塊內容,webpack提供了一個module屬性,用於進行模塊解析器的配置,其屬性值爲一個對象,對象中有一個rules屬性,其屬性值爲一個數組,數組中的元素爲一個對象,該對象主要完成兩件事,匹配對應格式的文件,而且使用對應模塊加載器進行加載,匹配使用的是test屬性,屬性值爲一個正則表達式,【使用】使用的是use屬性,屬性值能夠是字符串也能夠是數組,若是隻有一個模塊加載器的時候,可使用字符串的形式,若是有多個模塊加載器的時候,那麼就須要使用數組的形式,固然,若是模塊加載器須要傳遞參數配置,那麼能夠將模塊加載器寫成對象的形式,經過loader屬性指定模塊加載器名稱,經過options屬性傳遞參數配置。
① 處理css樣式,須要使用到css-loader和style-loader。
首先須要安裝css-loader和style-loader。
css-loader必須同時和style-loader一塊兒使用才能正確加載css文件,一個負責加載,一個負責插入。css-loader負責加載css, 即在js文件中可以經過require的方式引入css,即加載和解析css,同時支持在css文件中使用@ import的方式引入其餘css文件,style-loader負責將加載並解析好的css文件插入到html文件中去,從名字能夠看出其是在html文件中生成style標籤來引入css文件,loader的執行順序是從右向左,因此必須先加載而後再插入
好比,打包入口文件index.js中經過require的方式引入了一個index.js文件,即require("./index.css"),那麼webpack須要進行以下配置:
module.exports = { module: { rules: [ { test: /\.css$/, // 匹配以.css結尾的文件 use: [ // 並交給css-loader和style-loader進行處理 { loader: "style-loader", // 以對象的形式配置loader options: { // 經過options給loader傳遞參數 insertAt: 'top' // 默認爲bottom, 將加載的css文件插入到head標籤的最上面,即優先級最低,會被覆蓋 } }, "css-loader" // 直接以字符串的形式配置loader ] } ] } }
打包輸出後,會 將index.css中的內容放到<style>標籤中,而且 將這個<style>標籤自動插入到index.html文件的<head>標籤的最底部,若是配置了insertAt: "top", 那麼就會插入到<head>標籤的最上面。
同理,咱們也能夠出來sass,即scss文件,要處理scss文件,咱們須要安裝sass-loader,而sass-loader須要配合node-sass一塊兒使用,安裝好sass-loader以後咱們只須要再添加一個rule,改爲匹配.scss結尾的模塊,處理sass和處理css都須要用到style-loader和css-loader,只不過處理sass還須要sass-loader,即須要用sass-loader將scss文件轉換爲css文件,在css-loader後加一個sass-loader便可。
① 抽離樣式
咱們經過css-loader和style-loader處理css樣式後是直接經過<style>標籤將解析後樣式插入到了html中,若是須要將css樣式抽離成一個單獨的css文件, 而且自動link進html文件中,那麼就須要mini-css-extract-plugin這個插件。
首先安裝mini-css-extract-plugin插件,而後建立插件對象,並進行相應的配置,主要就是filename,即 抽離出的css文件叫什麼名字
module.exports = { plugins: [ new MiniCssExtractPlugin({ filename: "css/index.css", // 抽離出的css文件叫什麼名字,前面可加路徑 }) ] }
filename屬性值中能夠添加上一個路徑,實現css資源的分類輸出,上面index.css文件就會輸出到輸出目錄下的css目錄下
插件安裝配置好以後還不行,由於還要對loader進行相應的配置,以前css文件是經過了style-loader處理的,而style-loader會將樣式經過<style>標籤的方式插入到html文件中,因此必須先移除style-loader,而後使用mini-css-extract-plugin這個插件提供的loader
module.exports = { module: { rules: [ { test: /\.css$/, // 匹配以.css結尾的文件 use: [ // 並交給css-loader和MiniCssExtractPlugin的loader進行處理 MiniCssExtractPlugin.loader, // 將css進行抽離 "css-loader" // 直接以字符串的形式配置loader ] }, ] } }
② 壓縮css
要想壓縮css,那麼須要用到optimize-css-assets-webpack-plugin插件,須要注意的是該插件並非配置到plugins屬性中,而是配置到optimization屬性中。
module.exports = { optimization: { minimizer: [new OptimizeCSSAssetsPlugin({})], // 壓縮css } }
咱們能夠經過修改mode爲production來壓縮咱們的js,可是當使用了optimize-css-assets-webpack-plugin插件後,那麼js的壓縮就會失效,咱們須要使用uglifyjs-webpack-plugin插件進行壓縮,如:
module.exports = { optimization: { minimizer: [ new OptimizeCSSAssetsPlugin({}), // 壓縮css new UglifyjsWebpackPlugin({ //壓縮js cache: true, parallel: true, sourceMap: true }) ], } }
使用uglifyjs-webpack-plugin插件後,mode的切換仍然是生效的了。
① 將ES6以上的高級語法特性轉換ES5
Babel是一個JavaScript的編譯器,能將ES6的代碼轉換爲ES5的代碼,咱們須要安裝babel-loader來處理咱們js文件,而其須要配合@babel/core模塊一塊兒使用,還要告訴babel當前要轉換的JS代碼中使用了哪些新特性,即預設,咱們使用包含當前全部最新ES語法特性的預設便可,@babel/preset-env。
module.exports = { module: { rules: [ { test: /\.js$/, use: [ { loader: "babel-loader", // 使用babel-loader進行處理js文件 options: { presets: ["@babel/preset-env"] // 用了最新的ES6語法預設 } } ] } ] } }
② 減小代碼冗餘
babel在轉換ES6語法的時候,會使用一些由ES5編寫的幫助函數來實現新語法的轉換。好比轉換class語法,就須要使用到classCallCheck()函數,若是多個文件中都使用到了Class語法,那麼每一個文件都會被注入classCallCheck()輔助函數,代碼就會變得很是冗餘,經過引入@babel/babel-plugin-transform-runtime插件就能夠在輸出文件中經過require的方式引入一個公共的classCallCheck()輔助函數,而後全部文件一塊兒使用便可減小代碼的冗餘。@babel/babel-plugin-transform-runtime插件須要配合@babel/runtime一塊兒使用,由於babel-plugin-transform-runtime插件引入的幫助函數,都存放在@babel/runtime中
module.exports = { module: { rules: [ { test: /\.js$/, use: [ { loader: "babel-loader", // 使用babel-loader進行處理js文件 options: { presets: ["@babel/preset-env"] // 用了最新的ES6語法預設 plugins: ["@babel/plugin-transform-runtime"] // 減小代碼冗餘插件 } } ] } ] } }
③ 轉換新的ES6API
babel默認只能轉換ES6的新語法,若是想要轉換一下ES6的新功能(Promise)、新接口(數組的includes方法)等,那麼須要使用到@babel/polyfill, 其工做原理是在全局對象或者內置對象中添加一下屬性或者方法,其使用方式爲: 一種是直接在js文件中require, 如: require("@babel/polyfill"); 另外一種是將"@babel/polyfill"做爲入口文件一塊兒打包成一個chunk,如:
module.exports = { entry: ['@babel/polyfill', "./src/index.js"] }
好比,使用了Promise,那麼打包輸出的文件中,能夠看到 全局對象global被添加了一個Promise屬性。
① 若是咱們的項目中使用到了第三方模塊,好比jquery,咱們直接在咱們的js模塊中引入jquery,那麼這個jquery只能在當前模塊中使用,而沒法暴露到全局變量window中,若是想要實現,自動將jquery暴露給全局變量,那麼須要引入expose-loader,其能夠做爲內聯loader直接在js中使用,也能夠做爲普通loader在配置文件中使用。
// index.js
import $ from "expose-loader?$!jquery"; console.log($); console.log(window.$); // 能夠獲取到jquery
或者在配置文件中引入
module.exports = { module: { rules: [ { test: require.resolve("jquery"), // 若是require的時候引入了jquery use: "expose-loader?$" // 那麼將$變量暴露到全局 } ] } }
expose-loader是將一個模塊的輸出暴露給全局變量( 不限於第三方模塊,任何模塊均可以),可是 具體是暴露給window和global取決於配置文件中target的配置,若是是node則暴露給global,若是是web則暴露給window。
② 咱們也能夠不直接在咱們的js文件中引入第三方模塊,就可使用他們,能夠經過webpack提供的providePlugin內置插件來實現,將第三方模塊注入到每一個模塊中,固然也能夠是其餘任何一個模塊,如:
new webpack.ProvidePlugin({ $: "jquery", foo: path.resolve(__dirname,"./src/foo.js") // 自定義模塊必須是模塊的絕對路徑不然沒法解析 })
咱們就能夠在任何一個模塊中使用$和foo變量了,由於他們被注入到了全部模塊中,可是全局變量中是沒法訪問到的
③ 以上兩種方式第三方模塊都會被打包輸出到咱們的最終輸出文件中,咱們一般是不但願將第三方模塊打包到咱們的輸出文件中的,由於會咱們能夠經過cdn的方式直接引入第三方模塊,這個時候咱們就須要告訴webpack哪些模塊不須要打包輸出,而且用運行環境中的全局變量進行替換,須要用到webpack提供的externals配置,如:
module.exports = { externals: { "jquery": "jQuery" // 排除jquery模塊打包,並用瀏覽器中的jQuery替換掉jquery } }
此時雖然js模塊中引入了jquery,可是也不會被打包到輸出文件中,而且html模板文件中直接經過cdn引入了jQuery,因此全局變量中也能夠直接訪問到jQuery
webpack是將全部文件都當作模塊進行處理的,因此圖片也被認爲是一個模塊,須要經過require或者import進行引入加載才能被正確打包輸出。
若是想要加載並解析圖片模塊,那麼必須使用合適的loader,解析圖片可使用file-loaer。如:
module.exports = { module: { rules: [ { test: /\.(png|jpg|gif)$/, use: "file-loader" // 用file-loader解析圖片模塊 } ] } }
圖片會被單獨打包出來放在輸出目錄中,可是輸出的圖片名稱會發生變化,以hash值做爲圖片文件名,若是在css文件中使用圖片,不須要經過require的方式,能夠直接經過url("圖片路徑")的方式,由於css-loader對url()進行了轉換,會轉換爲require的方式
若是想在html文件中直接使用<img/> 標籤引入圖片,那麼須要使用到html-withimg-loader來處理咱們的html文件,圖片一樣會被打包單獨輸出到輸出目錄中。
module.exports = { module: { rules: [ { test: /\.html$/, // 處理html文件 use: { loader: "html-withimg-loader", options: { min: false // 不去除html中的換行符 } } } ] } }
若是想將圖片打包成base64編碼格式,那麼須要使用到url-loader來處理咱們的圖片,url-loader其實包含了file-loader的功能,由於其能夠設置一個limit,限制圖片的大小,只有圖片的大小在limit範圍內纔會被打包爲base64編碼格式,超過limit則仍是單獨打包圖片到輸出目錄中
module.exports = { module: { rules: [ { test: /\.(png|jpg|gif)$/, use: { loader: "url-loader", // 用url-loader解析圖片模塊 options: { limit: 200 * 1024, // 限制圖片大小爲200kb內纔打包爲base64編碼格式 outputPath: "/img/", // 將圖片打包輸出到輸出目錄的img目錄下 publicPath: "http://www.lihb.com/" // 僅僅給輸出的圖片資源添加資源服務器存放地址 } } } ] } }
url-loader能夠配置一個outputPath將圖片輸出到指定目錄下面,實現資源的分類輸出。還能夠配置一個publicPath,在引入圖片資源的時候添加上圖片資源所在的服務器地址。