基於 vue-cli 2 實現,vue 多模塊、vue多項目集成工程
Github項目地址 : https://github.com/BothEyes1993/vue-multi-module
目標:多模塊集成的vue項目,多項目共用一份配置,可以互相依賴,也可以獨立打包部署
使用業務場景
1.如果項目可能有對應多個不同UI界面;對於這樣的場景你可能首先會想到,用樣式主題就可以實現,基本的樣式或者換膚是可以通過樣式實現。但如果要實現更復雜的,比如不同兩套UI的界面可能功能顯示及樣式都有差別,那就不得不單獨拆成一個項目,但是這樣又會造成每個項目很多冗余代碼。
2.如果項目有多個子模塊(同時子模塊之間又存在互相依賴關系);對於這樣的場景是可以把項目獨立發布到npm倉庫,但是這樣又涉及到每個模塊都需要獨立編譯好再發布,實際過程有顯得有些繁瑣(實際視情況而定)。
對於以上場景可以使用一個項目管理多個子模塊也是一個不錯的選擇。
多頁面和多模塊區別
多頁面:多頁面是指一個項目有多個入口,打包是會生成多個html文件,實際開發過程中都是混合在一個項目中開發;
多模塊:是指不同的業務模塊可以進行拆分;各自獨立運行、也可以互相引用,這一點和通過 npm 發布是類似的;對於一些項目本身不允許發布的情況下,既可以獨立開發,又不需要發布到共有倉庫(當然也可以通過建立私有倉庫解決哈)
問題:
1,如何划分子模塊;
2,如何分離可復用組件;
3,如何獨立編譯,每個子模塊獨立打包編譯、運行;
優點
1,高復用性
2,統一管理依賴庫
3,不同模塊使用的依賴各自按需打包
4,模塊之間相互獨立運行、編譯、打包
5,模塊之間可以直接互相引用,不需要iframe(一般方式是通過iframe嵌入,這樣的性能相當差)
一:開始創建項目
先用vue-lic
創建個demo項目:
vue init webpack vue-multi-module
先看看創建成功的項目目錄:
創建完后先跑起來看看:
npm run dev
二:添加多項目模塊
把src目錄下的文件換成多模塊的形式
build:編譯、運行相關腳本文件
config:編譯、運行相關配置文件
static:不需要編譯的靜態資源,放到對應的模塊目錄下
子模塊1
子模塊2
...
src:項目源碼
comm:公共模塊
script:公共js文件
components:公共組件
子模塊1:
assets:樣式、圖片等資源文件
common:業務相關的公共文件
components:業務組件
router:路由配置
store:vuex相關
views:頁面視圖
子模塊2:
子模塊3:
...
項目模塊結構安裝上面的改動完畢之后,控制台會報一些路徑錯誤之類的:
這是因為webpack.base.conf.js
里面的main.js
的路徑發生改變導致的,之前項目是單模塊只要一個main.js
,現在換成多模塊之后每個模塊都有自己獨立的main.js
,所以要修改配置。
三:修改配置
1.增加 config/multi.conf.js
:多模塊配置文件,定義各個模塊自己的端口,名稱,轉發規則,靜態資源
.............
// 多模塊獨立配置
var importModules = [
new MultiModule('project1', {
port: 8091,
statics: ['static1'],
proxyTable: {
'/servers1/': getProxyConfig(PROXY_DOMAIN_DEFAULT)
}
}),
new MultiModule('project2', {
port: 8092,
statics: ['static2'],
proxyTable: {
'/servers2/': getProxyConfig(PROXY_DOMAIN_DEFAULT)
}
}),
new MultiModule('project3', {
port: 8093,
statics: ['static3'],
proxyTable: {
'/servers3/': getProxyConfig(PROXY_DOMAIN_DEFAULT)
}
}),
new MultiModule('project4', {
port: 8094,
statics: ['static4'],
proxyTable: {
'/servers4/': getProxyConfig(PROXY_DOMAIN_DEFAULT)
}
})
]
..........
2.修改 build/webpack.base.conf.js
文件:修改啟動項目的入口文件,添加各個模塊的別名
..............
module.exports = {
context: path.resolve(__dirname, '../'),
entry: multiConfig.process.entry,
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@comm': resolve(`src/comm`),
'@': multiConfig.process.alias,
...multiConfig.moduleAlias
}
},
.............
以上兩個配置加上之后之前的main.js
錯誤就消失了,但是又會報一些語法錯誤:
這是因為項目中的用了sass
語法和一些es6
語法缺少轉碼包,所以要加上對應的包:
到這里項目就可以正常啟動了:
3.修改package.json
文件
這里默認啟動的是project1,如果需要啟動project2,project3,就需要在package.json
里面加對應的script
現在可以啟動:npm run dev:project2
可能大家注意到了每次啟動的時候端口都是一樣的:
這樣如果同時啟動多個項目就沒法區分誰是誰了,所以要在webpack.dev.conf.js
里面的compilationSuccessInfo/messages
里面加上對應項目的提示信息和自定義端口,以及每個項目的代理轉發地址也不同,也要從multi.conf.js
獲取,涉及到修改以下的兩個配置文件
4.修改webpack.dev.conf.js
和config下的index.js
文件
webpack.dev.conf.js
:修改本地轉發規則proxy(指向multi),修改啟動后的描述文字
// Add FriendlyErrorsPlugin
let host = ['localhost', '127.0.0.1', '0.0.0.0'].includes(devWebpackConfig.devServer.host) ? 'localhost' : devWebpackConfig.devServer.host
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [chalk`{bold.rgb(255,255,0) [${pack.name} => ${multiConfig.process.name}]} App running at:\n - Local: {bold.cyan http://${host}:${port}${config.dev.assetsPublicPath}}\n - Network: {bold.cyan http://${getIPAdress()}:${port}${config.dev.assetsPublicPath}}`]
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})
index.js
:修改所有啟動端口(port)和靜態資源地址(static)
dev: {
// Paths
assetsSubDirectory: multiConfig.process.assetsSubDirectory,
assetsPublicPath: multiConfig.process.assetsPublicPath,
proxyTable: null,
// Various Dev Server settings
host: multiConfig.process.host, // can be overwritten by process.env.HOST
port: multiConfig.process.port, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
到這里本地啟動的名稱,端口,代理,靜態資源都已經區分開了。接下來打包的時候也要按需打包每個模塊項目自己的依賴的資源:
5.修改package.json
和config下的index.js
文件
package.json
:新加命令
"build": "npm install && npm run build:project1 && npm run build:project2 && npm run build:project3 && npm run build:project4",
"build:project1": "node build/build.js name=project1",
"build:project1:zip": "node build/build.js name=project1 zip",
"build:project2": "node build/build.js name=project2",
"build:project2:zip": "node build/build.js name=project2 zip",
"build:project3": "node build/build.js name=project3",
"build:project3:zip": "node build/build.js name=project3 zip",
"build:project4": "node build/build.js name=project4",
"build:project4:zip": "node build/build.js name=project4 zip",
config下的index.js
:各模塊分開打包后的路徑
build: {
// Template for index.html
index: multiConfig.process.index,
// Paths
assetsRoot: multiConfig.process.assetsRoot,
assetsSubDirectory: multiConfig.process.assetsSubDirectory,
assetsPublicPath: multiConfig.process.assetsPublicPath,
}
6.webpack.prod.conf.js
:打包的時候靜態資源按需copy拉取(CopyWebpackPlugin),添加模塊壓縮添加packZip.js
。
new CopyWebpackPlugin(multiConfig.process.publics.filter(name => isDirectory(path.resolve(__dirname, `../static/${name}`))).map(name => {
return {
from: path.resolve(__dirname, `../static/${name}`),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
})),
// pack zip
...require('./packZip')
packZip.js
:依賴filemanager-webpack-plugin打包zip組件,package.json相應添加
.............
plugins.push(new FileManagerPlugin({
onEnd: {
delete: [
path.join(__dirname, `../${pack.name}_${multiConfig.process.name}_*.zip`)
],
archive: [{
source: path.join(__dirname, `../dist/${multiConfig.process.name}`),
destination: path.join(__dirname, zipPros[1] ? `../${pack.name}_${zipPros[1]}.zip` : `../${pack.name}_${multiConfig.process.name}_v${pack.version}_${datetime}.zip`)
}]
}
}))
}
到這里模塊項目已經實現多模塊啟動,按需打包,壓縮等功能
完整項目地址 : https://github.com/BothEyes1993/vue-multi-module