概述
傳統(tǒng)的JSP頁面應(yīng)用無法有效的使用ES6語法特性,項目打包壓縮困難伦籍,無法熱更新帖鸦。傳統(tǒng)的單頁應(yīng)用在Tomcat等容器下無法進行服務(wù)端渲染到達SEO的效果。本項目工程很好融合的傳統(tǒng)JSP頁面服務(wù)端渲染的特點和單頁應(yīng)用開發(fā)特性且極易上手使用!
源碼地址
Demos與文檔
特性
- 多頁應(yīng)用
- JSP嵌套
- el表達式
- 服務(wù)端渲染(SEO)
- 熱部署
- js,css語法轉(zhuǎn)換
- eslint
- 熱更新
- 支持Vue
- 打包壓縮
- IE9+
支持傳統(tǒng)JSP開發(fā)所的所有功能攻锰;可以通過自定義webpack配置來實現(xiàn)對react的支持变擒;通過引入vue-router和vuex某一個頁面完成可以變成一個單頁應(yīng)用娇斑。
如果您想要支持IE8毫缆,那需要把webpack降級苦丁,因為webpack2+是不支持IE8的,以及盡量避免去使用不支持IE8的庫蛾狗,比如jquery2+沉桌,lodash4+, Vue等,祝您好運蔼夜。
環(huán)境搭建
工欲善其事挎扰,必先利其器尽超。
- JDK1.7+
- IntelliJ IDEA似谁,需要安裝js相關(guān)插件和配置支持es6語法秃诵。
- Maven3+
- Tomcat7+菠净,端口默認請使用8080
- Git bash
- npm3+
- node7+
如果您喜歡編輯js和css的時候用vscode也是沒有問題牵咙,不過編寫jsp和java還是推薦用idea。
以下總結(jié)環(huán)境配置的相關(guān)文章另凌,可供參考
JDK下載地址
IntelliJ IDEA配置前端開發(fā)環(huán)境
IntelliJ IDEA配置JAVA WEB的Tomcat環(huán)境
maven下載安裝
Git Bash下載安裝
目錄說明
├── pom.xml // maven配置文件
├── src
| ├── main
| | ├── filters
| | | └── resources // java工程資源配置目錄
| | ├── java // java代碼目錄
| | ├── js // 前端頁面工程
| | | ├── build // 編譯相關(guān)以及webpack相關(guān)配置
| | | | ├── build.js
| | | | ├── check-versions.js
| | | | ├── logo.png
| | | | ├── utils.js
| | | | ├── webpack.base.conf.js
| | | | ├── webpack.dev.conf.js
| | | | └── webpack.prod.conf.js
| | | ├── config // 配置相關(guān)
| | | | ├── dev.env.js
| | | | ├── index.js
| | | | ├── js-jsp-map.js // 配置入口js和jsp的映射
| | | | └── prod.env.js
| | | ├── package.json // npm配置
| | | ├── src // web項目工程目錄
| | | | ├── pages // jsp頁面溪食,最終的jsp文件們會按照pages相對路徑打包進webapp/WEB-INF/jsp目錄下
| | | | | ├── include // 共享的jsp頁面栅组,通過jsp:include引入
| | | | | | ├── common_script.jsp
| | | | | | ├── footer.jsp
| | | | | | ├── header.jsp
| | | | | | ├── init.jsp
| | | | | | └── meta.jsp
| | | | | ├── index // 頁面1
| | | | | | ├── index.js // 需要在在config/js-jsp-map.js配置與jsp的映射關(guān)系,這樣編譯后的js會加載jsp的body下司浪。一般js與jsp在同一個目錄下。
| | | | | | └── index.jsp
| | | | | └── start // 頁面2
| | | | | ├── dashboard.css
| | | | | ├── index.js
| | | | | └── index.jsp
| | | | └── my-component.vue 支持VUE
| | | ├── polyfills 兼容相關(guān)的代碼
| | | | ├── console.js
| | | | ├── index.js
| | | | └── promise.js
| | | ├── static // 存在靜態(tài)文件,最終這些文件會拷貝到webapp目錄下
| | | | ├── favicon.ico
| | | | ├── images
| | | | | ├── jsp.svg
| | | | | └── webpack.svg
| | | | ├── js
| | | | | └── lib
| | | | | └── jquery.min.js
| | | | └── WEB-INF
| | | | ├── tld
| | | | └── web.xml
| | | └── styles
| | └── webapp // 該目錄下的文件不用開發(fā)人員手動添加修改窟却,在npm run dev或npm run build的時候自動生成。
| └── test
| └── java
src/main/js目錄下的目錄結(jié)構(gòu)是在vue-cli的webpack模板的基礎(chǔ)上修改的,如果您使用過該模板創(chuàng)建過項目,那么將很容易會上手揭绑。
開發(fā)
cd src/main/js
npm run dev
在idea中啟動tomcat
在瀏覽器中打開http://localhost:8081
以下幾點需要注意一下
首次啟動項目夸研,建議先npm run dev
在啟動tomcat悼沈。之后其中一個重啟,另外一個可以不用重啟。
默認情況下npm run dev
跑在8081端口下贮乳,tomcat跑在8080端口下。最終在瀏覽器訪問只需要訪問8081的頁面亲铡,8080頁面沒有必要讹堤。
開發(fā)模式下疑务,js引入的css是動態(tài)引入的叙谨,頁面會出現(xiàn)閃變的效果。不用擔(dān)心,在發(fā)布后的環(huán)境中是不會出現(xiàn)的。
開發(fā)jsp頁面的時候迷守,熱部署會有延時凯力,具體參看JSP頁面這一章節(jié)
開發(fā)jsp文件務(wù)必在pages目錄下開發(fā),切勿在webapp目錄下開發(fā)礼华。否則在切換到pages目錄下開發(fā)或者打包后或咐鹤,webapp下的jsp的文件會被覆蓋,導(dǎo)致修改的內(nèi)容丟失圣絮。
打包發(fā)布
npm run build
webapp作為輸出目錄祈惶,static中文件會拷貝到輸出目錄,pages目錄下的jsp文件會作為模板文件拷貝到webapp/WEB-INF/jsp目錄下,與jsp關(guān)聯(lián)的js入口會被合并壓縮后引入到j(luò)sp文件的body中捧请。jsp關(guān)聯(lián)的css會被抽離出一個單個的css文件引入的jsp文件head中凡涩。
如果您打包后的應(yīng)用的Application Context不是/, 比如是/app
,即訪問地址都是基于http://localhost:8080/app
疹蛉,那么打包的時候webpack的publicPath
參數(shù)記得配置/app活箕,且jsp頁面中所有的地址都需要帶上${pageContext.request.contextPath}/
,在該項目框架中可以簡寫為${ctx}/
JSP頁面
傳統(tǒng)的JSP是在src/main/webapp
下開發(fā)可款,在這個項目框架下開發(fā)jsp文件是在src/main/js/src/pages
下開發(fā)育韩。雖然開發(fā)目錄不一致,但依然擁有傳統(tǒng)jsp開發(fā)所有的特性闺鲸。
- 模板嵌套筋讨,比如使用
<jsp:include page=''></jsp:include>
或者<%@include file=""%>
- el表達式,
<c:set>
,<c:if>
,<c:forEach>
等都可以使用 - 嵌入Java代碼 比如使用
<% out.println("hello world"); %>
- 支持熱部署摸恍。配置好啟動tomcat相關(guān)參數(shù)悉罕。在修改完jsp保存文件后,約10秒后刷新頁面就可以看到頁面的變化误墓。如果等不及10秒或者頁面一直不刷新蛮粮,可以先點擊idea菜單
File->Syncronize>
同步文件(快捷鍵Ctrl+Alt+Y
),然后在點擊Run的左側(cè)第三個按鈕后選擇Update classes and resources
手動更新谜慌,之后就刷新頁面就可以看到最新出的頁面然想。
實際在npm run dev
的時候,pages目錄下的jsp會作為htmlWebpackPlugin插件的模板文件欣范,每次修改pages下的文件都會被輸出到webapp/WEB-INF/jsp
下的相對目錄变泄。需要了解具體原理,請前往核心章節(jié)
自定義標簽庫
除了標準的c, fmt, fn標簽庫外恼琼,您也可以自定義標簽庫妨蛹。
- 首先在static/WEB-INF/tld新建一個tld,比如elftld
- 然后jsp頁面引入晴竞,
<%@ taglib prefix="elf" uri="/WEB-INF/tld/elfunc.tld" %>
注意的是蛙卤,在jsp頁面的地址必須以/WEB-INF/開頭,而實際開發(fā)jsp的路徑是在js/src/pages
目錄下噩死,導(dǎo)致idea無法正常解析pages目錄下jsp中tld文件路徑颤难,在使用自定義標簽的時候也無法自動補全。不過可以正常運行已维,實際開發(fā)過程影響不大行嗤。如果您有更好的解決方案,請與我們聯(lián)系垛耳。
語法轉(zhuǎn)換
因為了使用了webpack作為打包工具栅屏,您可以輕松對js和css進行語法轉(zhuǎn)換飘千,目前支持:
- es6, stage-2
- postcss
- less, sass, scss 需要額外裝對應(yīng)的loader即可支持
熱更新
在開發(fā)單頁應(yīng)用的過程中,有一個很棒的特性就是熱更新栈雳,修改了js文件护奈,頁面實時就會觸發(fā)更新。
在此項目框架下甫恩,您依然可以享受到熱更新帶來的喜悅逆济,在您修改js和css的時候,頁面都會實時觸發(fā)更新磺箕。
VUE
該項目已經(jīng)默認支持Vue。這一章節(jié)也是用VUE編寫的抛虫,你可以盡情的享受VUE帶來的編碼的快樂松靡。
- 您可以給idea添加vue.js插件,這樣也可以直接使用.vue文件建椰。
- js和css的語法轉(zhuǎn)換在.vue文件中同樣適用雕欺。
核心
該項目融合了webpack和jsp兩者的特性實現(xiàn)了多頁應(yīng)用,這很酷棉姐。那到底是如何實現(xiàn)的呢屠列。這里我們從搭建項目遇到的問題來講講最核心的幾個問題是如何解決的。
HtmlWebpackPlugin
使用webpack實現(xiàn)多頁應(yīng)用伞矩,很容易聯(lián)想到配置多個entry入口笛洛,每一個entry對應(yīng)一個HtmlWebpackPlugin
。jsp文件作為HtmlWebpackPlugin
的模板文件乃坤,在entry的js在打包之后會插入到body下苛让。該項目也是按照這樣的搭建的。
這里有幾點需要注意
- HtmlWebpackPlugin解析jsp文件需要對應(yīng)的loader湿诊,需要在webpack中配置
{ test: /\.jsp$/, loader: 'raw-loader' }
狱杰,這里使用raw-loader
進行純文本拷貝。如果您有更適合jsp的loader厅须,那么您可以賦予jsp文件特多的特性仿畸。 - 因為jsp可以被嵌套,這些被嵌套的jsp朗和,并不是入口的jsp错沽。所有只有是入口的jsp在配合HtmlWebpackPlugin插件的會額外添加{inject: 'body'}參數(shù)
- 那如何規(guī)定哪些jsp是入口文件呢?我們是通過配置來約定entry的js與jsp的關(guān)聯(lián)關(guān)系例隆,配置文件在
config/js-jsp-map.js
中甥捺。
proxy反代
tomcat是跑在8080端口下的,webpack-dev-server是跑在8081端口下的镀层,是兩個不同應(yīng)用镰禾。那豈不是開發(fā)jsp要在tomcat下編寫調(diào)試皿曲,開發(fā)js在webpack-dev-server調(diào)試。這樣的話豈不是很麻煩吴侦。
慶幸的webpack-dev-server有一個proxy參數(shù)屋休,我們利用proxy把訪問webpack-dev-server的請求都反代到8080下。這樣實際開發(fā)過程中瀏覽器只要打開8081端口頁面就可以备韧。這樣就做到兼顧jsp服務(wù)端渲染的功能劫樟,以及webpack語法轉(zhuǎn)換,熱更新的功能织堂。tomcat只有在必要的時候重啟一下就好叠艳。
這里有幾點需要注意
-
npm run dev
和啟動tomcat并沒有順序要求,不過在瀏覽器訪問8081前需要把這兩個服務(wù)都啟動起來易阳。 - 當涉及到j(luò)sp文件有新增刪除附较,或者static目錄下的文件有新增編輯刪除時,需要重新
npm run dev
和重啟tomcat潦俺。記住一點拒课,如果有文件新增和刪除,最好都把這兩個服務(wù)都重啟一下肯定是沒有問題的事示。
WriteFilePlugin
我們知道webpack-dev-server是使用內(nèi)存中的文件系統(tǒng)早像。而jsp頁面最終是要發(fā)布到tomcat的,內(nèi)存中的jsp文件并不能被idea監(jiān)聽肖爵,這樣即使最終輸出的jsp發(fā)生改變也無法被deploy到tomcat卢鹦。
慶幸我們找到了一個webpack的插件WriteFilePlugin,它能強制把webpack-dev-server程序的輸出的文件寫到磁盤文件系統(tǒng)上遏匆。
這里有幾點需要注意
- 雖然通過WriteFilePlugin的jsp文件輸出到磁盤上了法挨,但是因為不是通過idea直接修改,idea還是無法立刻同步這些文件幅聘。idea同步并發(fā)布jsp文件會有10s的延遲凡纳。如果等不及10秒或者頁面一直不刷新,可以先點擊idea菜單File->Syncronize>同步文件(快捷鍵Ctrl+Alt+Y)帝蒿,然后在點擊Run的左側(cè)第三個按鈕后選擇Update classes and resources手動更新荐糜,之后就刷新頁面就可以看到最新出的頁面。
結(jié)語
這個思路其實不僅適用tomcat下的jsp多頁應(yīng)用葛超,同樣也是適用node作為服務(wù)器的多頁應(yīng)用暴氏。Enjoy it!