在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變量去匹配打包後會使用的:
用來生成不一樣路由下的打包配置,最後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,以後再打包推薦改了哪一個模塊就打包那個模塊的代碼,這樣就回到初衷,每次打包至少能節省幾十倍的打包時間啦