首先我是很贊同業界的先後端分離的開發模式,雖然如今都講究全棧工程師,可是畢竟術業有專攻,前端同窗專一多終端,後端同窗關注高性能高可用。你們各自再本身的專一點上發光發熱。css
想一想咱們之前分模塊開發,既寫java又寫jsp,高級點的jsp不寫邏輯,全部的交互都是異步交互,算是一個簡單的先後端分離模型,最後找個美工(對,不是前端是寫css或者會畫圖的美工畫兩個圖)美化一下,而後就能夠用起來了,這樣的模式簡直就是原始社會同樣。前端
目前我同時接手了先後端同窗給個人2份代碼後,一我的作起了先後端分離開發,我感受本身一會兒高大上了起來,可是有幾點我也要吐槽一下java
1我要維護2分代碼,一份用webstorm編譯js代碼,一份用intelidea開發編譯java代碼,同時開了java和node服務本地聯調,這2個服務光開起來就已經7G內存了(jvm我開的是1024M,由於須要加載對象內存處理)。可憐的X1的內存是焊死的...焊死的....,並且只有8G....基本再開chrome就卡死了,卡死了。。。node
2 本地開發模式是這樣的,前端代碼用node開啓一個server跑頁面,後端代碼開啓跑接口服務,用頁面調用後端的接口服務,這就遇到一個尷尬的js跨域調用服務的問題,還好chrome良心支持這個參數,又還好IE咱們已經放棄了。。。react
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --args --disable-web-security --user-data-dir
可是由此升級chrome到51這個版本,新瀏覽器又出現跨域調不通的問題了,那時個人世界是崩潰的,之後怎麼開發吖webpack
還好網上有解決方案,感謝萬能的google,對於新版本的chrome瀏覽器,須要額外增長user-data-dir,而後就能夠繼續愉快的寫代碼了git
這裏我還要吐槽下之前的npm腳本github
"scripts": { "clean": "./node_modules/.bin/rimraf build", "build:webpack": "NODE_ENV=production ./node_modules/.bin/webpack --config webpack.config.prod.js", "build": "npm run clean && npm run build:webpack", "mock": "MOCK=true npm run start", "start": "./node_modules/node/bin/node server.js", "lint": "./node_modules/.bin/eslint src", "lintfix": "./node_modules/.bin/eslint src --fix", "daily": "npm run build && git add -A && git commit -am 'deploy test' && git branch -D daily/9.9.9 || true && git branch daily/9.9.9 && git push -f origin daily/9.9.9 && git reset --hard HEAD~" },
看裏面的反斜線,好像windows都不能用吖,只能本身搞個bat腳本封裝下,基本上再window下告別npm命令了web
echo "====start daily publish" call .\node_modules\.bin\rimraf build set NODE_ENV=production call .\node_modules\.bin\webpack --config webpack.config.prod.js call git add -A call git commit -m 'dailypublish' call git branch -D daily/9.9.9 call git branch daily/9.9.9 call git push -f origin daily/9.9.9 echo "====end daily publish"
3 最後吐槽一下發布和回滾問題sql
有段時間需求實在太多,團隊增長一個同窗一塊兒開發,注意下前端這塊,咱們都是用分支開發,發到預發的時候代碼是都要合併到daily9.9.9這個分支的,而後觸發一個鉤子,這個鉤子會把這9.9.9的代碼放到cdn上,就是2個會合用一個分支,預發環境常常是代碼被各類沖掉,這個後端的開發和發佈系統支持的就好,環境只有一個,可是每次發佈只能發一個分支。這樣能夠各類切換,而不是暴力的合併
另外,因爲後端代碼一次發佈可能會有屢次的前端發佈,因此前端的版本號實際上是和後端的版本號不一致的,若是線上出了故障,後端代碼進行回滾我可能準確的回滾到一個版本,可是前端代碼的版本號是跳躍的,很難回滾到後端同一時刻的版本
4 最後就是接口和代碼設計的問題
因爲先後端代碼是不一樣同窗開發的,當前端A同窗須要一個列表數據會跟後端B同窗要一個get接口,這時候B同窗提供一個接口服務返回一串數據給前端,我看過一個以前的代碼前端拿到這個數據活生生的在前端作了一個排序,各類map各類比較,其實這個在後端數據庫層面或者內存層面作一下很是簡單。
5 最後講講編譯問題
以前我手上還有一個項目,也是先後端代碼分開的,這個比較特殊,前端是GXT寫的,恩就是用java寫的EXT,寫前端的頁面的時候很是痛苦,GXT的編譯特別慢,有的時候改一個頁面編譯一下要1分鐘,另外發布的時候很是原始,寫好GXT的代碼把代碼打包成war包,而後copy出裏面的靜態頁面再放到後端代碼裏,後端代碼再打成war包進行發佈
相比如今來講現有項目已經很好了,前端寫好代碼push到指定分支上就能自動部署到cdn上,而後後端的vm直接讀取cdn上的靜態資源。可是後端的發佈每每要等cdn部署完畢才能真正生效,根本緣由仍是不是引得本地文件
由於實在感受如今本地開發模式效率有點低(真正項目裏咱們仍是要作先後端分離的哈),我花了2天的時間對現有的項目進行了一下改造,就是將先後端代碼合併起來,這裏就簡單的介紹下如何用再一個項目裏同時維護先後端代碼
這裏涉及到webpack打包操做,用mvn進行npm操做,前臺代碼的熱部署及前端代碼的合併分發
1 線上改造後的代碼結構
其中node是maven下運行npm的插件引入的,node_modules是前端依賴包(能夠理解成java中maven引入的本地倉庫),將原有的前端文件放到了webapp中
其中build是webpack打包生成的輸出文件,index頁面引用的就是這裏的合併後的js和css,app.js是前端的入口文件
其餘文件就是後臺和前端的配置文件了,前端的主要打包文件是webpack.config
2 定義npm的打包命令
"mydaily":".\\node_modules\\\\.bin\\webpack-dev-server --config webpack.config.js --inline ", #"mydaily":".\\node_modules\\\\.bin\\webpack --config webpack.config.js --hot --progress --colors --watch", "mybuild":".\\node_modules\\\\.bin\\webpack --config webpack.config.js --output-public-path /build/", "myclean": ".\\node_modules\\\\.bin\\rimraf .\\src\\main\\webapp\\build", "mystart": ".\\node_modules\\node\\bin\\node server.js",
其中mydaily定義的的是的本地開發模式,mybuild是打包線上發佈文件,myclean是清除文件,mystart是爲了兼容前端開發同窗保留的命令,直接用node本地啓動服務,固然還有一些其餘的調用eslint等輔助控件這裏就不一一列出了
3 本地開發模式下如何引用前端輸出的靜態資源呢
indexvm裏是這麼寫的
## <link rel="stylesheet" href="http://localhost:8080/build/style.css"/> ## <script src="http://localhost:8080/build/vendors.js"></script> ## <script src="http://localhost:8080/build/app.js"></script>
這裏有個關鍵的啓動命令,本地在npm的時候使用的是webpack-dev-server。這個命令能夠虛擬出一個服務,而且配置了熱加載,咱們能夠看到文件的publicpath配置的就是8080端口下的這個地址
output: { path: path.resolve(__dirname, 'src/main/webapp/build'), filename: '[name].js', publicPath: 'http://localhost:8080/build/', },
若是是線上發佈,就直接啓動webpack,將文件編譯好發佈到build文件夾
4 如何作前端資源熱加載的,這裏有2個地方要配置下
一是使用一個jsx的loader使用的react-hotloader
二是配置idea的自動監聽功能
這樣就能夠作到熱部署了
5 如何用maven維護npm的打包和編譯呢
這裏就要提到mavne下一個插件了frontend-maven-plugin,由於不管是線上aone打包仍是線下打包其實調用的都是mvn clean install命令,這時候會自動觸發這個插件中的命令,我本地的配置以下
<!--前端打包--> <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <version>1.0</version> <executions> <execution> <id>install node and npm</id> <goals> <goal>install-node-and-npm</goal> </goals> <configuration> <nodeVersion>v5.2.0</nodeVersion> <npmVersion>3.3.0</npmVersion> <nodeDownloadRoot>https://npm.taobao.org/mirrors/node/</nodeDownloadRoot> <npmDownloadRoot>http://registry.npmjs.org/npm/-/</npmDownloadRoot> </configuration> </execution> <execution> <id>npm install</id> <goals> <goal>npm</goal> </goals> <configuration> <arguments>install</arguments> </configuration> </execution> <execution> <id>npm run build</id> <goals> <goal>npm</goal> </goals> <configuration> <arguments>run mybuild</arguments> </configuration> </execution> </executions> </plugin>
這個插件會在maven命令執行的時候自動執行配置好的npm命令,因此在打包的時候就會自動觸發npm run mybuild命令打包最新的靜態資源到war包中,這樣就無需在引用cdn中的文件了
通過以上5部改造,基本上能夠實現先後端代碼同時維護和開發,保證了本地開發的效率。可是將來多端及服務化,先後端分離仍是大趨勢,咱們仍是要儘可能摒棄小做坊的開發模式,讓代碼在穩定的基礎上最大的保證開發效率。另外仍是要像全棧開發努力,由於不少功能前端作起來很容易,可是後端要寫一大堆不可維護的代碼來實現,有的時候前端要作很複雜的代碼,後端可能一個sql就搞定了。