swaechter / angularj-universal Goto Github PK
View Code? Open in Web Editor NEWThis project provides an experimental server side render for Spring Boot and Angular 5 based on the J2V8 library
This project provides an experimental server side render for Spring Boot and Angular 5 based on the J2V8 library
Does this project does have a future?
What about grpc?
This can be reproduced with the latest code (0.0.2) you have here.
You don't need to actually have lazy loading modules in your Angular application. Just run
$ npm install --save @nguniversal/module-map-ngfactory-loader
Then add ModuleMapLoaderModule
in the app.server.modules
imports array as documented in https://github.com/angular/angular-cli/wiki/stories-universal-rendering or https://angular.io/guide/universal.
Now clean build the whole application. When try to access any page, you will see the following error:
Exception in thread "Thread-22" /private/var/folders/rq/5l2f9vzn6ydf3phcsv1mtbk12wpc9s/T/serverbundle3877186372627513417tmp:2931: Error: StaticInjectorError[NgModuleFactoryLoader -> InjectionToken MODULE_MAP]:
StaticInjectorError(Platform: core)[NgModuleFactoryLoader -> InjectionToken MODULE_MAP]:
NullInjectorError: No provider for InjectionToken MODULE_MAP!
throw e;
^
Error: StaticInjectorError[NgModuleFactoryLoader -> InjectionToken MODULE_MAP]:
StaticInjectorError(Platform: core)[NgModuleFactoryLoader -> InjectionToken MODULE_MAP]:
NullInjectorError: No provider for InjectionToken MODULE_MAP!
at _NullInjector.get (/private/var/folders/rq/5l2f9vzn6ydf3phcsv1mtbk12wpc9s/T/serverbundle3877186372627513417tmp:2813:19)
at resolveToken (/private/var/folders/rq/5l2f9vzn6ydf3phcsv1mtbk12wpc9s/T/serverbundle3877186372627513417tmp:3111:24)
at tryResolveToken (/private/var/folders/rq/5l2f9vzn6ydf3phcsv1mtbk12wpc9s/T/serverbundle3877186372627513417tmp:3053:16)
at StaticInjector.get (/private/var/folders/rq/5l2f9vzn6ydf3phcsv1mtbk12wpc9s/T/serverbundle3877186372627513417tmp:2921:20)
at resolveToken (/private/var/folders/rq/5l2f9vzn6ydf3phcsv1mtbk12wpc9s/T/serverbundle3877186372627513417tmp:3111:24)
at tryResolveToken (/private/var/folders/rq/5l2f9vzn6ydf3phcsv1mtbk12wpc9s/T/serverbundle3877186372627513417tmp:3053:16)
at StaticInjector.get (/private/var/folders/rq/5l2f9vzn6ydf3phcsv1mtbk12wpc9s/T/serverbundle3877186372627513417tmp:2921:20)
at resolveNgModuleDep (/private/var/folders/rq/5l2f9vzn6ydf3phcsv1mtbk12wpc9s/T/serverbundle3877186372627513417tmp:12666:25)
at _createClass (/private/var/folders/rq/5l2f9vzn6ydf3phcsv1mtbk12wpc9s/T/serverbundle3877186372627513417tmp:12705:68)
at _createProviderInstance$1 (/private/var/folders/rq/5l2f9vzn6ydf3phcsv1mtbk12wpc9s/T/serverbundle3877186372627513417tmp:12677:26)
com.eclipsesource.v8.V8ScriptExecutionException
at com.eclipsesource.v8.V8._executeVoidFunction(Native Method)
at com.eclipsesource.v8.V8.executeVoidFunction(V8.java:1004)
at com.eclipsesource.v8.V8Object.executeVoidFunction(V8Object.java:418)
at ch.swaechter.angularjuniversal.v8renderer.V8RenderEngine.startWorking(V8RenderEngine.java:101)
at ch.swaechter.angularjuniversal.renderer.Renderer.lambda$startRenderer$0(Renderer.java:78)
at java.lang.Thread.run(Thread.java:748)
Hello,
I tried to follow the instructions to use this library with Angular 6. I was not able to make it work. Can you please update the doc with instructions to make it work with angular 6
With server side rendering all cyrillic characters in generated html are replaced with "?" At the same time, client-side rendering characters are displayed correctly. Any idea why this happens?
Windows 7
<dependency>
<groupId>com.eclipsesource.j2v8</groupId>
<artifactId>j2v8_win32_x86</artifactId>
<version>4.6.0</version>
</dependency>
<dependency>
<groupId>ch.swaechter</groupId>
<artifactId>angularj-universal-renderer-v8</artifactId>
<version>0.0.1</version>
</dependency>
Hi,
First of all, thank you for the tremendous effort you've put into this lib and please forgive me if my question is inappropriate as I mainly focus on the implementation detail of this issue.
I don't have much experience with front-end development as I'm mainly an Android developer, just side track into front-end to help develop an ad landing page for our app so a lot of these stuff is very new to me. We have just finished a basic Angular app and then got hit with this performance issue, very long load time on mobile device (~10ms) for the first page. I investigate a little bit and then came across Angular Universal, but the problem is our backend is in Java/ Spring so I would need to use the mentioned issue-1000 workaround.
I followed the main tutorial and got stuck at this step:
which is an example for Node Express server.
I kind of have a rough idea of putting the Usage Server section:
const socketEngine = require('@nguniversal/socket-engine');
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./dist/server/main');
socketEngine.startSocketEngine(AppServerModuleNgFactory);
into the server.ts
file.
And the Usage Client would somehow go into our Java backend.
If you don't mind would you please explain how could I do that in a noob-friendly way? :)
I need to get the request header server side, in my app.component. I tried the code below but does not work.
import { Request } from 'express';
import { REQUEST } from '@nguniversal/express-engine/tokens';
const lang = isPlatformServer(this.platformId) ?
this.request.headers['accept-language'] :
this.translateService.getBrowserLang();
I also tried with
injector. injector.get(REQUEST);
I have combed over your directions. I have solved most of my issues by rereading your post. Very thorough. But I have an angular 5 app integrated with your Spring Boot example. When I request the url I have configured I immediately get a login page. Cant seem to get around this issue. Any clue what Im doing wrong?
Add a logger hook in the J2V8 engine and capture all output (Normal output, warnings, errors and exceptions). The output is not capturable via System.out and hence the render engine has to provide logging methods.
In the next weeks I want to implement a live reloading feature. I have two loading strategies in mind:
If I missed a workflow, please leave a comment!
At the moment the transition from the server side rendered page to the client side page is not working. I am not sure if preboot.js is already integrated into Angular CLI 1.3.0, so I have to verify that first.
If you have a working server side/client side transition with Angular CLI 1.3.0 and Node.js, please post a link to the project (Reference).
Hi,
I would like to start with great thanks for your wonderful work.
I have a angular app with a Spring boot backend. I use your solution to implement SSR. The solution works great, but the first load takes about 1 minute. I don't really understand why.
On server start up, I have the following warning ;
Java HotSpot(TM) 64-Bit Server VM warning: You have loaded library /home/me/libj2v8_linux_x86_64.so which might have disabled stack guard. The VM will try to fix the stack guard now.
It's highly recommended that you fix the library with 'execstack -c <libfile>', or link it with '-z noexecstack'.
And the following logs when I try to reach "/".
[Error]
ERROR [Error]
ERROR [Error]
Any explanation of why my rendering takes too long ?
Thank you.
At the moment the render engine is used in combination with a Spring Boot application. In the future it should be also possible to use the render engine as a standalone library in other projects.
PS: Finding a good name for the GitHub project is always the most difficult thing, so if you have a good one please share it :)
I'm pleased to see your solution to provide a bridge between the popular Java framework Spring Boot and the popular front-end framework Angular. Your project will make it possible to just implement your application once -and render it both on the client and server side.
As of right now, the provided functionality will be sufficient for some simple websites: front-end application with a simple Java back-end. For those projects, the main requirement of this solution would be that it becomes tested and production-ready.
On the other hand, most websites with backend API's requires some sort of authentication. Therefore it would be great to implement Spring Security in the Spring Boot example - or at least have a discussion on how we could achieve such authentication.
Normally we could serve the Angular application and then use cookies or tokens to authenticate towards the back-end API. When a visitor refreshes the web page or follows a direct link, the Angular page will be rendered on the backend, without this knowledge. In my point of view, we should pass some information from the current request on the Angular application.
Hi
currently the ResourceProvider
API would create temp server.bundle.js
in user temp folder, but the code never clean the temp folders, see getServerBundle
function in ResourceProvider
class.
is it reasonable, can add delete method ?
Hi, I'm using the 0.0.1
version with SpringBoot and it works fine.
But when I test the LayLoading module, the server side would generate additional "0.server.js", and it's would fail(V8 cannot find the 0.server.js
file). It's due to the ResourceProvider
API only accept one server.bundle.js
file, so I need manually copy the 0.server.js
to the temp folder.
so, can let the ResourceProvider
constructor accept the server bundle folder ?
Hi
I'm trying to run my working spring-boot app in a docker container, but every time I run it, i get something similar to the below logs
OpenJDK 64-Bit Server VM warning: You have loaded library /root/libj2v8_linux_x86_64.so which might have disabled stack guard. The VM will try to fix the stack guard now.
It's highly recommended that you fix the library with 'execstack -c <libfile>', or link it with '-z noexecstack'.
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00000000003cf916, pid=6, tid=0x00007fedbd77aae8
#
# JRE version: OpenJDK Runtime Environment (8.0_181-b13) (build 1.8.0_181-b13)
# Java VM: OpenJDK 64-Bit Server VM (25.181-b13 mixed mode linux-amd64 compressed oops)
# Derivative: IcedTea 3.9.0
# Distribution: Custom build (Tue Oct 23 11:27:22 UTC 2018)
# Problematic frame:
# C 0x00000000003cf916
#
# Core dump written. Default location: /app/core or core.6
#
# An error report file with more information is saved as:
# /app/hs_err_pid6.log
#
# If you would like to submit a bug report, please include
# instructions on how to reproduce the bug and visit:
# http://icedtea.classpath.org/bugzilla
#
Segmentation fault (core dumped)
I've tried various base images, including openJDK 8u181 both alpine or non alpine, also openJDK 11 and tried tarent/openjdk-alpine-j2v8. It works when running the jar directly on my windows machine, but I just cant get it running in a docker container on a linux box.
Is there any know issues/solutions for this?
Following your guide, there is a TODO regarding enabling lazy loading. Is this working by now ?
@NgModule({
imports: [
AppModule,
ServerModule,
// ModuleMapLoaderModule // Add this line // TODO: Check how to add this line - lazy loading is at the moment not supported!
],
bootstrap: [AppComponent],
})
export class AppServerModule {
}
Use the memory manager that is provided by the J2V8 engine to simplify the memory management of the render engine. At the moment the release of the V8 engine is missing and hence memory is leaked.
The current project name spring-boot-angular-renderer is quite long and people might think it's only about Spring Boot. To reflect these problems I will rename the project into angularj-ssr.
After the rename I will also request a namespace in the Maven Central Repository to publish the project as library via Maven.
What are the steps necessary to run the project after pulling it?
At the moment the aggregation vs. inheritance in Maven is driving me insane. Maybe I am able to solve that problem with a more aggregation based build system, otherwise switching to Gradle might be an interesting thought. Link https://stackoverflow.com/questions/7502336/apache-maven-what-is-the-difference-between-inheritance-aggregation-and-depen?rq=1 (For example Spring Boot requires an own parent to get all plugin dependencies in Maven)
At the moment version 0.0.1 isn't published in Maven Central, so this is also the reason why @kweheliye had to add/hack the dependencies together.
At the moment the Spring Boot application uses a random port for testing. Because the Angular HTTP module has to work with absolute values, we have to provide the URL including port. At the moment they don't align during tests and need a fix.
Does the library overcome the known limitations for Angular Universal like "no-DOM manipulation" ?
I just came across graalvm & wanted to check whether graalvm can make our life simpler & improve performance when doing pre-rendering?
Thanks
Hey,
Would it be possible to build and push a 0.0.2 release to Maven?
I would like to be able to use the 'Make it possible to use several render engines in parallel' commit.
Add an HTTP AJAX call to the example to show the communication with the backend (In our case that is the same server as the render engine).
The Angular team published an interesting language-independent draft to offer render capabilities via TCP or gRPC. For more information see these links:
angular/universal#999
angular/universal#1000
angular/universal#1001
angular/universal#1002
angular/universal#1003
This is really cool and the plan is to write a TCP/gRPC renderer and take advantage of the ls-router
module to get all routes & use them in the Java middleware.
There's mention in the documentation of using wildcard routes but I'm not sure how this is done. Ideally I just want a simple one method controller to blanket handle all of my routes, but barring that even individual parameterized route examples would be helpful.
For example I have the route /person/:personId
in my Angular app. In the controller in my Spring app I'm trying
@GetMapping({"/person/{personId}"})
public ModelAndView showPersonDetail(HttpServletRequest request, @PathVariable("person") String personId) {
return new ModelAndView("/person/:personId");
}
and
@GetMapping({"/person/{personId}"})
public ModelAndView showPersonDetail(HttpServletRequest request, @PathVariable("person") String personId) {
return new ModelAndView("/person/" + personId);
}
With
angularjuniversal.routes=/,/person/:personId
In my application.properties file. Neither of them seem to be able to render the page on the server side with the data retrieved.
Edit: Updated for markdown formatting
Hi,
after we migrated to angular 8, we can't start java application. We have this errors message:
node.js:376
callback();
^
undefined:8: SyntaxError: Unexpected token {
This error only occurs when we start the java application with angular-universal activated.
Project is build without problems.
Do you have idea how to fix it?
Thank you.
"dependencies": { "@angular/animations": "8.2.0", "@angular/common": "8.2.0", "@angular/compiler": "8.2.0", "@angular/core": "8.2.0", "@angular/forms": "8.2.0", "@angular/platform-browser": "8.2.0", "@angular/platform-browser-dynamic": "8.2.0", "@angular/platform-server": "8.2.0", "@angular/router": "8.2.0", "@nguniversal/common": "^8.1.1", "@nguniversal/module-map-ngfactory-loader": "^8.1.1", "@nguniversal/socket-engine": "^8.1.1", "@ngx-translate/core": "^11.0.1", "classlist.js": "^1.1.20150312", "copy": "^0.3.2", "core-js": "^2.6.5", "del-cli": "^1.1.0", "localize-router": "^2.0.0-RC.2", "localize-router-http-loader": "^1.0.2", "npm": "^6.9.0", "prettier": "^1.17.0", "rxjs": "^6.4.0", "svgxuse": "^1.2.6", "tslib": "^1.9.0", "web-animations-js": "^2.3.2", "zone.js": "~0.9.1" }, "devDependencies": { "@angular-devkit/build-angular": "~0.802.0", "@angular/cli": "8.2.0", "@angular/compiler-cli": "8.2.0", "@angular/language-service": "8.2.0", "@types/jasmine": "~2.5.53", "@types/jasminewd2": "^2.0.6", "@types/node": "^6.14.4", "codelyzer": "^5.0.1", "jasmine-core": "~2.6.2", "jasmine-spec-reporter": "~4.1.0", "json-server": "^0.14.2", "karma": "^4.1.0", "karma-chrome-launcher": "~2.1.1", "karma-cli": "~1.0.1", "karma-coverage-istanbul-reporter": "^1.4.3", "karma-jasmine": "^1.1.2", "karma-jasmine-html-reporter": "^0.2.2", "protractor": "^6.0.0", "svg-sprite": "^1.5.0", "ts-loader": "^6.0.4", "ts-node": "3.x", "tslint": "^5.16.0", "typescript": "3.5.3", "uglifyjs-webpack-plugin": "^2.1.2", "webfont": "^8.2.1", "webpack-cli": "^3.3.7" }
At the moment the code base is not documented & tested well enough. More tests are required to reach a production level.
At the moment the render engine uses raw polling to handle incoming render requests. In idle, this creates unnecessary load which should be handled by a blocking queue.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.