- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) >
- webpack多入口文件頁(yè)面如何打包配置
這篇文章主要介紹webpack多入口文件頁(yè)面如何打包配置,文中介紹的非常詳細,具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
手動(dòng)配置
單頁(yè)應用程序和多頁(yè)應用程序的 webpack配置文件其實(shí)絕大部分都還是相同的,只不過(guò)多頁(yè)的配置需要在單頁(yè)配置的基礎上顧及到多個(gè)頁(yè)面罷了,loader、output、plugins這些基本都不需要改動(dòng),需要改動(dòng)的一般都是入口文件 entry,如果你用到了 抽離css樣式的插件 extract-text-webpack-plugin、自動(dòng)模板插件 html-webpack-plugin的話(huà),那么還需要對這兩個(gè)插件進(jìn)行額外的改寫(xiě),大多數情況下,我們也都只需要改動(dòng)這三個(gè)地方,所以本文就只簡(jiǎn)單說(shuō)下這三個(gè)位置,如果在實(shí)際的項目中還有其他的地方需要改動(dòng),參照這三個(gè)位置即可。
示例的文件目錄如下:
entry
單頁(yè)應用程序的入口配置一般如下所示:
entry: resolve(__dirname, "src/home/index.js")
這個(gè)配置就是指定 webpack從 /src/home/index.js這個(gè)文件開(kāi)始進(jìn)入,進(jìn)行一系列的打包編譯過(guò)程。
如果是多頁(yè)應用程序,則需要多個(gè)入口文件,例如:
entry: { home: resolve(__dirname, "src/home/index.js"), about: resolve(__dirname, "src/about/index.js") }
這樣,整個(gè)項目就有了兩個(gè)入口 home和 about
extract-text-webpack-plugin
extract-text-webpack-plugin 插件主要是為了抽離css樣式,防止將樣式打包在 js中引起頁(yè)面樣式加載錯亂的現象,單頁(yè)程序中,一般這樣使用此插件:
plugins: [ new ExtractTextPlugin('style.[contenthash].css') ]
而到了多頁(yè)程序,因為存在多個(gè)入口文件以及對應的多個(gè)頁(yè)面,每個(gè)頁(yè)面都有自己的 css樣式,所以需要為每個(gè)頁(yè)面各自配置一下:
plugins: [ new ExtractTextPlugin('home/[name].[contenthash].css'), new ExtractTextPlugin('about/[name].[contenthash].css') ]
除此之外還需要注意一點(diǎn),每個(gè)頁(yè)面也只需要自己的 css樣式,理論上把別的頁(yè)面 css樣式文件也打包到自己的頁(yè)面中當然也是可以的,但顯然是不合理的,這只會(huì )增加冗余代碼,還可能會(huì )導致不可預測的樣式覆蓋等問(wèn)題,所以需要對下面這種 loader配置進(jìn)行修改:
{ test: /\.css$/, loader: 'style!css!autoprefixer' }, { test: /\.scss$/, loaders: [ 'style', 'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]', 'sass', 'autoprefixer' ] },
上面的配置會(huì )把所有編譯出來(lái)的 css文件打包到同一個(gè)文件中,我們要做的就是把這些 css分離開(kāi),每個(gè)頁(yè)面都有各自單獨的 css樣式文件:
// 為每個(gè)頁(yè)面定義一個(gè) ExtractTextPlugin const homeExtractCss = new ExtractTextPlugin('home/[name].[contenthash].css') const aboutExtractCss = new ExtractTextPlugin('about/[name].[contenthash].css') // ... module: { rules: [ // 每個(gè)頁(yè)面的 ExtractTextPlugin 只處理這個(gè)頁(yè)面的樣式文件 { test: /src(\\|\/)home(\\|\/)css(\\|\/).*\.(css|scss)$/, use: homePageExtractCss.extract({ fallback: 'style-loader', use: ['css-loader', 'postcss-loader', 'sass-loader'] }) }, { test: /src(\\|\/)about(\\|\/)css(\\|\/).*\.(css|scss)$/, use: salePersonalCenterExtractCss.extract({ fallback: 'style-loader', use: ['css-loader', 'postcss-loader', 'sass-loader'] }) } ] } // ... // 每個(gè)頁(yè)面都有各自的 ExtractTextPlugin,所以需要都聲明一遍 plugins: [ homeExtractCss, aboutExtractCss ]
html-webpack-plugin
html-webpack-plugin插件的使用,在單頁(yè)應用程序和多頁(yè)應用程序中的 webpack配置沒(méi)什么區別
new HtmlWebpackPlugin({ filename: 'home/home.html', template: 'src/home/html/index.html', inject: true, minify: { removeComments: true, collapseWhitespace: true } }) new HtmlWebpackPlugin({ filename: 'about/about.html', template: 'src/about/html/index.html', inject: true, minify: { removeComments: true, collapseWhitespace: true } })
有幾個(gè)頁(yè)面,就對每個(gè)頁(yè)面進(jìn)行上述配置即可。
自動(dòng)配置
上述的配置代碼已經(jīng)可以滿(mǎn)足多頁(yè)面開(kāi)發(fā)需求了,但是有一點(diǎn)似乎有些遺憾,那就是每增加一個(gè)頁(yè)面,就需要更新一遍 entry、extract-text-webpack-plugin、HtmlWebpackPlugin的配置,雖然只是幾行代碼的問(wèn)題,而且基本上都是復制粘貼沒(méi)什么難度,但畢竟代碼再少也需要過(guò)問(wèn),并且需要改的地方比較多,倉促之下可能還會(huì )遺漏,要是能一勞永逸,寫(xiě)一遍代碼,無(wú)論以后增刪頁(yè)面都不需要過(guò)問(wèn)就好了。
稍微觀(guān)察下這個(gè)目錄就可以發(fā)現,這個(gè)目錄結構其實(shí)是很有規律的:
每個(gè)頁(yè)面都是 src/目錄下的一個(gè)文件夾,這個(gè)文件夾中有兩個(gè)子目錄,分別存放這個(gè)頁(yè)面的模板 html,樣式文件 css,還有一個(gè)入口文件 index.js
既然有規則,那么肯定是可以進(jìn)行程序編碼的,如果按照這種規則,每個(gè)頁(yè)面都是 ./src下的一個(gè)目錄,目錄名即為頁(yè)面名,并且這個(gè)目錄中的結構也都是相同的,那么可以通過(guò)一個(gè)通用方法來(lái)獲取所有的頁(yè)面名稱(chēng)(例如 home、about),這個(gè)通用方法的一個(gè)示例如下:
function getEntry () { let globPath = 'src/**/html/*.html' // (\/|\\\\) 這種寫(xiě)法是為了兼容 windows和 mac系統目錄路徑的不同寫(xiě)法 let pathDir = 'src(\/|\\\\)(.*?)(\/|\\\\)html' let files = glob.sync(globPath) let dirname, entries = [] for (let i = 0; i < files.length; i++) { dirname = path.dirname(files[i]) entries.push(dirname.replace(new RegExp('^' + pathDir), '$2')) } return entries }
借助 glob這個(gè)庫,遍歷 .src/目錄下具有這種規律 src/**/html/*.html的子目錄,通過(guò)正則匹配出這個(gè)子目錄的名稱(chēng)
獲取到了所有的頁(yè)面名稱(chēng),下面就好辦了。
entry
// entry: resolve(__dirname, "src/home/index.js") // 改為 entry: addEntry() //... function addEntry () { let entryObj = {} getEntry().forEach(item => { entryObj[item] = resolve(__dirname, 'src', item, 'index.js') }) return entryObj }
extract-text-webpack-plugin
// plugins: [ // new ExtractTextPlugin('home/[name].[contenthash].css'), // new ExtractTextPlugin('about/[name].[contenthash].css') //] // 改為 const pageExtractCssArray = [] getEntry().forEach(item => { pageExtractCssArray.push(new ExtractTextPlugin(item + '/[name].[contenthash].css')) }) // ... plugins: [...pageExtractCssArray]
module.rules樣式相關(guān)的兩個(gè)loaders刪掉,改為動(dòng)態(tài)添加:
getEntry().forEach((item, i) => { webpackconfig.module.rules.push({ test: new RegExp('src' + '(\\\\|\/)' + item + '(\\\\|\/)' + 'css' + '(\\\\|\/)' + '.*\.(css|scss)$'), use: pageExtractCssArray[i].extract({ fallback: 'style-loader', use: ['css-loader', 'postcss-loader', 'sass-loader'] }) }) }) // ... module.exports = webpackconfig
html-webpack-plugin
plugins中無(wú)需手動(dòng)初始化 html-webpack-plugin,改為動(dòng)態(tài)添加:
getEntry().forEach(pathname => { let conf = { filename: path.join(pathname, pathname) + '.html', template: path.join(__dirname, 'src', pathname, 'html', 'index.html') } webpackconfig.plugins.push(new HtmlWebpackPlugin(conf)) }) // ... module.exports = webpackconfig
完成了上述修改后,以后無(wú)論是在項目中添加頁(yè)面還是刪除頁(yè)面,都無(wú)需再對 webpack配置進(jìn)行手動(dòng)修改了,雖然開(kāi)始時(shí)開(kāi)起來(lái)似乎這種動(dòng)態(tài)的自動(dòng)配置代碼比較多,而且稍微復雜一點(diǎn),但是從長(cháng)期來(lái)看,絕對是一勞永逸的好做法。
另外,如果你的項目目錄結構和我示例的目錄結構不一樣,那么就需要你根據自己的目錄結構對代碼進(jìn)行少許的修改,但整體解決問(wèn)題的方法是不變的,一個(gè)易于維護的項目,目錄結構都該是有律可循的。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站