webpack 構建多頁面應用

2022-09-18 14:12:12 字數 4802 閱讀 6675

如何使用webpack構建多頁面應用,這是乙個我一直在想和解決的問題。網上也給出了很多的例子,很多想法。猛一看,覺得有那麼點兒意思,但仔細看也就那樣。

使用webpack這個構建工具,可以使我們少考慮很多的問題。

我們常見的單頁面應用只有乙個頁面,它考慮問題,解決問題圍繞著中心化去解決,因此很多麻煩都迎刃而解。如果你使用過vue.js,那麼想必你一定用過vue-router,vuex,它們就是典型的中心化管理模式,當然還有很多,這裡不一一枚舉了。

而多頁面應用,我們不能再按照中心化模式的路走了,因為行不通,這也是很多人認為多頁面應用不好做,或者乾脆認為webapck只能做單頁面應用,而不能做多頁面應用的原因。

所以,我要說明的第一點兒是:不要用做單頁面應用的思維來做多頁面應用。

單頁面的模組共享,其實是**塊在同乙個頁面的不同位置的重複出現;而多頁面應用的**塊兒共享需要實現的不僅是同乙個頁面的共享,還要做到跨頁面的共享。所以,第乙個要解決的問題是:不同頁面的**塊共享如何實現?

單頁面的路由管理,其實是根據使用者的觸發條件來實現不同的**塊的顯隱;而多頁面應用的路由管理則不然,它實現的是頁面的跳轉。所以,第二個要解決的問題是:所頁面應用的導航該如何做?

單頁面的狀態管理,很受開發者喜好。單頁面是乙個頁面,所以頁面中的資料狀態的管理操作起來還算得心應手,那麼多頁面應用的呢,顯然依靠它自身很難實現。

所以,第三個要解決的問題是:多頁面應用的狀態管理如何做?

注:這個問題問的其實有點兒傻,如果你做的是dom操作的多頁面兒應用,就不用做狀態管理了。如果你還是使用想vue.js這樣的庫,你就需要考慮要不要再用做多頁面的狀態管理了,因為此法兒就是為單頁面應用做的,多頁面兒行不通。

入口(entry):

webpack對入口不僅可以定義單個檔案,也可以定義多個檔案。

熟悉當頁面應用開發的對於下面的**應該不會陌生吧?

module.exports =
我第一次接觸真正的單頁面應用專案使用的就是angualrjs,使用的構建工具使webapck+gulp,其中的webpack.config.js中的看到的入口檔案**就是它。

後來,接觸到的是陣列形式,**如下:

module.exports =
這樣,將bootstrap和入口檔案一起引用,就可以在任何乙個**塊中使用boostrap。

再後來,接觸到的是物件形式,**如下:

module.exports =
這樣做的目的是為了給輸出的檔案指定特定的名字。

再後來,就是做多頁面應用,就需要用到如下的**:

module.exports = 

}

為了引入第三方庫,我們可以像如下這樣做:

module.exports = 

}

但為了共享模組**,我們需要像下面這這樣做:

const commonschunkplugin = require('webpack').optimization.commonschunkplugin

module.exports = ,

plugins: [

new commonschunkplugin()

]}

這樣型就會形成如下所示的專案目錄結構:

├── src

│ ├── common // 公用的模組

│ │ ├── a.js

│ │ ├── b.js

│ │ ├── c.js

│ │ ├── d.js

│ ├── uttils // 工具

│ │ ├── load.js // 工具**load.js

│ ├── index.js // 主模組index.js (包含a.js, b.js, c.js, d.js)

│ ├── aboutus.js // 主模組aboutus.js (包含a.js, b.js)

│ ├── contactus.js // 主模組contactus.js (包含a.js, c.js)

├── webpack.config.js // css js 和資源

├── package.json

├── yarn.lock

但是這個內建外掛程式的侷限性比較大。正如上面所使用的那樣,它只會提取chunks選項所匹配的模組共有的**塊。就如同上面**表示的那樣,它只會提取pindex, aboutus, contactus共有的**塊loadsh,而不會提取index, contactus共有的**塊load.js

當然,一般的第三方庫,我們也不這樣使用,而是像下面這樣使用:

const commonschunkplugin = require('webpack').optimization.commonschunkplugin

module.exports = ,

externals: ,

plugins: [

new commonschunkplugin()

]}

對於web應用最終的目的是:匹配生成不同的html頁面。

這裡我們要使用的就是html-webpack-plugin

首先,需要安裝html-webpack-plugin

yarn add --dev html-webpack-plugin
然後引入外掛程式,並配置如下:

...

const htmlwebapckplugin = require('html-webpack-plugin');

... plugins: [

...new htmlwebapckplugin(),

new htmlwebapckplugin(),

new htmlwebapckplugin()

],...

這樣乙個基於webpack3.x的多頁面框架就有了基本的樣子。

而使用webpack4.x則完全不同,它移除了內建的commonschunkplugin外掛程式,引入了splitchunksplugin外掛程式,這個外掛程式滿足了我們的需要,彌補了commonschunkplugin的不足。

如果你想要解決之前的不足,去提取index, contacus共有的模組,操作起來會很簡單。正如上面的所列舉的那樣,我們有三個入口點index, aboutus, contactussplitchunksplugin外掛程式會首先獲取這三個入口點共有的**塊,然後建立乙個檔案,緊接著獲取每兩個入口點的共有**塊,然後將每個入口點獨有的**塊單獨形成乙個檔案。如果你使用了第三方庫,就像上面我們使用的loadsh,它會將第三方入口**塊單獨打包為乙個檔案。

配置檔案webpack.config.js需要增加如下的**:

···

optimization:

}···

因為splitchunksplugin可以提取任意的入口點之間的共同**,所以,我們就不需要使用vendors入口節點了。那麼,為匹配生成不同的頁面**可以修改成如下:

const htmlwebapckplugin = require('html-webpack-plugin')

··· plugins: [

new htmlwebapckplugin(),

new htmlwebapckplugin(),

new htmlwebapckplugin(),

]···

可以發現結果越來越接近我們所想。但是這裡還是存在乙個問題,第三方庫loadsh因為在入口點index, aboutus中被分別引入,但是構建的結果卻輸出了兩個第三方庫檔案,這不是我們想要的。這個問題怎麼解決呢,因為html-webpack-plugin外掛程式的chunks選項,支援多入口節點,所以,我們可以再單獨建立乙個第三方庫的入口節點vendors。配置**修改如下:

...

entry: ,

...plugins: [

new htmlwebapckplugin(),

new htmlwebapckplugin(),

new htmlwebapckplugin(),

],...

注意:如果不同的入口點兒之間有依賴關係,如上面的indexvendors之間,因為index依賴於vendors,所以vendors要置於index之前。

這篇文章,說到這裡基本上已經結束了。當然,webpack多頁面應用的知識點還沒有講完,這些內容會放在後續的文章中詳解。

webpack3.x multi-page

webpack4.x multi-page

使用Webpack構建多頁面程式

使用webpack搭建單頁面程式十分常見,但在實際開發中我們可能還會有開發多頁面程式的需求,因此我研究了一下如何使用webpack搭建多頁面程式。將每個頁面所在的資料夾都看作是乙個單獨的單頁面程式目錄,配置多個entry以及html webpack plugin即可實現多頁面打包。下面為本專案目錄結...

webpack多頁面方案

參考文章比較多 react loadable import 這個方案需要 babel plugin syntax dynamic import的支援,記得修改babelrc。一般用這個方案的話是要用react router來寫乙個單頁應用,模板載入乙個入口js,入口js裡把頁面路由寫好,每個頁面作為...

webpack多頁面打包

在src下新建多個js檔案和html模板 在entry裡配置多個入口檔案 entry htmlwebpackplugin裡配置不同的html頁面引用不同的js檔案 const plugins new htmlwebpackplugin new htmlwebpackplugin 但是每次在 entr...