vue項目webpack根據路由打包成多個html

背景

在vue項目中,咱們是將整個項目打包到一個dist目錄下,可是在實際開發中,當項目足夠龐大時(一級路由幾十個,二級路由上百個),咱們僅僅改一個小的BUG,好比說改了某個地方的一個按鈕邊框顏色,可是要發到線上的時候就須要打包整個項目,這樣就會形成開發2分鐘,打包半小時的現象,因此就須要拆分項目根據路由打包。css

目的

以下所示項目結構:html

根據views下面的模塊(也就是路由),打包成各自的html,以下圖vue

步驟

第一步

在package.json中添加如下代碼node

"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",
複製代碼

其中webpack

build:all是首次打包時,或者打包多個模塊時使用,能夠一次性按照順序執行其中的指令;web

cross-env是在打包以前配置打包變量的插件,這裏須要設置route變量爲路由名(路由名與文件夾名相同)vue-router

第二步

在view目錄下的各自模塊文件夾中,創建與模塊文件名相同的html和js,分別做爲各自的入口頁面和入口jsnpm

html至關於原來src下面的index.htmljson

js至關於原來src下面main.jsbabel

在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,以後再打包推薦改了哪一個模塊就打包那個模塊的代碼,這樣就回到初衷,每次打包至少能節省幾十倍的打包時間啦

相關文章
相關標籤/搜索