原文復制:https://www.jianshu.com/p/fa19a07b1496
修改了一些東西,因為sh腳本不能再window電腦執行,所以改成了node腳本。這是基於vue-cli2.0配置的,3.0的也是同樣的道理。
我現在的項目改成vue-cli3.0的了,實現了一個工程多項目共用一些資源,但是打包的時候只打包一個項目,並且每個項目也可以配置多頁面,並且實現了自動化上傳到測試服務器(生產沒權限)和靜態資源分離,一行命令就可以打包項目並且把靜態資源上傳到一個服務器,而html文件上傳到另一個服務器。歡迎一起交流學習。
1.最終實現結果
先看下目錄結構

要實現
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目錄下新建兩個腳本文件

腳本內容
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文件

內容就一行代碼
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和修改打包入口路徑來動態打包。
首先為每個項目單獨新建入口和渲染模板

每個項目的webpack配置可能有很多不同,所有我建了一個projectConfig.js專門來處理

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
修改渲染模板


修改打包入口

至此第二步也完成了
這樣就實現多個項目共用組件並且動態打包單個項目了