背景
在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变量去匹配打包后会使用的:
用来生成不同路由下的打包配置,最后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,之后再打包推荐改了哪个模块就打包那个模块的代码,这样就回到初衷,每次打包至少能节省几十倍的打包时间啦
所有评论(0)