(注:本文以vue-cli 2.x爲例)html
起初,咱們的項目還只是簡單的一個腳手架建立的簡單工程,直到有一天,公司決定在現有基礎上再出一個 版本,現有內容不變,兩個版本並存,後期有可能還會出現更多版本,做爲前端,咱們怎麼作最好呢,前端
大佬0:開個新的分支作吧,
大佬1:可是如今這個工程,已經作了大量的打包配置,而且有不少可複用的組件和封裝好的類,若是有一天這些內容要作更改呢,我總不能沒一個分支都去修改吧,
大佬2:咱們能夠傳到公司的git上,公共內容改變時只要從新pull一下就好了,
大佬n:...
小王子:咱們能夠像分佈式那樣垂直拆分一下咱們的項目嗎?提取公共部分,而後分模塊進行編譯,
衆人:...vue
emmmmm,說的怪好,怎麼實現呢,node
首先看一下默認的文件結構webpack
既然咱們要用多入口打包,固然就不能再用一個入口文件(main.js)和模板文件(index.html)了,咱們在不一樣的模塊下分別建立他們,而後咱們對模塊A打包, 他就自動去訪問模塊A的main.js和index.html; 對模塊B打包,他就自動去訪問模塊B的main.js和index.html。 這時候咱們的文件結構就要變成這樣子,git
安裝
npm install yargs --D
在命令後面添加參數
node build/build.js --env module1
接收參數
const yargs = require('yargs')
const module_fileName = yargs.argv.env
複製代碼
執行一下發現讀取到對應的參數了,咱們再進行下一步, 咱們能夠把接收參數的方法提取到公共部分, 由於生產環境和開發環境對應的打包文件都要使用他,咱們直接在使用的地方調用方法取值便可了,web
在build/utils.js文件中添加如下代碼
+ const yargs = require('yargs')
+ const fileName = yargs.argv.env
+ // 自定義入口main.js
+ exports.entry = function () {
+ return {
+ app: './src/modules/' + fileName + '/main.js'
+ }
+ }
+ // 自定義入口html文件
+ exports.template = function () {
+ return './src/modules/' + fileName + '/index.html'
+ }
複製代碼
做爲入口文件,生產環境和開發環境都要從這裏進入,屬於基礎配置,因此咱們找到webpack.base.conf.jsvuex
在build/webpack.base.conf.js文件中修改entry
entry: utils.entry(),
複製代碼
模板文件的使用就相對複雜點了,一樣生產環境和開發環境都須要他,並且咱們的熱更新也要用他vue-cli
首先修改開發環境npm
在build/webpack.dev.conf.js修改devServer.historyApiFallback.rewrites
devServer: {
historyApiFallback: {
rewrites: [
{from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, utils.template())},
],
}
...
}
在build/webpack.dev.conf.js修改plugins
plugins: [
new HtmlWebpackPlugin({
filename: utils.template(),
template: utils.template(),
inject: true
}),
...
]
複製代碼
接着修改生產環境
在build/webpack.dev.conf.js修改plugins
plugins: [
new HtmlWebpackPlugin({
template: utils.template(),
...
})
]
複製代碼
最後測試一下,咱們分別執行兩個命令
npm run dev:module1
npm run dev:module2
等到編譯經過後,發現webpack啓動了兩個服務器,
分別是module1和module2的項目,
這就表示咱們的修改生效了
複製代碼
關於數據倉庫的模塊化,vuex自己提供了方案
Vuex 容許咱們將 store 分割成模塊(module)。每一個模塊擁有本身的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進行一樣方式的分割 vuex.vuejs.org/zh/guide/mo…
官方推薦了modules,同時咱們配合registerModule,能夠實現數據倉庫的按需引入,是個很好的優化方案。
可是咱們的項目在搭建的時候沒有考慮到如今這種狀況。採起該方案,意味着咱們要修改每個使用了vuex的組件,工程量比較大,若是很不幸,你的狀況像咱們同樣,或許能夠考慮下面這種方案。
文章開頭咱們已經展現的文件的結構,數據倉庫放在項目根目錄, module1和module2只要按需引入數據倉庫的模塊便可 這裏咱們這樣作,
首先看下根目錄下的數據倉庫
咱們在module1中按需引入
src/module1/store/config.js
export [
'common',
'alarm',
'params_3dCity',
'params_sky',
'queue_message',
'user_city'
]
複製代碼
這裏字符串的內容就是文件名,有了他,咱們能夠動態地將文件require進來,而後使用Object.assign方法將對象合併,最後export出一個實例化的Vuex.Store對象,main.js直接使用便可。
代碼以下
src/module1/store/config.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import config from './config'
const state = {};
const mutations = {};
const actions = {};
for(let fileName of config) {
const module = require('@/store/' + fileName);
Object.assign(state, state, module.default.state);
Object.assign(actions, actions, module.default.actions);
Object.assign(mutations, mutations, module.default.mutations);
}
export default new Vuex.Store({
state,
mutations,
actions,
})
複製代碼
在package.json中添加以下命令
+ "dev:module1": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --env module1",
+ "dev:module2": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --env module2",
+ "build:module1": "node build/build.js --env module1",
+ "build:module2": "node build/build.js --env module2",
複製代碼