應(yīng)用場景
在toB端業(yè)務(wù)中盖呼,同樣的產(chǎn)品,客戶多多少少會要求一些定制化化撕。從皮膚几晤,圖片,到一些小的功能的差異植阴。
前端總是沖在最前面需要改的蟹瘾。如果改動不大的話,拉個分支有增加了維護(hù)的成本掠手,分支拉多了憾朴,如果主干有一個問題相當(dāng)于copy了n份,那個滋味簡直不要太酸爽惨撇。那么伊脓,是否可以一套代碼支持多個項目呢?
前段時間,接了一個需求报腔,技術(shù)選型是VUE株搔,用vue-cli搭建的。一套代碼需要支持10幾家客戶纯蛾,每家的皮膚纤房,功能都有一些小的差異,主體流程大致是一樣的翻诉。在這個場景下研究了一下解決方案炮姨。
思路
總體的思路模塊化,然后在編譯的時候根據(jù)輸入命令直接組裝不同的模塊碰煌,打包出我們需要的頁面舒岸。
這個地方就有兩個問題:
1.如何劃分頁面,控制組件的顆粒度芦圾?
2.如何差異化編譯蛾派?
項目結(jié)構(gòu)
同樣一個頁面,有相同的部分个少,也有一些不一樣的部分洪乍。vue本身的組件化思想很容易讓我們想到把頁面拆分成組件,然后把公共的提取出來夜焦,差異化的分別處理壳澳。
項目總體結(jié)構(gòu)
build
build結(jié)構(gòu)中主要是webpack的一些腳本配置
config
config文件主要是項目相關(guān)配置,我們常用的就是當(dāng)端口沖突時配置監(jiān)聽端口茫经,打包輸出路徑及命名等
src
源碼文件巷波。
assets:靜態(tài)資源,一般放圖片科平,樣式等
less:樣式文件褥紫,這里分主題處理了
pages:頁面文件
router:路由
util:工具類
components
文件夾中是各個項目的自有的組件。components目錄下的是公共的組件
static
靜態(tài)資源瞪慧,不會被webpack編譯髓考。一般放一下外部引用文件。
webpack打包配置
如何差異化編譯弃酌?
1.cross-env使用環(huán)境變量氨菇。在編譯階段,根據(jù)編譯傳入的變量不同妓湘,編譯不同的組件查蓉。
首先,要改的是package.json的文件
"scripts": {
"dev:gx": "cross-env BRANCH_ENV=gx node build/dev-server.js",
"build:gx": "cross-env BRANCH_ENV=gx node build/build.js"
},
這個時候我們編譯的時候輸入對應(yīng)的命令 就可以傳入相應(yīng)的環(huán)境變量榜贴。
eg:npm run dev:gx 會傳入BRANCH_ENV=gx豌研。
2.把config/prod.env.js中注入這個環(huán)境變量
module.exports = {
NODE_ENV: '"production"',
API_PATH:'""',
BRANCH_ENV: JSON.stringify(process.env.BRANCH_ENV) || '"base"',
ignoreCsrfToken:'"false"'
}
3.webpack.base.conf.js
resolve: {
extensions: ['', '.js', '.vue', '.json'],
fallback: [path.join(__dirname, '../node_modules')],
alias: {
'vue$': 'vue/dist/vue.common.js',
'src': path.resolve(__dirname, '../src'),
'assets': path.resolve(__dirname, '../src/assets/images/'+process.env.BRANCH_ENV),
'components': path.resolve(__dirname, '../src/components'),
'componentsDif': path.resolve(__dirname, '../src/components/'+process.env.BRANCH_ENV),
}
},
可以看的出,我們把編譯命令注入的環(huán)境變量在引入別名的時候用上了。比如說鹃共,假設(shè)我輸入的編譯命令是
npm run build:gx
這個時候
'assets': path.resolve(__dirname, '../src/assets/images/'+process.env.BRANCH_ENV)
//等同于
'assets': path.resolve(__dirname, '../src/assets/images/gx')
頁面引用
1.圖片引用
<img class="icon-arrow" src="~assets/arrow.png">
//根據(jù)編譯命令鬼佣。圖片引用的是src/assets/images/gx/arrow.png
background: url(~assets/btn_1.png) no-repeat;
ps:用別名的時候記得要加上~號
組價引用
//公共組件
import ruleTitle from 'components/RuleTitle'
//差異化組件
import ruleContent from 'componentsDif/RuleContent'
總結(jié)
總而言之,核心思想就是跟進(jìn)編譯命令傳入環(huán)境變量霜浴,利用環(huán)境變量和別名的配置來差異化打包晶衷。比較難的是如何控制組件的顆粒度,如何拆分組件阴孟,這個需要跟據(jù)需求的不同來實際定制晌纫。
更新:傳變量進(jìn)入需要安裝cross-env,直接npm install cross-env (不好意思很久沒看評論永丝,最近比較忙)