WEBPACK + JSP 構(gòu)建多頁應(yīng)用

概述

傳統(tǒng)的JSP頁面應(yīng)用無法有效的使用ES6語法特性,項目打包壓縮困難伦籍,無法熱更新帖鸦。傳統(tǒng)的單頁應(yīng)用在Tomcat等容器下無法進行服務(wù)端渲染到達SEO的效果。本項目工程很好融合的傳統(tǒng)JSP頁面服務(wù)端渲染的特點和單頁應(yīng)用開發(fā)特性且極易上手使用!

源碼地址

源碼地址

Demos與文檔

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!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市绣张,隨后出現(xiàn)的幾起案子答渔,更是在濱河造成了極大的恐慌,老刑警劉巖侥涵,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沼撕,死亡現(xiàn)場離奇詭異宋雏,居然都是意外死亡,警方通過查閱死者的電腦和手機务豺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門磨总,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人笼沥,你說我怎么就攤上這事蚪燕。” “怎么了奔浅?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵馆纳,是天一觀的道長。 經(jīng)常有香客問我汹桦,道長厕诡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任营勤,我火速辦了婚禮,結(jié)果婚禮上壹罚,老公的妹妹穿的比我還像新娘葛作。我一直安慰自己,他們只是感情好猖凛,可當我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布赂蠢。 她就那樣靜靜地躺著,像睡著了一般辨泳。 火紅的嫁衣襯著肌膚如雪虱岂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天菠红,我揣著相機與錄音第岖,去河邊找鬼。 笑死试溯,一個胖子當著我的面吹牛蔑滓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播遇绞,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼键袱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了摹闽?” 一聲冷哼從身側(cè)響起蹄咖,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎付鹿,沒想到半個月后澜汤,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚜迅,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年银亲,在試婚紗的時候發(fā)現(xiàn)自己被綠了慢叨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡务蝠,死狀恐怖拍谐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情馏段,我是刑警寧澤轩拨,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站院喜,受9級特大地震影響亡蓉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜喷舀,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一砍濒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧硫麻,春花似錦爸邢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至浇辜,卻和暖如春券敌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背柳洋。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工待诅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人膳灶。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓咱士,卻偏偏與公主長得像,于是被迫代替她去往敵國和親轧钓。 傳聞我的和親對象是個殘疾皇子序厉,可洞房花燭夜當晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容

  • 寫在開頭 先說說為什么要寫這篇文章, 最初的原因是組里的小朋友們看了webpack文檔后, 表情都是這樣的: (摘...
    Lefter閱讀 5,273評論 4 31
  • 在現(xiàn)在的前端開發(fā)中,前后端分離毕箍、模塊化開發(fā)弛房、版本控制、文件合并與壓縮而柑、mock數(shù)據(jù)等等一些原本后端的思想開始...
    Charlot閱讀 5,431評論 1 32
  • 人的一生準能遇到一些人渣
    劉曉軍閱讀 227評論 0 0
  • 這個是因為蘋果解決Xcode ghost文捶。把插件屏蔽了荷逞。解決方法命令運行:sudo /usr/libexec/xp...
    Smallwolf_JS閱讀 238評論 0 0
  • 江南的水墨煙雨 北國的冰天雪地 塞北的馬頭琴音 巴蜀的肥魚 愛琴海的圣托里尼 美麗的西西里 以及 盛夏五月的你 這...
    魚丸粗面只要碗閱讀 121評論 0 0