webpack基礎(三)--多頁面打包

1、多頁應用(MPA)

單頁應用SPA:只有一個html文檔,經過js感知url的變化,js動態的將當前頁面內容清除掉,而後將下一個頁面的內容掛載到頁面上,這就是單頁應用,每次跳轉了解不須要請求新的html文檔;html

多頁應用MPA:每一次頁面跳轉,服務器都會返回一個新的html文檔,這種類型的網站就是多頁網站,也叫多頁應用。html5

2、基本思路

每個頁面對應一個entry和一個html-webpack-plugin,代碼示例以下:webpack

module.exports = {
    entry:{
        index:'./src/index/index.js',
        search:'./src/search/index.js'
    }
}
複製代碼

缺點:每次新增或刪除頁面都須要修改webpack配置,頁面過多時,會寫很是多的html-webpack-plugin配置,形成webpack配置文件冗長,不利於維護。web

3、通用方案

每次打包時動態獲取entry,根據entry信息自動設置html-webpack-plugin數量。bash

頁面內容所有放在src文件夾下面,而且每個頁面單獨一個文件夾,htmljs文件所有命名爲index,使用glob模塊的glob.sync動態獲取src文件夾下面的各個子文件夾中的index.js文件做爲每一個頁面的入口文件。服務器

獲取全部的入口文件路徑:post

const entryFiles = glob.sync(path.join(__dirname,'./src/*/index.js'))
複製代碼

遍歷入口文件集合建立html-webpack-plugin設置:網站

const entry = {};//入口對象
const htmlWebpackPlugins = [];//html-webpack-plugin設置集合
Object.keys(entryFiles).map(index => {
    const entryFil = entryFiles[index];
    //獲取文件夾名稱
    const match = entryFil.match(/src\/(.*)\/index\.js/);
    const pathname = match && match[1];
    //設置入口對象
    entry[pathname] = entryFil;
    //設置html-webpack-plugin設置
    htmlWebpackPlugins.push(
        new HtmlWebpackPlugin({
            template:path.join(__dirname,`src/${pathname}/index.html`),
            filename:`${pathname}.html`,
            chunks:[pathname],
            inject:true,
            minify:{
                html5:true,
                collapseWhitespace:true,
                preserveLineBreaks:false,
                minifyJS:true,
                minifyCSS:true,
                removeComments:false
            }
        })
    )
})
複製代碼

修改webpack配置:ui

module.exports = {
    entry:entry,
    ...
    plugins:[
        ...
    ].concat(htmlWebpackPlugins)
}
複製代碼

4、完整代碼

const path = require('path');
const glob = require('glob');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

const setMpa = () => {
    const entry = {};//入口對象
    const htmlWebpackPlugins = [];//html-webpack-plugin配置
    //獲取入口文件
    const entryFiles = glob.sync(path.join(__dirname,'./src/*/index.js'));
    
    Object.keys(entryFiles).map(index => {
        const entryFil = entryFiles[index];
        //獲取文件夾名稱
        const match = entryFil.match(/src\/(.*)\/index\.js/);
        const pathname = match && match[1];
        //配置入口文件對象
        entry[pathname] = entryFil;
        //配置html-webpack-plugin
        htmlWebpackPlugins.push(
            new HtmlWebpackPlugin({
                template:path.join(__dirname,`src/${pathname}/index.html`),
                filename:`${pathname}.html`,
                chunks:[pathname],
                inject:true,
                minify:{
                    html5:true,
                    collapseWhitespace:true,
                    preserveLineBreaks:false,
                    minifyJS:true,
                    minifyCSS:true,
                    removeComments:false
                }
            })
        )
    });
    
    return {
        entry,
        htmlWebpackPlugins
    }
};

const { entry, htmlWebpackPlugins } = setMpa();
module.exports = {
    entry:entry,
    output:{
        path:path.join(__dirname,'dist'),
        filename:'[name]_[chunkhash:5].js'
    },
    mode:'production',
    module:{
        rules:[
            ...
        ]
    },
    plugins:[
        new CleanWebpackPlugin(),
    ].concat(htmlWebpackPlugins)
}
複製代碼

系列連接:url

相關文章
相關標籤/搜索