WEBPACK + JSP 构建多页应用

2018-01-19  本文已影响0人  star__light

概述

传统的JSP页面应用无法有效的使用ES6语法特性,项目打包压缩困难,无法热更新。传统的单页应用在Tomcat等容器下无法进行服务端渲染到达SEO的效果。本项目工程很好融合的传统JSP页面服务端渲染的特点和单页应用开发特性且极易上手使用!

源码地址

源码地址

Demos与文档

Demos与文档

特性

如果您想要支持IE8,那需要把webpack降级,因为webpack2+是不支持IE8的,以及尽量避免去使用不支持IE8的库,比如jquery2+,lodash4+, Vue等,祝您好运。

环境搭建

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

如果您喜欢编辑js和css的时候用vscode也是没有问题,不过编写jsp和java还是推荐用idea。

以下总结环境配置的相关文章,可供参考
JDK下载地址
IntelliJ IDEA配置前端开发环境
IntelliJ IDEA配置JAVA WEB的Tomcat环境
maven下载安装
Git Bash下载安装

目录说明

├── 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模板的基础上修改的,如果您使用过该模板创建过项目,那么将很容易会上手。

开发

cd src/main/js
npm run dev

在idea中启动tomcat

在浏览器中打开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开发所有的特性。

自定义标签库

除了标准的c, fmt, fn标签库外,您也可以自定义标签库。

注意的是,在jsp页面的地址必须以/WEB-INF/开头,而实际开发jsp的路径是在js/src/pages目录下,导致idea无法正常解析pages目录下jsp中tld文件路径,在使用自定义标签的时候也无法自动补全。不过可以正常运行,实际开发过程影响不大。如果您有更好的解决方案,请与我们联系。

语法转换

因为了使用了webpack作为打包工具,您可以轻松对js和css进行语法转换,目前支持:

热更新

在开发单页应用的过程中,有一个很棒的特性就是热更新,修改了js文件,页面实时就会触发更新。
在此项目框架下,您依然可以享受到热更新带来的喜悦,在您修改js和css的时候,页面都会实时触发更新。

VUE

该项目已经默认支持Vue。这一章节也是用VUE编写的,你可以尽情的享受VUE带来的编码的快乐。

核心

该项目融合了webpack和jsp两者的特性实现了多页应用,这很酷。那到底是如何实现的呢。这里我们从搭建项目遇到的问题来讲讲最核心的几个问题是如何解决的。

HtmlWebpackPlugin

使用webpack实现多页应用,很容易联想到配置多个entry入口,每一个entry对应一个HtmlWebpackPlugin。jsp文件作为HtmlWebpackPlugin的模板文件,在entry的js在打包之后会插入到body下。该项目也是按照这样的搭建的。
这里有几点需要注意

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只有在必要的时候重启一下就好。
这里有几点需要注意

WriteFilePlugin

我们知道webpack-dev-server是使用内存中的文件系统。而jsp页面最终是要发布到tomcat的,内存中的jsp文件并不能被idea监听,这样即使最终输出的jsp发生改变也无法被deploy到tomcat。
庆幸我们找到了一个webpack的插件WriteFilePlugin,它能强制把webpack-dev-server程序的输出的文件写到磁盘文件系统上。
这里有几点需要注意

结语

这个思路其实不仅适用tomcat下的jsp多页应用,同样也是适用node作为服务器的多页应用。Enjoy it!

上一篇下一篇

猜你喜欢

热点阅读