WEBPACK + JSP 構建多頁應用

概述

傳統的JSP頁面應用沒法有效的使用ES6語法特性,項目打包壓縮困難,沒法熱更新。傳統的單頁應用在Tomcat等容器下沒法進行服務端渲染到達SEO的效果。本項目工程很好融合的傳統JSP頁面服務端渲染的特色和單頁應用開發特性且極易上手使用!css

源碼地址

源碼地址html

Demos與文檔

Demos與文檔前端

特性

  • 多頁應用
  • JSP嵌套
  • el表達式
  • 服務端渲染(SEO)
  • 熱部署
  • js,css語法轉換
  • eslint
  • 熱更新
  • 支持Vue
  • 打包壓縮
  • IE9+ 支持傳統JSP開發所的全部功能;能夠經過自定義webpack配置來實現對react的支持;經過引入vue-router和vuex某一個頁面完成能夠變成一個單頁應用。

若是您想要支持IE8,那須要把webpack降級,由於webpack2+是不支持IE8的,以及儘可能避免去使用不支持IE8的庫,好比jquery2+,lodash4+, Vue等,祝您好運。vue

環境搭建

工欲善其事,必先利其器。java

  • JDK1.7+
  • IntelliJ IDEA,須要安裝js相關插件和配置支持es6語法。
  • Maven3+
  • Tomcat7+,端口默認請使用8080
  • Git bash
  • npm3+
  • node7+

若是您喜歡編輯js和css的時候用vscode也是沒有問題,不過編寫jsp和java仍是推薦用idea。node

如下總結環境配置的相關文章,可供參考 JDK下載地址 IntelliJ IDEA配置前端開發環境 IntelliJ IDEA配置JAVA WEB的Tomcat環境 maven下載安裝 Git Bash下載安裝react

目錄說明

├── pom.xml   // maven配置文件
├── src
|  ├── main
|  |  ├── filters
|  |  |  └── resources // java工程資源配置目錄
|  |  ├── java // java代碼目錄
|  |  ├── js // 前端頁面工程
|  |  |  ├── build  // 編譯相關以及webpack相關配置
|  |  |  |  ├── build.js
|  |  |  |  ├── check-versions.js
|  |  |  |  ├── logo.png
|  |  |  |  ├── utils.js
|  |  |  |  ├── webpack.base.conf.js
|  |  |  |  ├── webpack.dev.conf.js
|  |  |  |  └── webpack.prod.conf.js
|  |  |  ├── config // 配置相關
|  |  |  |  ├── 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的映射關係,這樣編譯後的js會加載jsp的body下。通常js與jsp在同一個目錄下。
|  |  |  |  |  |  └── index.jsp
|  |  |  |  |  └── start // 頁面2
|  |  |  |  |     ├── dashboard.css
|  |  |  |  |     ├── index.js
|  |  |  |  |     └── index.jsp
|  |  |     |     └── my-component.vue 支持VUE
|  |  |     ├── polyfills 兼容相關的代碼
|  |  |     |  ├── console.js
|  |  |     |  ├── index.js
|  |  |     |  └── promise.js
|  |  |     ├── static // 存在靜態文件,最終這些文件會拷貝到webapp目錄下
|  |  |     |  ├── favicon.ico
|  |  |     |  ├── images
|  |  |     |  |  ├── jsp.svg
|  |  |     |  |  └── webpack.svg
|  |  |     |  ├── js
|  |  |     |  |  └── lib
|  |  |     |  |     └── jquery.min.js
|  |  |     |  └── WEB-INF
|  |  |     |     ├── tld
|  |  |     |     └── web.xml
|  |  |     └── styles
|  |  └── webapp // 該目錄下的文件不用開發人員手動添加修改,在npm run dev或npm run build的時候自動生成。
|  └── test
|     └── java
複製代碼

src/main/js目錄下的目錄結構是在vue-cli的webpack模板的基礎上修改的,若是您使用過該模板建立過項目,那麼將很容易會上手。jquery

開發

cd src/main/js npm run devwebpack

在idea中啓動tomcatgit

在瀏覽器中打開http://localhost:8081

如下幾點須要注意一下

首次啓動項目,建議先npm run dev在啓動tomcat。以後其中一個重啓,另一個能夠不用重啓。 默認狀況下npm run dev跑在8081端口下,tomcat跑在8080端口下。最終在瀏覽器訪問只須要訪問8081的頁面,8080頁面沒有必要。 開發模式下,js引入的css是動態引入的,頁面會出現閃變的效果。不用擔憂,在發佈後的環境中是不會出現的。 開發jsp頁面的時候,熱部署會有延時,具體參看JSP頁面這一章節 開發jsp文件務必在pages目錄下開發,切勿在webapp目錄下開發。不然在切換到pages目錄下開發或者打包後或,webapp下的jsp的文件會被覆蓋,致使修改的內容丟失。

打包發佈

npm run build

webapp做爲輸出目錄,static中文件會拷貝到輸出目錄,pages目錄下的jsp文件會做爲模板文件拷貝到webapp/WEB-INF/jsp目錄下,與jsp關聯的js入口會被合併壓縮後引入到jsp文件的body中。jsp關聯的css會被抽離出一個單個的css文件引入的jsp文件head中。

若是您打包後的應用的Application Context不是/, 好比是/app,即訪問地址都是基於http://localhost:8080/app,那麼打包的時候webpack的publicPath參數記得配置/app,且jsp頁面中全部的地址都須要帶上${pageContext.request.contextPath}/,在該項目框架中能夠簡寫爲${ctx}/

JSP頁面

傳統的JSP是在src/main/webapp下開發,在這個項目框架下開發jsp文件是在src/main/js/src/pages下開發。雖然開發目錄不一致,但依然擁有傳統jsp開發全部的特性。

  • 模板嵌套,好比使用<jsp:include page=''></jsp:include>或者<%@include file=""%>
  • el表達式,<c:set>, <c:if>, <c:forEach>等均可以使用
  • 嵌入Java代碼 好比使用<% out.println("hello world"); %>
  • 支持熱部署。配置好啓動tomcat相關參數。在修改完jsp保存文件後,約10秒後刷新頁面就能夠看到頁面的變化。若是等不及10秒或者頁面一直不刷新,能夠先點擊idea菜單File->Syncronize>同步文件(快捷鍵Ctrl+Alt+Y),而後在點擊Run的左側第三個按鈕後選擇Update classes and resources手動更新,以後就刷新頁面就能夠看到最新出的頁面。 實際在npm run dev的時候,pages目錄下的jsp會做爲htmlWebpackPlugin插件的模板文件,每次修改pages下的文件都會被輸出到webapp/WEB-INF/jsp下的相對目錄。須要瞭解具體原理,請前往核心章節

自定義標籤庫

除了標準的c, fmt, fn標籤庫外,您也能夠自定義標籤庫。

  • 首先在static/WEB-INF/tld新建一個tld,好比elftld
  • 而後jsp頁面引入,<%@ taglib prefix="elf" uri="/WEB-INF/tld/elfunc.tld" %>

注意的是,在jsp頁面的地址必須以/WEB-INF/開頭,而實際開發jsp的路徑是在js/src/pages目錄下,致使idea沒法正常解析pages目錄下jsp中tld文件路徑,在使用自定義標籤的時候也沒法自動補全。不過能夠正常運行,實際開發過程影響不大。若是您有更好的解決方案,請與咱們聯繫。

語法轉換

由於了使用了webpack做爲打包工具,您能夠輕鬆對js和css進行語法轉換,目前支持:

  • es6, stage-2
  • postcss
  • less, sass, scss 須要額外裝對應的loader便可支持

熱更新

在開發單頁應用的過程當中,有一個很棒的特性就是熱更新,修改了js文件,頁面實時就會觸發更新。 在此項目框架下,您依然能夠享受到熱更新帶來的喜悅,在您修改js和css的時候,頁面都會實時觸發更新。

VUE

該項目已經默認支持Vue。這一章節也是用VUE編寫的,你能夠盡情的享受VUE帶來的編碼的快樂。

  • 您能夠給idea添加vue.js插件,這樣也能夠直接使用.vue文件。
  • js和css的語法轉換在.vue文件中一樣適用。

核心

該項目融合了webpack和jsp二者的特性實現了多頁應用,這很酷。那究竟是如何實現的呢。這裏咱們從搭建項目遇到的問題來說講最核心的幾個問題是如何解決的。

HtmlWebpackPlugin

使用webpack實現多頁應用,很容易聯想到配置多個entry入口,每個entry對應一個HtmlWebpackPlugin。jsp文件做爲HtmlWebpackPlugin的模板文件,在entry的js在打包以後會插入到body下。該項目也是按照這樣的搭建的。 這裏有幾點須要注意

  • HtmlWebpackPlugin解析jsp文件須要對應的loader,須要在webpack中配置{ test: /\.jsp$/, loader: 'raw-loader' },這裏使用raw-loader進行純文本拷貝。若是您有更適合jsp的loader,那麼您能夠賦予jsp文件特多的特性。
  • 由於jsp能夠被嵌套,這些被嵌套的jsp,並非入口的jsp。全部只有是入口的jsp在配合HtmlWebpackPlugin插件的會額外添加{inject: 'body'}參數
  • 那如何規定哪些jsp是入口文件呢?咱們是經過配置來約定entry的js與jsp的關聯關係,配置文件在config/js-jsp-map.js中。

proxy反代

tomcat是跑在8080端口下的,webpack-dev-server是跑在8081端口下的,是兩個不一樣應用。那豈不是開發jsp要在tomcat下編寫調試,開發js在webpack-dev-server調試。這樣的話豈不是很麻煩。

慶幸的webpack-dev-server有一個proxy參數,咱們利用proxy把訪問webpack-dev-server的請求都反代到8080下。這樣實際開發過程當中瀏覽器只要打開8081端口頁面就能夠。這樣就作到兼顧jsp服務端渲染的功能,以及webpack語法轉換,熱更新的功能。tomcat只有在必要的時候重啓一下就好。 這裏有幾點須要注意

  • npm run dev和啓動tomcat並無順序要求,不過在瀏覽器訪問8081前須要把這兩個服務都啓動起來。
  • 當涉及到jsp文件有新增刪除,或者static目錄下的文件有新增編輯刪除時,須要從新npm run dev和重啓tomcat。記住一點,若是有文件新增和刪除,最好都把這兩個服務都重啓一下確定是沒有問題的。

WriteFilePlugin

咱們知道webpack-dev-server是使用內存中的文件系統。而jsp頁面最終是要發佈到tomcat的,內存中的jsp文件並不能被idea監聽,這樣即便最終輸出的jsp發生改變也沒法被deploy到tomcat。 慶幸咱們找到了一個webpack的插件WriteFilePlugin,它能強制把webpack-dev-server程序的輸出的文件寫到磁盤文件系統上。 這裏有幾點須要注意

  • 雖然經過WriteFilePlugin的jsp文件輸出到磁盤上了,可是由於不是經過idea直接修改,idea仍是沒法馬上同步這些文件。idea同步併發布jsp文件會有10s的延遲。若是等不及10秒或者頁面一直不刷新,能夠先點擊idea菜單File->Syncronize>同步文件(快捷鍵Ctrl+Alt+Y),而後在點擊Run的左側第三個按鈕後選擇Update classes and resources手動更新,以後就刷新頁面就能夠看到最新出的頁面。

結語

這個思路其實不只適用tomcat下的jsp多頁應用,一樣也是適用node做爲服務器的多頁應用。Enjoy it!

相關文章
相關標籤/搜索