最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

webpack多入口文件頁(yè)面打包配置詳解

 更新時(shí)間:2018年01月09日 11:46:21   作者:清夜  
本篇文章主要介紹了webpack多入口文件頁(yè)面打包配置詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

大多數(shù)情況下,我們使用 webpack來(lái)打包單頁(yè)應(yīng)用程序,這個(gè)時(shí)候只需要配置一個(gè)入口,一個(gè)模板文件,但也不盡是如此,有時(shí)候也會(huì)碰到多頁(yè)面的項(xiàng)目,而且以我的經(jīng)驗(yàn)來(lái)看,這種情況出現(xiàn)的頻率還不低,例如項(xiàng)目比較大,無(wú)法進(jìn)行全局的把握,或者項(xiàng)目需要多次的更新迭代等,都適合做成多頁(yè)面程序,這就涉及到了 webpack的多頁(yè)面文件的打包配置問(wèn)題。

手動(dòng)配置

單頁(yè)應(yīng)用程序和多頁(yè)應(yīng)用程序的 webpack配置文件其實(shí)絕大部分都還是相同的,只不過(guò)多頁(yè)的配置需要在單頁(yè)配置的基礎(chǔ)上顧及到多個(gè)頁(yè)面罷了,loader、output、plugins這些基本都不需要改動(dòng),需要改動(dòng)的一般都是入口文件 entry,如果你用到了 抽離css樣式的插件 extract-text-webpack-plugin、自動(dòng)模板插件  html-webpack-plugin的話,那么還需要對(duì)這兩個(gè)插件進(jìn)行額外的改寫,大多數(shù)情況下,我們也都只需要改動(dòng)這三個(gè)地方,所以本文就只簡(jiǎn)單說(shuō)下這三個(gè)位置,如果在實(shí)際的項(xiàng)目中還有其他的地方需要改動(dòng),參照這三個(gè)位置即可。

示例的文件目錄如下:

 

entry

單頁(yè)應(yīng)用程序的入口配置一般如下所示:

entry: resolve(__dirname, "src/home/index.js")

這個(gè)配置就是指定 webpack從 /src/home/index.js這個(gè)文件開(kāi)始進(jìn)入,進(jìn)行一系列的打包編譯過(guò)程。

如果是多頁(yè)應(yīng)用程序,則需要多個(gè)入口文件,例如:

entry: {
 home: resolve(__dirname, "src/home/index.js"),
 about: resolve(__dirname, "src/about/index.js")
}

這樣,整個(gè)項(xiàng)目就有了兩個(gè)入口 home和 about

extract-text-webpack-plugin

extract-text-webpack-plugin 插件主要是為了抽離css樣式,防止將樣式打包在 js中引起頁(yè)面樣式加載錯(cuò)亂的現(xiàn)象,單頁(yè)程序中,一般這樣使用此插件:

plugins: [
 new ExtractTextPlugin('style.[contenthash].css')
]

而到了多頁(yè)程序,因?yàn)榇嬖诙鄠€(gè)入口文件以及對(duì)應(yīng)的多個(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è)面中當(dāng)然也是可以的,但顯然是不合理的,這只會(huì)增加冗余代碼,還可能會(huì)導(dǎo)致不可預(yù)測(cè)的樣式覆蓋等問(wèn)題,所以需要對(duì)下面這種 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è)面都有各自單獨(dú)的 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īng)用程序和多頁(yè)應(yīng)用程序中的 webpack配置沒(méi)什么區(qū)別

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è)面,就對(duì)每個(gè)頁(yè)面進(jìn)行上述配置即可。

自動(dòng)配置

上述的配置代碼已經(jīng)可以滿足多頁(yè)面開(kāi)發(fā)需求了,但是有一點(diǎn)似乎有些遺憾,那就是每增加一個(gè)頁(yè)面,就需要更新一遍 entry、extract-text-webpack-plugin、HtmlWebpackPlugin的配置,雖然只是幾行代碼的問(wèn)題,而且基本上都是復(fù)制粘貼沒(méi)什么難度,但畢竟代碼再少也需要過(guò)問(wèn),并且需要改的地方比較多,倉(cāng)促之下可能還會(huì)遺漏,要是能一勞永逸,寫一遍代碼,無(wú)論以后增刪頁(yè)面都不需要過(guò)問(wèn)就好了。

稍微觀察下這個(gè)目錄就可以發(fā)現(xiàn),這個(gè)目錄結(jié)構(gòu)其實(shí)是很有規(guī)律的:

 

每個(gè)頁(yè)面都是 src/目錄下的一個(gè)文件夾,這個(gè)文件夾中有兩個(gè)子目錄,分別存放這個(gè)頁(yè)面的模板 html,樣式文件 css,還有一個(gè)入口文件 index.js

既然有規(guī)則,那么肯定是可以進(jìn)行程序編碼的,如果按照這種規(guī)則,每個(gè)頁(yè)面都是 ./src下的一個(gè)目錄,目錄名即為頁(yè)面名,并且這個(gè)目錄中的結(jié)構(gòu)也都是相同的,那么可以通過(guò)一個(gè)通用方法來(lái)獲取所有的頁(yè)面名稱(例如 home、about),這個(gè)通用方法的一個(gè)示例如下:

function getEntry () {
 let globPath = 'src/**/html/*.html'
 // (\/|\\\\) 這種寫法是為了兼容 windows和 mac系統(tǒng)目錄路徑的不同寫法
 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è)庫(kù),遍歷 .src/目錄下具有這種規(guī)律 src/**/html/*.html的子目錄,通過(guò)正則匹配出這個(gè)子目錄的名稱
獲取到了所有的頁(yè)面名稱,下面就好辦了。

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ú)論是在項(xiàng)目中添加頁(yè)面還是刪除頁(yè)面,都無(wú)需再對(duì)  webpack配置進(jìn)行手動(dòng)修改了,雖然開(kāi)始時(shí)開(kāi)起來(lái)似乎這種動(dòng)態(tài)的自動(dòng)配置代碼比較多,而且稍微復(fù)雜一點(diǎn),但是從長(zhǎng)期來(lái)看,絕對(duì)是一勞永逸的好做法。

另外,如果你的項(xiàng)目目錄結(jié)構(gòu)和我示例的目錄結(jié)構(gòu)不一樣,那么就需要你根據(jù)自己的目錄結(jié)構(gòu)對(duì)代碼進(jìn)行少許的修改,但整體解決問(wèn)題的方法是不變的,一個(gè)易于維護(hù)的項(xiàng)目,目錄結(jié)構(gòu)都該是有律可循的。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

萍乡市| 广平县| 福鼎市| 阜新市| 四川省| 宁夏| 兴隆县| 凌源市| 望城县| 大竹县| 云浮市| 沅江市| 射阳县| 奉化市| 阿克| 双柏县| 马关县| 长泰县| 通山县| 行唐县| 聂拉木县| 固阳县| 旺苍县| 扎兰屯市| 涿州市| 鄂州市| 奎屯市| 太湖县| 三明市| 天全县| 阿合奇县| 论坛| 吉安市| 尼勒克县| 张家港市| 太白县| 库车县| 灵寿县| 石楼县| 卓资县| 斗六市|