国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

webpack多入口文件頁面打包配置詳解

2019-11-19 14:33:31
字體:
來源:轉載
供稿:網友

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

手動配置

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

示例的文件目錄如下:

 

entry

單頁應用程序的入口配置一般如下所示:

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

這個配置就是指定 webpack從 /src/home/index.js這個文件開始進入,進行一系列的打包編譯過程。

如果是多頁應用程序,則需要多個入口文件,例如:

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

這樣,整個項目就有了兩個入口 home和 about

extract-text-webpack-plugin

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

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

而到了多頁程序,因為存在多個入口文件以及對應的多個頁面,每個頁面都有自己的 css樣式,所以需要為每個頁面各自配置一下:

plugins: [ new ExtractTextPlugin('home/[name].[contenthash].css'), new ExtractTextPlugin('about/[name].[contenthash].css')]

除此之外還需要注意一點,每個頁面也只需要自己的 css樣式,理論上把別的頁面 css樣式文件也打包到自己的頁面中當然也是可以的,但顯然是不合理的,這只會增加冗余代碼,還可能會導致不可預測的樣式覆蓋等問題,所以需要對下面這種 loader配置進行修改:

{  test: //.css$/,  loader: 'style!css!autoprefixer'},{  test: //.scss$/,  loaders: [   'style',   'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]',   'sass',   'autoprefixer'  ]},

上面的配置會把所有編譯出來的 css文件打包到同一個文件中,我們要做的就是把這些 css分離開,每個頁面都有各自單獨的 css樣式文件:

// 為每個頁面定義一個 ExtractTextPluginconst homeExtractCss = new ExtractTextPlugin('home/[name].[contenthash].css')const aboutExtractCss = new ExtractTextPlugin('about/[name].[contenthash].css')// ...module: {  rules: [   // 每個頁面的 ExtractTextPlugin 只處理這個頁面的樣式文件  {    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']    })   } ]}// ...// 每個頁面都有各自的 ExtractTextPlugin,所以需要都聲明一遍plugins: [  homeExtractCss,  aboutExtractCss]

html-webpack-plugin

html-webpack-plugin插件的使用,在單頁應用程序和多頁應用程序中的 webpack配置沒什么區別

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  } })

有幾個頁面,就對每個頁面進行上述配置即可。

自動配置

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

稍微觀察下這個目錄就可以發現,這個目錄結構其實是很有規律的:

 

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

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

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

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樣式相關的兩個loaders刪掉,改為動態添加:

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中無需手動初始化 html-webpack-plugin,改為動態添加:

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

完成了上述修改后,以后無論是在項目中添加頁面還是刪除頁面,都無需再對  webpack配置進行手動修改了,雖然開始時開起來似乎這種動態的自動配置代碼比較多,而且稍微復雜一點,但是從長期來看,絕對是一勞永逸的好做法。

另外,如果你的項目目錄結構和我示例的目錄結構不一樣,那么就需要你根據自己的目錄結構對代碼進行少許的修改,但整體解決問題的方法是不變的,一個易于維護的項目,目錄結構都該是有律可循的。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 海晏县| 浑源县| 河曲县| 临海市| 仁寿县| 广德县| 桐城市| 伊通| 中牟县| 石家庄市| 永靖县| 沭阳县| 乐至县| 乐都县| 措勤县| 靖边县| 辽宁省| 开原市| 泰来县| 司法| 北京市| 定日县| 弥渡县| 龙江县| 东至县| 渑池县| 和平县| 离岛区| 涞源县| 永嘉县| 长海县| 精河县| 百色市| 榆中县| 南和县| 贺兰县| 寿阳县| 云和县| 抚宁县| 宣武区| 五台县|