使用webjars + graalvm js 引擎增强业务处理

机制上比较简单,webjars 是利用了web 容器对于资源解析的特性
META-INF/resources 会自动解析处理,而且我们可以基于此模式实现js 的方便
打包以及版本化管理(这点webjars的设计比较到位),以下是一个简单的尝试,基于 graalvm js 的能力
我们可以比较灵活的扩展业务系统

核心代码

我们可以通过classloader 加载资源

 
public  static void scritLoad(Engine engine) throws IOException {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        URL url =  cl.getResource("META-INF/resources/webjars/jquery/3.5.1/jquery.js");
        Source mysource = Source.newBuilder("js",url).build();
        Context context = Context.newBuilder().allowHostClassLoading(true).allowIO(true).allowHostAccess(true).engine(engine).build();
        context.eval(mysource);
        Value callapp = context.getBindings("js").getMember("$");
        System.out.println(callapp.execute());
}

附加:基于spring resource 工具类加载

public static  void content() throws IOException {
        URL myfile =  ResourceUtils.getURL("classpath:META-INF/resources/webjars/jquery/3.5.1/jquery.js");
        InputStream inputStream = myfile.openStream();
        byte[] bytes = new byte[inputStream.available()];
        inputStream.read(bytes);
        String str = new String(bytes);
        inputStream.close();
        System.out.println(str);
}

webjars 开发说明

这个比较简单,核心还是按照webjars 的约定在打包阶段进行资源处理,我们可以在资源处理阶段进行管理,参考

<?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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.dalong-web</groupId>
    <artifactId>webjars</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <java.version>1.8</java.version>
        <package-version>1.0</package-version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <destinationDir>${project.build.outputDirectory}/META-INF/resources/platform/userlogin/${package-version}</destinationDir>
    </properties>
    <build>
        <resources>
            <resource>
                <directory>${project.basedir}/src/main/resources</directory>
                <targetPath>${destinationDir}</targetPath>
            </resource>
        </resources>
    </build>
</project>

说明

基于上边的我们可能发现不是很方便,因为我们的系统可能有多版本的(webjars 支持多版本模式),那么我们可以基于ClassGraph 来解决
同时webjars 中的静态资源我们可以使用browserify 进行构建打包,提示js的模块化水平,或者自定义包装也是可以的,实现一个自定义的require 机制
(nodyn/jvm-npm 是一个值得参考的方案),目前graalvm js已经支持了es 6 的模块机制(参考),理论上我们可以改写require 实现将资源的加载通过jar 中的内容获取(load 加载改写)
的文件(后边可以尝试下)

参考资料

https://github.com/classgraph/classgraph
https://www.webjars.org/
https://www.graalvm.org/reference-manual/js/JavaScriptCompatibility/
https://github.com/graalvm/graaljs/blob/master/docs/user/JavaScriptCompatibility.md
http://browserify.org/