使用webpack構建多頁應用

流霜發表於2019-04-09

背景

隨著react, vue, angular 三大前端框架在前端領域地位的穩固,SPA應用正在被應用到越來越多的專案之中。然而在某些特殊的應用場景之中,則需要使用到傳統的多頁應用。在使用webpack進行專案工程化構建時,也需要對應到調整。

與SPA應用區別

在SPA應用中,使用 webpack 構建完成專案之後,會生成一個 html 檔案,若干個 js 檔案,以及若干個 css 檔案。在 html 檔案中,會引用所有的 jscss 檔案。
而在多頁應用中,使用 webpack 構建完成專案之後,會生成多個 html 檔案,多個 js 檔案,以及多個 css 檔案。在每個 html 檔案中,只會引用該頁面所對應的 jscss 檔案。

webpack配置

入口設定

多頁應用的打包會對應多個入口 js 檔案,以及多個 html 模版檔案。假設我們的開發狀態下的多頁目錄是這樣:

    |--page1
        |--index.html
        |--index.js
        |--index.less
    |--page2
        |--index.html
        |--index.js
        |--index.less
複製程式碼

包括 page1page2 兩個頁面,以及它們所對應的 jsless 檔案。那麼在使用 webpack 構建專案時,就有 page1->index.jspage2->index.js 兩個入口檔案,以及 page1->index.htmlpage2->index.html 兩個模版檔案。然而在構建專案時,不可能針對每一個頁面指定一個入口配置。
要自動匹配到所有的頁面入口及模版檔案,有兩種方法。

方法一:使用 nodefs 檔案系統。來讀取父級資料夾下的所有子資料夾。通過資料夾名稱,來自動匹配到所有的頁面。然而,這種方式需要保持父級資料夾下檔案的乾淨。否則就需要使用具體的判斷邏輯來過濾出所有的入口目錄。

方法二:通過配置檔案來配置入口。比如:

    entry: ['page1', 'page2'];
複製程式碼

這樣便能準確的指定出所有的入口目錄。然而卻在每次增加頁面時,都需要去更改配置檔案。
兩種方法個有特點,可根據具體情況選擇。

具體配置

entry

entry的配置需要根據我們獲取到的入口資料來迴圈新增。

    const entryData = {};
    entry.forEach(function (item) {
        entryData[item] = path.join(__dirname, `../src/pages/${item}/index.js`);
    })
複製程式碼
output

output的配置和SPA應用一致,不需要特殊配置。

    output: {
        filename: 'public/[name]_[chunkhash:8].js',
        path: path.join(__dirname, `../dist/`),
        publicPath: '/'
    },
複製程式碼
HtmlWebpackPlugin

在使用 webpack 構建時。需要使用到 html-webpack-plugin 外掛來生成專案模版。對於需要生成多個模版的多頁應用來說,也需要生成多個 html 模版檔案。同樣的,使用獲取到的入口檔案資料來迴圈新增。

    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const HtmlWebpackPluginData = [];
    entry.forEach(function (item) {
        HtmlWebpackPluginData.push(
            new HtmlWebpackPlugin({
                filename: `${item}.html`,
                template: path.join(__dirname, `../src/pages/${item}/index.html`),
                chunks: [item]
            })
        );
    })      
複製程式碼

配置中 chunks 必須配置,如果不配置,會導致每個模版檔案中均引入所有的 jscss 檔案。指定為 entry 中的配置 name,則會只引入該入口相關的檔案。

配置組合

接下來,便是將前面的entry, output, htmlWebpackPlugin的配置組合起來,除此之外的其它配置,跟SPA應用一致,無需做單獨處理。組合如下

    modules.exports = {
        entry: { ...entryData },
        output: {
            filename: 'public/[name]_[chunkhash:8].js',
            path: path.join(__dirname, `../dist/`),
            publicPath: '/'
        },
        plugins: [
            ...HtmlWebpackPluginData
        ]
        ...
    }
複製程式碼

完整demo可檢視多頁應用demo

相關文章