vue+webpack多个项目共用组件动态打包单个项目

原文复制:https://www.jianshu.com/p/fa19a07b1496

修改了一些东西,因为sh脚本不能再window电脑执行,所以改成了node脚本。这是基于vue-cli2.0配置的,3.0的也是同样的道理。
我现在的项目改成vue-cli3.0的了,实现了一个工程多项目共用一些资源,但是打包的时候只打包一个项目,并且每个项目也可以配置多页面,并且实现了自动化上传到测试服务器(生产没权限)和静态资源分离,一行命令就可以打包项目并且把静态资源上传到一个服务器,而html文件上传到另一个服务器。欢迎一起交流学习。

1.最终实现结果

先看下目录结构

 

projectA,projectB,projectC是三个业务上没有关系的三个项目,但是可以共用一些公用的组件、公用工具类、公用样式等。
要实现npm run dev/build projectA 编译打包的时候,只编译打包项目projectA,而projectB和projectC不会编译打包进来。
实现npm run dev/build + 项目名字编译打包对应的项目

 

2.为什么这么做

以下是结合自己公司的业务场景进行摸索的
公司经常会有一些活动,为了配合活动开发人员需要开发一些h5页面来配合活动,刚开始活动不多,所有活动页面都放在一个项目目录下,webpack共用一个固定打包入口,对路由(vue-router)和状态管理(vuex)进行模块划分,不同的活动页面通过不同的路由路径来加载。
随着活动项目增多,页面也越来越多,问题就就出现了,比如打包projectA,webpack也会把projectB,projectC打包进来,因为SPA应用是一次性下载所有资源文件,这就造成访问projectA或者projectB或者projectC的时候会变得慢,因为把一些不相干的代码也下载下来了。
有人会说每有一个项目vue init另起一个工程目录,但是这样每次都要复制一下工具类等公用代码,每次都要配置下环境,有的活动也就一两个页面另起一个工程没必要。

3.走的弯路

一开始我想通过webpack的一些配置,当打包projectA的时候,把projectB和projectC目录排除在外,后来这条路没走通,就放弃了。

4.实现

分两个步骤
第一是怎样当npm run dev/build + 项目名字的时候让webpack知道你想打包哪个项目
第二是根据项目名称来动态更改一些webpack配置

第一

在config目录下新建两个脚本文件

 

 
WechatIMG1481.jpeg

脚本内容
build.js

// 下面这行代码
// 拿到命令行里参数,比如执行(npm run b projectA),这个时候projectName就等于projectA
// 有了这个变量,就可以根据这个名字来读取projectConfig里面的配置了
let projectName = process.argv[2]

// 下面两行代码 获取projectName后把保存起来,写入到project.js里,方便其它js文件里引入使用
let fs = require('fs')
fs.writeFileSync('./config/project.js', `exports.name = '${projectName}'`)

// 下面两行代码继续执行命令(npm run build),执行默认命令开始进行打包
let exec = require('child_process').execSync;
exec('npm run build', {stdio: 'inherit'});

dev.js

let projectName = process.argv[2]
let fs = require('fs')

fs.writeFileSync('./config/project.js', `exports.name = '${projectName}'`)

let exec = require('child_process').execSync;
exec('npm run dev', {stdio: 'inherit'});

在config目录下新建 project.js文件


 
image.png

内容就一行代码

exports.name = 'ProjectA'

修改package.json

  "scripts": {
    "d": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "b": "node build/build.js",
    "dev": "node config/dev.js",
    "build": "node config/build.js"
  },

到此第一步就完成了
以打projectA生产包为例
当执行npm run build projectA的时候,会执行build.js脚本,并把projectA传给脚本let projectName = process.argv[2]拿到项目名称,
fs.writeFileSync('./config/project.js', `exports.name = '${projectName}'`)写入到project.js文件里
这就达到了动态获取你想要打包的项目名称的目的,有了这个环境变量,就可以根据项目的需要来修改webpack的配置了。

let exec = require('child_process').execSync;
exec('npm run build', {stdio: 'inherit'});

继续执行打包流程。

第二

至于webpack配置,可以通过修改HtmlWebpackPlugin的template和修改打包入口路径来动态打包。
首先为每个项目单独新建入口和渲染模板


 
image.png

每个项目的webpack配置可能有很多不同,所有我建了一个projectConfig.js专门来处理


 
image.png

projectConfig.js内容

const projectName = require('./project')

const config = {
  //活动1
  projectA:{
    localPath:'./src/projects/projectA/',
    uploadPath:'/h5/test/cb/',
  },
  //活动2
  projectB:{
    localPath:'./src/projects/projectB/',
    uploadPath:'/h5/act/tf/',
  },
  //活动3
  projectC:{
    localPath:'./src/projects/projectC/',
    uploadPath:'/h5/test/tf/',
  }
}

const configObj = config[projectName.name]
module.exports = configObj

这里是根据项目要打包的项目名称获取一些webpack打包配置
还是以打projectA生产包为例,即npm run build projectA
修改渲染模板

 
image.png

 
image.png

修改打包入口
 
image.png

至此第二步也完成了
这样就实现多个项目共用组件并且动态打包单个项目了

 

5.demo

demo地址

posted @ 2019-01-22 14:38  菲比月  阅读(5804)  评论(1编辑  收藏  举报