Skip to content

Server-side JavaScript improvements [SPR-13508] #18086

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Sep 25, 2015 · 12 comments
Closed

Server-side JavaScript improvements [SPR-13508] #18086

spring-projects-issues opened this issue Sep 25, 2015 · 12 comments
Labels
has: votes-jira Issues migrated from JIRA with more than 10 votes at the time of import in: web Issues in web modules (web, webmvc, webflux, websocket) status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Sep 25, 2015

Sébastien Deleuze opened SPR-13508 and commented

Spring Framework 4.2.x introduced a generic support for script based templating suitable for any kind of script technology. The scope of this issue is to keep track of potential server-side javascript improvements.

Java to JSON object conversion

In the script template, the model object available on Javascript side is still a Java object. Most template engines requires to have a real JSON object instead of a Map, and a real JSON array instead of an Iterable. It should be useful to provide out of the box this functionality. A possible implementation is available here.

JS logging on server-side

Similarly to this Spring Boot proposed feature, it should be possible to provide a console.log() interceptor that will forward client side logs to your Java log appender.

Load easily file content from filesystem or classpath

Very useful to make it possible to implement easily nested template support for example.

Script loader extension

Provide a JS extension for script loader like System.js/Require.js that loads lazily a Javascript dependency from the classpath (instead of an Ajax request) in order to improve maintainability of such app.

EmberJS 2/Angular 2/React support

More helpers/guidance for Angular 2, EmberJS 2 or React universal/isomorphic applications.

Spring beans accessible on Javascript

Experiment about making Spring beans accessible from Javascript. Wildfly support for similar functionality seems worth to have a look.


Issue Links:

12 votes, 19 watchers

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues
Copy link
Collaborator Author

chanwook park commented

Hi!
I'm tried pre-compile partial with simple maven plugin with Dust.js, and very nice work.
(Thanks to Sébastien your suggestion)

Pre-compiled template is located specific folder, then I hope to ScriptTemplateView.setScripts(..) is support to load script in folder!
For example,

/resources/static
   + templates
       + partial-compiled
           + nav.js
           + header.js
           + footer.js 
       + template.html

ScriptTemplateView.setScripts("render.js", "static/templates/partial-compiled", ...) 

Is that possible?
thanks.

@spring-projects-issues
Copy link
Collaborator Author

Titus Cheung commented

This is very exciting. Would support for Angular 2 means we can actually pre-render a normal Angular 2 app within Nashorn and send the rendered HTML/CSS to browser? Am curious how we may achieve this because Nashorn only provides JavaScript support and doesn't implement the full browser DOM, event loop, timer, etc and neither env.js nor Avatar.js appears to be going anywhere. Thanks.

@spring-projects-issues
Copy link
Collaborator Author

Sébastien Deleuze commented

Initial discussion with Angular team about Nashorn support for rendering Angular 2 universal application on server-side.

@spring-projects-issues
Copy link
Collaborator Author

Sébastien Deleuze commented

After more thoughts, and given the fact that JavaScript frameworks like Angular 2 and Ember now provide native support for isomorphic applications for server-side rendering, I tend to think we should focus on trying to provide a way to integrate seamlessly with for example Angular Universal and Ember FastBoot.

The JavaScript router is a key part of Universal and Fastboot, and we should maybe have an architecture where Spring MVC (and Spring Web Reactive) handles requests for REST or Websocket endpoints, but also where HTML pages requests should be just forwarded to the JavaScript router bundled in Universal and Fastboot.

Dealing with routing/mapping on Spring side like we do currently in ScriptTemplateView is perfectly fine with JavaScript template engines as demonstrated in spring-react-isomorphic and spring-boot-sample-web-handlebars example apps, but with Angular 2 or Ember HTML page routing should be JavaScript framework responsability.

I think the best way to progress is to create a Spring Boot + Angular 2 universal support prototype as discussed in this Angular Universal Java support issue. Here is a draft decription of what this prototype could be:

  • A Spring Boot web application
  • Based on Spring Framework 5.0.0.BUILD-SNAPSHOT
  • JSON REST endpoints implemented with Spring MVC or Spring Web Reactive
  • Regular Angular 2 application in src/main/resources/static
  • Experiment with the 2 possible engines:
    • Nashorn (run natively on the JVM but some compatility issues with Angular 2)
    • J2V8 (Java binding for NodeJS)
  • Universal application support based on Angular Universal + some adaptations
  • Experiment about how to delegate the HTML pages to Angular 2 :
    • ScriptTemplateView + @RequestMapping with ** wildcard?
    • Dedicated handler (may be required for J2V8 since it does not support JSR223 yet)?
  • Define where such support should live:
    • Spring Framework?
    • Spring Boot?
    • Side project?
  • Provide some configuration via application.properties or via a JavaScript file
  • Benchmarks
  • Optimize static files access by avoiding using the classpath to serve them (needed for Spring Web Reactive zero copy support)

We could use this hello-angular2-universal-j2v8 as a starting point (especially the server.ts file), adding support for MacOS X, replace Spark by Spring Boot, see if Nashorn is a viable option or not, etc. If anybody is interested to work on such prototype, any help will be appreciated and could help to progress faster.

The other part where I would like to move forward is the JS logging extension to send logs in a Spring Boot actuator endpoint. The goal is to achieve that for the early Spring Boot 2.0 milestones, see this Spring Boot issue for more details.

As usual, any feedbacks is welcome. Keep in mind this is a topic where we really need to experiment and there is not commitment yet to include such support in Spring Framework 5.

@spring-projects-issues
Copy link
Collaborator Author

Patrick Grimard commented

Hi Sébastien, I've read over your latest comments and saw that you'd like to explore using J2V8 as a rendering engine. I've implemented such an example. You can find my GitHub repo here https://github.com/pgrimard/spring-j2v8. So far in my non-extensive example, performance seems to be quite good, but I haven't tried it with anything like React.

My repo contains a sample application, you'll also find a V8ScriptTemplateView implementation which uses J2V8 to render the view using the template and model, in a similar fashion to the existing ScriptTemplateView. I also have a V8ScriptTemplateViewResolver, V8ScriptTemplateConfig and V8ScriptTemplateConfigurer.

@spring-projects-issues
Copy link
Collaborator Author

Sébastien Deleuze commented

Patrick Grimard Thanks a lot for this great contribution. This could allow to experiment on rendering Isomorphic application using React, EmberJS or Angular Universal since such support is natively built to run on top of NodeJS. It is not a pure Java solution, but when it comes to such complex JavaScript serverside rendering use case, such tradeoff is maybe something worth to consider, especially if at some point they provide natively a JSR 223 support. See also the platform specific dependencies.

If you have the time to create a JSV8 based branch in your sample application coming from your awesome blog post, please let me know (nice to see you used Kotlin for the backend ^^).

@spring-projects-issues
Copy link
Collaborator Author

Patrick Grimard commented

I've just pushed the J2V8 branch to my other sample application https://github.com/pgrimard/spring-boot-react/tree/j2v8. I had to make some slight modifications to make it work. Most notable was in the V8ScriptTemplateView, instead of calling executeObjectScript against each script defined in the V8ScriptTemplateConfigurer, now I'm merely calling executeScript and only tracking results that are instances of V8Value to release later before releasing the V8 runtime. The reason for this is that when Webpack minifies the production bundle, the first character in the bundle is a ! which returns a boolean value, causing executeObjectScript to throw an exception. Calling executeScript simply returns an Object and I can check if that object is an instance of V8Value to determine if it needs to be released later or not.

@spring-projects-issues
Copy link
Collaborator Author

Patrick Grimard commented

Hi Sébastien, following a comment on my blog post about using i18n in script templates, I've added this support to the J2V8 branch of my project. It uses a custom ResourceBundleMessageSource implementation to allow fetching all messages of a given basename and locale, as a Java Map. The map then gets converted to a V8Object which is passed as a 3rd parameter to the JS render function. This could theoretically be applied to the existing ScriptTemplateView without too much fuss if you think this merits a pull request.

As a side note, I've updated the sample application. It now uses a AcceptHeaderLocaleResolver bean and a MappingResourceBundleMessageSource (my custom implementation). The resulting messages are stored in the Redux store both on the server side and client side scripts.

@spring-projects-issues
Copy link
Collaborator Author

Patrick Grimard commented

I have submitted a PR to add i18n support to ScriptTemplateView #1262

I had some issue rebasing after Codacy checked my code. My original PR 1261 got closed while I tried to sort out the mess I created. PR 1262 is a new one with the rebased code.

@spring-projects-issues
Copy link
Collaborator Author

Sébastien Deleuze commented

Interesting community driven project for server side render with Spring Boot and Angular 4 based on the J2V8 library : https://github.com/swaechter/angularj-ssr

@spring-projects-issues spring-projects-issues added type: enhancement A general enhancement has: votes-jira Issues migrated from JIRA with more than 10 votes at the time of import in: web Issues in web modules (web, webmvc, webflux, websocket) labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 5.x Backlog milestone Jan 11, 2019
@jhoeller jhoeller modified the milestones: 5.x Backlog, General Backlog Aug 24, 2020
@sdeleuze
Copy link
Contributor

With no update in 5 years and Nashorn now removed from the JDK, I think it is better to close this and stay unopinionated at Spring Framework level.

@sdeleuze sdeleuze removed this from the General Backlog milestone Jan 11, 2022
@sdeleuze sdeleuze added the status: declined A suggestion or change that we don't feel we should currently apply label Jan 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
has: votes-jira Issues migrated from JIRA with more than 10 votes at the time of import in: web Issues in web modules (web, webmvc, webflux, websocket) status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

3 participants