把Web项目的前端资源打包成jar给项目引用

起因

用maven管理项目构建过程后,java部分已经有了很好的工程实践。但web静态资源仍处于复制粘贴的阶段,比较混乱。
前端工程化工具,比如webpack。但毕竟不是专职做前端的人员,感觉上手还不是那么容易。
无意看到了maven webjar的解决方案。

把前端静态资源做成jar包,直接给项目引用。
比如jquery,以前要拷贝到项目中来。
现在只用在pom.xml中引用

1
2
3
4
5
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>2.1.4</version>
</dependency>

在jsp中加入

1
<script src="/webjars/jquery/2.1.4/jquery.min.js"></script>

就可以直接引用,不用拷贝静态资源。

有这个思路,可以把自己项目中常用的静态资源,也打包成jar,放maven仓库中给自己使用。
又进一步简化了操作。

原理

在这样配置的框架中,会有下面的日志。相当于把指定路径下的请求变成了资源请求。

1
INFO 1100 --- [  restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]

servlet 3.0规定jar包中META-INF/resources文件夹下的文件,可以作为静态资源被引用。所以就有人把常见的web库用这种方式搞成了jar包,这样的话,web静态资源也能像Java库一样被直接引用了

如何操作

操作过程

创建maven工程

比如工程为test,目录结构如下

1
2
3
4
5
6
7
\TEST
│ pom.xml

└─src
└─main
└─resources
test.js

最简处理,这里有包含一个pom文件和一个需要打包到jar中的文件。

编辑pom文件

pom文件中也可以做最简处理。常规的groupId,artifactId,version,name之后呢。
重点要配置build下的resources节点。
完整的pom示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<groupId>com.fengcl</groupId>
<artifactId>test</artifactId>
<version>0.0.1</version>
<name>test</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<destinationDir>${project.build.outputDirectory}/META-INF/resources/webjars/${project.artifactId}/${project.version}</destinationDir>
</properties>
<build>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<targetPath>${destinationDir}</targetPath>
</resource>
</resources>
<plugins>
</plugins>
</build>
</project>

打包安装

运行mvn package进行打包。
会成target目录下生成test-0.0.1.jar文件
验证下有没有打包进去。
运行jar -tvf test-0.0.1.jar
会看到jar中目录结构为

1
2
3
4
5
6
7
8
9
10
11
12
   0 <time>  META-INF/
128 <time> META-INF/MANIFEST.MF
0 <time> META-INF/resources/
0 <time> META-INF/resources/webjars/
0 <time> META-INF/resources/webjars/test/
0 <time> META-INF/resources/webjars/test/0.0.1/
4 <time> META-INF/resources/webjars/test/0.0.1/test.js
0 <time> META-INF/maven/
0 <time> META-INF/maven/com.fengcl/
0 <time> META-INF/maven/com.fengcl/test/
1000 <time> META-INF/maven/com.fengcl/test/pom.xml
104 <time> META-INF/maven/com.fengcl/test/pom.properties

证明test.js已经打包进到jar中了。

然后进行安装

1
mvn isntall

这样就可以在别的工程中引用

测试验证

另新建一个spring-boot的maven工程
在pom文件中加入依赖

1
2
3
4
5
<dependency>
<groupId>com.fengcl</groupId>
<artifactId>test</artifactId>
<version>0.0.1</version>
</dependency>

在jsp中加入

1
<script src="/webjars/test/0.0.1/test.js"></script>

检测是否成功

上传到maven私服

现在是自己的机器上的项目都可以使用了,要让大家使用,就要上传到maven私服上。

step1

在pom.xml的节点中加入

1
2
3
4
5
6
7
8
9
10
11
12
<distributionManagement>
<snapshotRepository>
<id>snapshots</id>
<name>Nexus Snapshot Repository</name>
<url>http://192.168.2.47:8081/nexus/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>releases</id>
<name>Nexus Release Repository</name>
<url>http://192.168.2.47:8081/nexus/content/repositories/releases</url>
</repository>
</distributionManagement>

step2

修改maven的配置文件setting.xml
节点中加入

1
2
3
4
5
<server>
<id>releases</id> <!-- nexus仓库的ID,比如这里选的是releases仓库 -->
<username>deployment</username> <!-- 这里使用的是nexus的帐号:deployment,可以在nexus服务器管理 -->
<password>deployment123</password> <!-- deployment帐号默认密码: deployment123 -->
</server>

step3

执行mvn deploy

自己走的一些弯路

  • 先是直接打包,发现res目录下有,META-INF下没有
  • 想参考webjars把自己的文件打包成jar
  • overflow说这个是书上可以查到的,问题关闭
  • 查看jquery的pom文件,进行修改验证
  • 进行简化修改,可以打包安装成功
  • 引入项目的时候,报找不到,修改目录结构,再验证,还是找不到
  • 第二天再重新做了一次,用浏览器验证的时候,还是网络错误,找不到
  • 准备打断点跟踪这个地址的处理过程的,然后用curl访问,发现又可以了
  • 猜想浏览器缓存的原因?

由这些想到的总结。

  • 有一些常用组件,还是要去看看官方的文档,加自己做一些实验了解内部过程,必要要看看源代码实现。
  • 在这里找原因找错误,和以前做理科试验一样,猜想,验证,排除。

参考