Vue单工程多项目实践
背景
- 原来项目使用的是Vue-cli2.x 生成的SPA项目模板来维护,随着项目的迭代,每次创建一个SPA项目,下载一堆依赖,而且各个项目之间公共组件重合较多,依赖也没有明显的变化,这就促使需要一个工程来维护多个项目,来尽量复用项目之间的组件,样式,打包依赖等等。
- 为了减少重复性的工作,提高代码复用,更快更好的响应需求,因此做单工程多项目的实践。
Vue-cli3.x
趁这次机会升级了Vue-cli的版本,对vue-cli3.x的使用这里就不做介绍了。官网地址vue-cli3
安装 vue-cli
npm install -g @vue/cli
创建项目
vue create helloapp
剩下的根据cli的提示创建适合自己的项目
实现过程
- 创建project.js文件用来存储要运行的项目名称,可以通过命令行参数设置。
module.exports = {projectName:'xxx'}
- 创建按环境区分的配置文件,获取命令行项目名称,设置node运行命令,执行相应的运行。
dev.js
let projectName = process.argv[2];
if (!projectName) {
throw Error('Project name cannot be empty and must match the directory name');
}
let fs = require('fs');
let template = `module.exports = {projectName:"${projectName}"}`;
fs.writeFileSync('./config/project.js', template);
let exec = require('child_process').execSync;
exec('npm run d', {stdio: 'inherit'});
build.js
let projectName = process.argv[2];
if (!projectName) {
throw Error('Project name cannot be empty and must match the directory name');
}
let fs = require('fs');
let template = `module.exports = {projectName:'${projectName}'}`;
fs.writeFileSync('./config/project.js', template);
let exec = require('child_process').execSync;
exec('npm run b', {stdio: 'inherit'});
- 修改package.json
新增npm run dev、npm run build 命令。
npm run dev: 以开发模式运行项目
npm run build: 打包编译项目到本地dist目录
"scripts": {
"d": "vue-cli-service serve",
"b": "vue-cli-service build",
"dev": "node config/dev.js",
"build": "node config/build.js"
}
- 新增projectConfig.js
const project = require('./project');
const config = {};
const projectName = project.projectName;
config[projectName] = {
entry:`./src/projects/${projectName}/main.js`,
template:`./src/projects/${projectName}/${projectName}.html`,
fileName:`${projectName}.html`
}
5.创建vue.config.js文件
相关的配置在这个文件进行配置
publicPath: publicPath,
outputDir: config.build.assetsRoot + '/' + project.projectName,
assetsDir: process.env.NODE_ENV === "production" ?
config.build.assetsSubDirectory : config.dev.assetsSubDirectory,
indexPath: pageConfig.filename,
lintOnSave: false,
productionSourceMap: false,
configureWebpack: config => {
config.entry = {
app: ['babel-polyfill', pageConfig.entry]
}
},
chainWebpack: config => {
config.output.filename('[name].js');
config.plugin('html').tap(args => {
args[0].template = resolve(pageConfig.template);
args[0].filename = pageConfig.filename;
return args;
});
config.resolve.alias
.set('vue$', "vue/dist/vue.esm.js")
}
使用devServer配置开发调试模式的内容
index: pageConfig.filename,
contentBase: resolve('public'),
historyApiFallback: {
rewrites: [
{from: /^\//, to: path.posix.join(config.dev.assetsPublicPath, pageConfig.filename)},
{from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, pageConfig.filename)}
]
}