背景

在vue项目中,我们是将整个项目打包到一个dist目录下,但是在实际开发中,当项目足够庞大时(一级路由几十个,二级路由上百个),我们仅仅改一个小的BUG,比如说改了某个地方的一个按钮边框颜色,但是要发到线上的时候就需要打包整个项目,这样就会造成开发2分钟,打包半小时的现象,所以就需要拆分项目根据路由打包。

目的

如下所示项目结构:

根据views下面的模块(也就是路由),打包成各自的html,如下图

步骤

第一步

在package.json中添加以下代码

    "build:all": "npm run build:healthWorksite && npm run build:inquiryManage && npm run build:remoteInquiry && npm run build:statistics && npm run build:staffWorkbench && npm run build:storage",
    "build:healthWorksite": "cross-env NODE_ENV=production env_config=prod route=healthWorksite node build/build.js",
    "build:inquiryManage": "cross-env NODE_ENV=production env_config=prod route=inquiryManage node build/build.js",
    "build:remoteInquiry": "cross-env NODE_ENV=production env_config=prod route=remoteInquiry node build/build.js",
    "build:statistics": "cross-env NODE_ENV=production env_config=prod route=statistics node build/build.js",
    "build:staffWorkbench": "cross-env NODE_ENV=production env_config=prod route=staffWorkbench node build/build.js",
    "build:storage": "cross-env NODE_ENV=production env_config=prod route=storage node build/build.js",
复制代码

其中

build:all是首次打包时,或者打包多个模块时使用,可以一次性按照顺序执行其中的指令;

cross-env是在打包之前配置打包变量的插件,这里需要设置route变量为路由名(路由名与文件夹名相同)

第二步

在view目录下的各自模块文件夹中,建立与模块文件名相同的html和js,分别作为各自的入口页面和入口js

html相当于原来src下面的index.html

js相当于原来src下面main.js

在js中,通用的依赖与原来的main.js相同,再添加各自页面需要的依赖,并且将router的指向改变为router目录下建立的自己模块路由,由于引用的App.vue没有做任何改变,所以引用外层的通用App.vue

示例代码如下:

import Vue from "vue";

import "@src/common";
import "@src/components";
import "normalize.css/normalize.css"; 
import "@src/assets/styles/index.scss"; 
import "@src/assets/styles/public.scss";
import App from "@src/App";
// 其他地方所有页面大体相同,这里引用的router不同
import router from "@src/router/healthWorksite/index.js"; 
import store from "@src/store";

// 以下代码省略
......

复制代码

第三步

在router目录下,建立与模块名相同的路由文件夹,并在文件夹下建立index.js,相当于原先router下面的index.js

在index.js中导入当前路由的配置,如上图,仅导入healthWorksit.js作为当前模块的路由

index.js示例代码如下:

import Vue from "vue";
import VueRouter from "vue-router";
import healthWorksite from "@src/router/routes/healthWorksite";
Vue.use(VueRouter);

const routes = [
  ...healthWorksite,
  {
    path: "/",
    redirect: {
      name: "/login"
    }
  }
];

const router = new VueRouter({
  base: "/",
  linkActiveClass: "active",
  routes
});
// 以下代码省略
......
复制代码

第四步

在config文件夹下的index.js里面添加以下代码

根据在package中设置的route变量去匹配打包后会使用的:

index-输出html文件名
assetsRoot-输出文件根目录路径
assetsSubDirectory-输出文件二级目录路径
assetsPublicPath-引用公共路径

用来生成不同路由下的打包配置,最后merge到输出项中

const merge = require("webpack-merge");
const buildNanme = process.env.route;
const buildList = {
  index: path.resolve(__dirname, `../../vueClinicWeb/${process.env.route}/index.html`),
  assetsRoot: path.resolve(__dirname, `../../vueClinicWeb/${process.env.route}`),
  assetsSubDirectory: "./static",
  assetsPublicPath: `../../vueClinicWeb/${process.env.route}`,
  productionSourceMap: false,
  devtool: "#source-map",
  productionGzip: false,
  productionGzipExtensions: ["js", "css"],
  bundleAnalyzerReport: process.env.npm_config_report
};
let buildRouteConfig = {};
buildRouteConfig[buildNanme] = buildList;
module.exports = merge(buildRouteConfig, {
  dev: {// 此处省略
  },

  build: merge(buildList, {
    index: path.resolve(__dirname, "../dist/index.html"),
    assetsRoot: path.resolve(__dirname, "../dist")
  })
});
复制代码

第五步

在build文件夹下面的utils.js中加入以下代码

根据路由匹配到上一步设置的路径,并输出该路径常量给其他js使用

// 根据路由进行配置
let routePathRoot = config.build.assetsRoot;
let routePathSubDirectory = config.build.assetsSubDirectory;
let routeAssetsPublicPath = config.build.assetsPublicPath;
let routeEntry = "./src/main.js";
let templatePath = "index.html";
let filename = config.build.index;
const ENV_ROUTE = process.env.route;
if (ENV_ROUTE) {
  routePathRoot = config[ENV_ROUTE].assetsRoot;
  routePathSubDirectory = config[ENV_ROUTE].assetsSubDirectory;
  routeAssetsPublicPath = config[ENV_ROUTE].assetsPublicPath;
  routeEntry = `./src/views/${ENV_ROUTE}/${ENV_ROUTE}.js`;
  templatePath = resolve(`/src/views/${ENV_ROUTE}/${ENV_ROUTE}.html`);
  filename = config[ENV_ROUTE].index;
}

exports.assetsPath = function(_path) {
  const assetsSubDirectory = process.env.NODE_ENV === "production" ? routePathSubDirectory : config.dev.assetsSubDirectory;

  return path.posix.join(assetsSubDirectory, _path);
};
exports.routePathRoot = routePathRoot;
exports.routePathSubDirectory = routePathSubDirectory;
exports.routeAssetsPublicPath = routeAssetsPublicPath;
exports.routeEntry = routeEntry;
exports.templatePath = templatePath;
exports.filename = filename;

复制代码

第六步

修改build文件夹下面的build.js

根据路由设置需要删除的文件夹路径

let routePathRoot = utils.routePathRoot;
let routePathSubDirectory = utils.routePathSubDirectory;

rm(path.join(routePathRoot, routePathSubDirectory)
// 以下代码省略
复制代码

第七步

修改build文件夹下的webpack.base.conf.js

根据路由设置通用的入口js文件路径、输出文件根目录、输出页面引用路径

// 仅显示修改部分
const routePathRoot = utils.routePathRoot;
const routeAssetsPublicPath = utils.routeAssetsPublicPath;
const routeEntry = utils.routeEntry;
module.exports = {
  entry: ["babel-polyfill", routeEntry],
  output: {
    path: routePathRoot,
    publicPath: process.env.NODE_ENV === "production" ? routeAssetsPublicPath : config.dev.assetsPublicPath
  }
};
复制代码

第八步

修改build文件夹下的webpack.prod.conf.js

根据路由设置文件名、入口页面路径、打包文件根目录路径、打包文件二级目录路径、引用资源公用路径等

// 仅展示修改部分
const filename = utils.filename;
const templatePath = utils.templatePath;
const routePathRoot = utils.routePathRoot;
const routePathSubDirectory = utils.routePathSubDirectory;
const routeAssetsPublicPath = utils.routeAssetsPublicPath;

const webpackConfig = merge(baseWebpackConfig, {
  output: {
    path: routePathRoot
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: filename,
      template: templatePath,
      inject: true,
      path: routeAssetsPublicPath + routePathSubDirectory,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
      },
      chunksSortMode: "dependency"
    }),
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, "../static"),
        to: config.build.assetsSubDirectory,
        ignore: [".*"]
      }
    ])
  ]
});
复制代码

第九步

最后在终端中npm run build:all就大功告成了

首次打包推荐npm run build:all,之后再打包推荐改了哪个模块就打包那个模块的代码,这样就回到初衷,每次打包至少能节省几十倍的打包时间啦

转载于:https://juejin.im/post/5c2dcaec6fb9a04a0821cd27

Logo

前往低代码交流专区

更多推荐