【多页面配置】webpack通用配置方案

149 阅读2分钟

引言

对于单页面应用webpack的entry配置比较简单,而多页面应用entry配置会随着页面增加需要手动添加配置,如何才能不需要每次都改变配置呢?

我们先看下webpack手动搭建单页面和多页面的配置。

  • 单页面
    entry: 'path.join(__dirname, '../src/index.js')'
    plugins: [new HtmlWebapckPlugin()]
  • 多页面
entry: {
    home: 'path.resolve(__dirname, '../src/pages/home/main.js')',
    login: 'path.resolve(__dirname, '../src/pages/login/main.js')',
    ...
}

plugins: [
    new HtmlWebapckPlugin({
        template: path.join(__dirname, `../src/pages/home/index.html`),
        filename: 'home.html',
        chunks: ['vendors', 'home']
    }),
     new HtmlWebapckPlugin({
        template: path.join(__dirname, `../src/pages/login/index.html`),
        filename: 'login.html',
        chunks: ['vendors', 'login']
    })
]
  • vue脚手架多页面配置
entry: {
    home: {
        template: path.resolve(__dirname, '../src/pages/home/index.html'),
        entry: path.resolve(__dirname, '../src/pages/home/main.js'),
        filename: 'home.html',
        chunks: ['vendor', 'common', 'home']
    },
    login: {
         template: path.resolve(__dirname, '../src/pages/login/index.html'),
        entry: path.resolve(__dirname, '../src/pages/login/main.js'),
        filename: 'home.html',
        chunks: ['vendor', 'common', 'login'] 
    }
}

通过以上配置可知,对于多页面每次新增页面都需要对entry和HtmlWebapckPlugin进行改变,不符合工程化思维。那么如何解决这个问题呢?

工程化改造

借助glob遍历文件目录,通过规则匹配自动找到入口文件。

  1. 安装glob:npm install glob -D
  2. 入口文件动态匹配
const glob = require('glob');

const setMPA = () => {
    // 入口entry
    const entry = {};
    // 输出文件数组
    const htmlWebapckConfig = [];
    // 同步获取符合src/pages/xx/main.js规则的文件地址数组
    const entryFiles = glob.sync(path.join(__dirname, '../src/pages/*/main.js'));
    Object.keys(entryFiles)
        .map((index) => {
            const entryFile = entryFiles[index];
            const match = entryFile.match(/src\/pages\/(.*)\/main\.js/);
            // 获得多页面的名称
            const pageName = match && match[1];
            // 设置entry
            entry[pageName] = entryFile;
            // 设置HtmlWebapckPlugin
            htmlWebapckConfig.push(
                {
                    template: path.join(__dirname, `../src/pages/${pageName}/index.html`),
                    filename: `${pageName}.html`,
                    chunks: ['vendors', pageName]
                }
            );
        });

    return {
        entry,
        htmlWebapckConfig
    };
};

const { entry, htmlWebapckConfig } = setMPA();
module.exports = {
    entry,
    htmlWebapckConfig
}
  1. 修改配置

将entry和htmlWebapckConfig分配赋值给webpack配置的entry和plugins。

可将上述作为单独的文件webpack.base.js,开发和生产环境配置可以复用。

const config = require('./webpack.base.js');

let devConfig = {
    entry: config.entry,
    ...,
    plugins: [...]
}
// 动态添加插件
config.htmlWebapckConfig.forEach(item => {
    const option = {
        filename: item.filename,
        template: item.template,
        chunks: item.chunks
    };
    devConfig.plugins.push(new HtmlWebapckPlugin(option));
});

总结

通过以上步骤就完成了多页面通用配置方案,完整工程可以参考:webpack5+vue3多页面通用工程