Skip to content
New issue

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

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

Already on GitHub? # to your account

build(docs-infra): introduce prerendering for angular.io app's index.html and 404.html #10

Open
gkalpak opened this issue Sep 28, 2020 · 14 comments
Assignees
Labels
docs-infra Issues related to documentation infrastructure.

Comments

@gkalpak
Copy link
Collaborator

gkalpak commented Sep 28, 2020

Investigate enhancing the angular.io app's build process with prerendering (via @angular/platform-server/@nguniversal/express-engine) for:

  • /index.html
  • /404.html

Context regarding 404.html
Currently, a 404 page is generated for the angular.io app using a script, aio/scripts/build-404-page.js, which is invoked as part of the build process using the build-404-page npm script. The page is generated based on a hard-coded template, aio/src/404-body.html, which needs to be manually kept in sync with the actual page's style/layout.

NOTE 1: This is only about prerendering those two pages; it is not about introducing server-side rendering.

NOTE 2: This can be split up by a prerendered page.

Related resources:

@bampakoa bampakoa added the documentation Improvements or additions to documentation label Sep 29, 2020
@bampakoa bampakoa changed the title build(docs-infra): introduce prerendring for angular.io app's index.html and 404.html build(docs-infra): introduce prerendering for angular.io app's index.html and 404.html Oct 7, 2020
@gkalpak gkalpak added docs-infra Issues related to documentation infrastructure. and removed documentation Improvements or additions to documentation labels Oct 9, 2020
@gmavridakis
Copy link

Shall i try with your help always? :)

@gmavridakis
Copy link

Hello,

I am able to run in local the aio project but facing issues when trying to run pre-render.

More specifically based on 'Blogpost on prerendering with Angular Universal' I followed the below steps:

npx -p @angular/cli@next --> OK
ng add @nguniversal/express-engine@next --> OK
npm run prerender -- FAILS

[error] Error: Configuration 'production' is not set in the workspace.
at WorkspaceNodeModulesArchitectHost.getOptionsForTarget (C:\Users\gregm\Angular\contribution-angular\angular\aio\node_modules@angular-devkit\architect\node\node-modules-architect-host.js:83:27)
at core_1.experimental.jobs.createJobHandler.name (C:\Users\gregm\Angular\contribution-angular\angular\aio\node_modules@angular-devkit\architect\src\architect.js:172:21)
at Observable._subscribe (C:\Users\gregm\Angular\contribution-angular\angular\aio\node_modules@angular-devkit\core\src\experimental\jobs\create-job-handler.js:92:26)
at Observable._trySubscribe (C:\Users\gregm\Angular\contribution-angular\angular\aio\node_modules@angular-devkit\core\node_modules\rxjs\internal\Observable.js:44:25)
at Observable.subscribe (C:\Users\gregm\Angular\contribution-angular\angular\aio\node_modules@angular-devkit\core\node_modules\rxjs\internal\Observable.js:30:22)
at Object.innerSubscribe (C:\Users\gregm\Angular\contribution-angular\angular\aio\node_modules@angular-devkit\core\node_modules\rxjs\internal\innerSubscribe.js:102:23)
at SwitchMapSubscriber._innerSub (C:\Users\gregm\Angular\contribution-angular\angular\aio\node_modules@angular-devkit\core\node_modules\rxjs\internal\operators\switchMap.js:63:51)
at SwitchMapSubscriber._next (C:\Users\gregm\Angular\contribution-angular\angular\aio\node_modules@angular-devkit\core\node_modules\rxjs\internal\operators\switchMap.js:53:14)
at SwitchMapSubscriber.Subscriber.next (C:\Users\gregm\Angular\contribution-angular\angular\aio\node_modules@angular-devkit\core\node_modules\rxjs\internal\Subscriber.js:66:18)
at SwitchMapSubscriber.notifyNext (C:\Users\gregm\Angular\contribution-angular\angular\aio\node_modules@angular-devkit\core\node_modules\rxjs\internal\operators\switchMap.js:85:26)

Seems that the issue might be with the current version of @Angular-devkit

By testing the same guide in another test project it run without any issue so I tried to install same version of @Angular-devkit.

npm i @angular-devkit/build-angular@0.1002.0 --save
npm i zone.js

No luck.

So there are two questions:

  1. Any suggestion on the error - if ever faced again or how to proceed?
  2. Regarding the 404 page can you please advise on if there is any route for it? I searched for routing module but didn't find any. This will be needed to declare the prerendered route for 404 pages in anguar.json and not quite sure which route to use.
        "prerender": {
          "builder": "@nguniversal/builders:prerender",
          "options": {
            "browserTarget": "static-app:build:production",
            "serverTarget": "static-app:server:production",
            "routes": ["/" , "???? for 404 page"] // <-- Here you should put the routes you want to prender
          },

@gkalpak
Copy link
Collaborator Author

gkalpak commented Nov 1, 2020

Thx for looking into this, @gmavridakis!

  1. Regarding the error, as the error message says, the problem is that there is no production configuration for the build target. Instead, in angular.io we have the stable, next and archive configurations (which are equivalent to production). Therefore, you have to update the prerender configuration as follows:

     "prerender": {
       ...
       "options": {
    -    "browserTarget": "site:build:production",
    +    "browserTarget": "site:build:stable",
         "serverTarget": "site:server:production",
         ...
  2. Regarding the route for the 404 page, there is none (by definition 😁). Maybe you could try using a non-existent route (such as /404.html) and see what happens.

@gmavridakis
Copy link

gmavridakis commented Nov 1, 2020

Hi @gkalpak ,

It worked hopefully and now I am getting a new error when I am running with "routes": ["/"]:
npm run prerender

Prerendering 1 route(s) to C:\Users\gregm\Angular\contribution-angular\angular\aio\dist\site\browser
(node:12900) UnhandledPromiseRejectionWarning: ReferenceError: Element is not defined
at C:\Users\gregm\Angular\contribution-angular\angular\aio\dist\site\server\main.js:1:2812194
at Module.uj+Y (C:\Users\gregm\Angular\contribution-angular\angular\aio\dist\site\server\main.js:1:2812373)
at webpack_require (C:\Users\gregm\Angular\contribution-angular\angular\aio\dist\site\server\main.js:1:317)
at Object.0 (C:\Users\gregm\Angular\contribution-angular\angular\aio\dist\site\server\main.js:1:8631)
at webpack_require (C:\Users\gregm\Angular\contribution-angular\angular\aio\dist\site\server\main.js:1:317)
at /0p4 (C:\Users\gregm\Angular\contribution-angular\angular\aio\dist\site\server\main.js:1:2513)
at Object. (C:\Users\gregm\Angular\contribution-angular\angular\aio\dist\site\server\main.js:1:2558)
at Module._compile (internal/modules/cjs/loader.js:956:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:973:10)
at Module.load (internal/modules/cjs/loader.js:812:32)
(node:12900) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:12900) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Keep in note that compilation is completed without any issues but in final stage of prerendering it fails (I can confirm also due to the fact that no original file is generated under dist/browser)

With the help of @bampakoa we tried to investigate further where exactly the issue is and reached to this related issue:
angular/angular#27732

Any other suggestions? :D

@gkalpak
Copy link
Collaborator Author

gkalpak commented Nov 2, 2020

Aha! I think this is this known issue with @angular/elements and universal. It has been fixed in angular/angular#37799, which was released with 10.1.6 and 11.0.0-next.6 (see angular/angular#37799 (comment)).

However, angular.io is currently v10.1.3, so the fix is not available there. So, you need to wait for something like angular/angular#39441, that updates angular.io to newer versions.

In the meantime, you can try updating just the @angular/elements package to the latest version (i.e. update package.json > dependencies as shown below and run yarn --cwd=aio):

-    "@angular/elements": "10.1.3",
+    "@angular/elements": "10.2.1",

Let me know if that helps.

@bampakoa
Copy link

@gmavridakis we will be having another workshop next Thursday 😃 You are more than welcome to attend if you would like to continue working on the issue. We are here to help 👌 Let me know if you want so that I can send you a Zoom link for the event.

@gmavridakis
Copy link

Hi @bampakoa ,

As I am still working on the issue I will not attend this workshop.
I will update once I have the final findings or some help is needed.

Thanks

@gmavridakis
Copy link

Hi @gkalpak,

So I upgraded to the suggested version but still no luck - getting the same error so not sure if this is related to elements after all.

npm i @angular/elements@10.2.1 --save   
yarn --cwd=aio   
npm run prerender

If there is any other suggestion is more than welcome otherwise I will try to find related issues :)

Thanks

@gkalpak
Copy link
Collaborator Author

gkalpak commented Nov 28, 2020

I see that you used npm for updating (while the AIO projects uses yarn for dependency management). I am not sure if this may have messed things up. If not, then I am out of ideas, but feel free to put your code on a branch on your remote and I can take a look.

@gmavridakis
Copy link

@gkalpak here is the commited code..

Tried with yarn to be sure but I face the same error.

yarn add @angular/elements@10.2.1
yarn --cwd=aio
npm run prerender

Thanks

@gkalpak
Copy link
Collaborator Author

gkalpak commented Nov 28, 2020

Nice! I noticed that your commit is based on an older commit from master. Can you rebase your branch on top of the latest master commit (which uses v11 for angular.io)? (Before doing that make sure you get rid of the @angular/elements update to 10.2.1, since master is using a more recent version.)

If you are still getting the error, ping me here and I'll take a look.

@gmavridakis
Copy link

gmavridakis commented Nov 29, 2020

@gkalpak good news since there is progress :)

I rebased based on master branch which has angular 11 version as suggested and applied again current installation.
More specifically as you can see below I run again after the rebase:

yarn setup
ng add @nguniversal/express-engine
npm run prerender

Hopefully, in prerender command, there was no error related to promises as before so you were right it was related to version of Angular. Now the error I get is the below:

yarn setup
ng add @nguniversal/express-engine
npm run prerender0 info it worked if it ends with ok
1 verbose cli [
1 verbose cli 'C:\Program Files\nodejs\node.exe',
1 verbose cli 'C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js',
1 verbose cli 'run',
1 verbose cli 'prerender'
1 verbose cli ]
2 info using npm@6.14.8
3 info using node@v12.20.0
4 verbose run-script [ 'prerender' ]
5 info lifecycle angular.io@0.0.0prerender: angular.io@0.0.0
6 verbose lifecycle angular.io@0.0.0
prerender: unsafe-perm in lifecycle true
7 verbose lifecycle angular.io@0.0.0prerender: PATH: ....
8 verbose lifecycle angular.io@0.0.0
prerender: CWD: C:\Users\gregm\Documents\angular\aio
9 silly lifecycle angular.io@0.0.0prerender: Args: [ '/d /s /c', 'ng run site:prerender' ]
10 silly lifecycle angular.io@0.0.0
prerender: Returned: code: 1 signal: null
11 info lifecycle angular.io@0.0.0~prerender: Failed to exec prerender script
12 verbose stack Error: angular.io@0.0.0 prerender: ng run site:prerender
12 verbose stack Exit status 1
12 verbose stack at EventEmitter. (C:\Program Files\nodejs\node_modules\npm\node_modules\npm-lifecycle\index.js:332:16)
12 verbose stack at EventEmitter.emit (events.js:314:20)
12 verbose stack at ChildProcess. (C:\Program Files\nodejs\node_modules\npm\node_modules\npm-lifecycle\lib\spawn.js:55:14)
12 verbose stack at ChildProcess.emit (events.js:314:20)
12 verbose stack at maybeClose (internal/child_process.js:1022:16)
12 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:287:5)
13 verbose pkgid angular.io@0.0.0
14 verbose cwd C:\Users\gregm\Documents\aaa\angular\aio
15 verbose Windows_NT 10.0.18363
16 verbose argv "C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js" "run" "prerender"
17 verbose node v12.20.0
18 verbose npm v6.14.8
19 error code ELIFECYCLE
20 error errno 1
21 error angular.io@0.0.0 prerender: ng run site:prerender
21 error Exit status 1
22 error Failed at the angular.io@0.0.0 prerender script.
22 error This is probably not a problem with npm. There is likely additional logging output above.
23 verbose exit [ 1, true ]

Based on it I understand that the error is in command:
ng run site:prerender

So the error I am getting when running this command is:

× Prerendering routes to C:\Users\gregm\Documents\angular\aio\dist\site\browser failed.
Unable to render C:\Users\gregm\Documents\angular\aio\dist\site\browser\index.html.
Error: HTMLElement is not defined

Now I am focused in server.ts file to figure out why it cannot identify index.html!

Last but not least I committed again all my progress here.

Thanks in regards for your time :D

@gkalpak
Copy link
Collaborator Author

gkalpak commented Nov 30, 2020

Thx for the update, @gmavridakis 👍

I took a quick look and this seems to be a bug/incompatibility with elements and universal. The error comes from the fact that the abstract NgElement class (which extends HTMLElement) is defined eagerly in create-custom-element.ts. At the time when the file is loaded on the server, the global object is not yet extended with domino's implementations (which includes HTMLElement).

This is essentially a variation of angular/angular#24551.

Could you please open an issue on the angular/angular repo and provide a description of the problem (feel free to also include my description above) and minimal reproduction of the problem? 🙏

For the reproduction, you should create a branch that is on the same commit as the current master branch and add a commit with the changes introduced by running ng add @nguniversal-express-engine`. This is essentially what you have on your pre-render branch, but with all your commits squahsed into one.

(Feel free to ping me if you need any help with the process and I can also add additional context/details on the issue you will create, if needed.)

@gkalpak
Copy link
Collaborator Author

gkalpak commented Dec 3, 2020

For reference, here is the issue (reported by @juristr, who ran into the same problem): angular/angular#39950

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
docs-infra Issues related to documentation infrastructure.
Projects
None yet
Development

No branches or pull requests

3 participants