使用webpack+vue进行单页/多页应用配置-[七日打卡2]

477 阅读2分钟

介绍

什么是单页应用? Single Application Page简写为SPA,不是那个斯霸,也不是那个SAP

SPA可以理解成一个应用程序中只有一个 html 文件作为程序的入口,如果需求中有多个子页面跳转的话,一般是通过前端路由机制实现切换的。

那什么是多页应用(Multiple Application Page)呢?

简单来说就是由多个单页应用构成的一个应用。

如下图所示:

spa-mpa

如何配置

我们知道webpack的没一个入口文件都对应于一个entry配置项,既然是多页应用对应多个html,所以对于webpack配置来说应该有多个entry,每个入口都是一个独立的单页应用,每个单页应用又可以包含组件、路由、状态管理等部分。简单来说,多页应用的每个单页部分拥有和纯单页应用同样的文件和功能。

在单页应用中,入口文件只有一个,通常约定为 src 目录下的 main.js或者index.js文件。但是多页应用为了增加项目的扩展性,一般会通过动态读取 src/pages/ 目录下的 main.js 等文件。

所以我们需要动态计算出入口文件数量并正确解析路径,然后配置到 webpack.entry 上。

效果如下所示:

// webpack.config.js
entry = {
    page1: 'src/pages/page1/main.js',
    page2: 'src/pages/page1/main.js',
    page3: 'src/pages/page1/main.js',
}

可以通过如下方法读取多页应用的入口:

// utils.js
const glob = require('glob')

// 读取多页应用的入口文件
// 返回entry对象
const getEntries = function (path = 'src/pages/**/main.js') {
  var files = glob.sync(path);

  var entryList = {};
  files.length > 0 && files.forEach(filepath => {
    var name = filepath.replace('src/pages', '');
    name = name.split('/') && name.split('/').length > 0 && name.split('/')[1];
    entryList[`${name}`] = './' + filepath;
  });
  return entryList;
}

通过 glob.sync 方法得到入口文件的对象集合,然后通过一个循环构造一个entryList对象,包含 entry 名称和对应的路径。

最后把这个变量赋值给 webpack.entry 变量。

// webpack.config.js
module.exports = {
    entry: getEntries(),
}

配置多模板 MPA

对于多页的多入口来说,多模板的配置也很类似。

一般多页的模板类似,所以用如下的方法得到多模板的配置信息:

// utils.js
const HtmlWebpackPlugin = require('html-webpack-plugin')

const getHtmlWebpackPlugins = function(entries) {
  const arrHTMLWebpackPlugin = Object.keys(entries).map(name => {
    const config = {
      filename: `${name}/index.html`, // 生成html的文件名
      template: './index.html', // 默认template读取项目根目录下的index.html文件,即:src/index.html
      chunks:[`${name}`, 'vendor', 'manifest'], // 需要加载的chunk模块
    };
    return new HtmlWebpackPlugin(config);
  });
  return arrHTMLWebpackPlugin;
}

上面这个方法根据传入参数entries进行循环遍历,动态返回一个包含HtmlWebpackPlugin元素的数组。

然后把这个变量放在 webpack.plugins 中。

// webpack.config.js
const entries = utils.getEntries()
const arrHTMLWebpackPlugin = utils.getHtmlWebpackPlugins(entries)

module.exports = {
    plugins: [
        ...arrHTMLWebpackPlugin,
    ]
}

这样我们就配置好了,运行npm run build 命令后就会发现 dist 目录下生成了打包产物:

dist
├── index
│   └── index.html
├── page2
│   └── index.html
├── page3
│   └── index.html
└── static
    ├── css
    ├── img
    └── js

至此就完成使用webpack对单页应用和多页应用的同时支持的配置说明。