Skip to content
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

Support Angular Universal (with CI job to test all components) #308

Closed
jeffbcross opened this issue Apr 14, 2016 · 127 comments
Closed

Support Angular Universal (with CI job to test all components) #308

jeffbcross opened this issue Apr 14, 2016 · 127 comments
Assignees
Labels
area: dev-infra Issue related to internal project infrastructure feature This issue represents a new feature or feature request rather than a bug or bug fix P2 The issue is important to a large percentage of users, with a workaround

Comments

@jeffbcross
Copy link

jeffbcross commented Apr 14, 2016

There's no automated verification that all material components are safe to use in node, i.e. pre-rendering with Angular Universal. See #306.

Proposal

Create a step in the CI process to pre-compile a single root component which contains an instance of each material component. Use one of the Angular Universal pre-render libraries to build: https://github.com/angular/universal/tree/master/modules

Note: I'm planning to submit a Broccoli plugin to that repo which would work well with Angular CLI.

I'm willing to help set this up.

@jelbourn jelbourn changed the title test: add CI step to test each component in pre-render build step with Angular Universal Add CI job to test all components in pre-render build step with Angular Universal Apr 14, 2016
@jelbourn jelbourn added the area: dev-infra Issue related to internal project infrastructure label Apr 14, 2016
@jelbourn jelbourn added this to the alpha.5 milestone Apr 14, 2016
@jelbourn jelbourn added P2 The issue is important to a large percentage of users, with a workaround feature This issue represents a new feature or feature request rather than a bug or bug fix labels Apr 14, 2016
@jelbourn jelbourn modified the milestones: alpha.6, alpha.5 May 19, 2016
@jelbourn jelbourn assigned jelbourn and unassigned kara Jun 27, 2016
@jelbourn jelbourn modified the milestones: alpha.6, alpha.7 Jun 27, 2016
@cyrilletuzi
Copy link
Contributor

cyrilletuzi commented Sep 14, 2016

To report one problem unsolved in #774 and #883, Material is not working with Universal for now because of many reference to window in Material umd bundles.

As proposed by @orangesoup, adding var window = undefined; in Material umd bundles do the trick for now, and then Universal and Material work very well together in my test app.

I looked at Material TypeScript source files, and found very few direct reference to window (and it's not the same as in umd bundles). So I think it is just a problem with the umd packaging system (maybe configured to target browsers). It's beyond my skills, but I think it's just a bundling option to change, and Material would already work with Universal.

@cyrilletuzi
Copy link
Contributor

Well I've been too optimist, the var window = undefined; is causing problems on client side, so I suppose it's not just a bundling problem.

But I'm quite surprise to see so many references to window, as we're supposed to avoid native dom and browser things inside Angular 2.

@cyrilletuzi
Copy link
Contributor

I confirm that window references causing problems with Universal are just in umd bundles, which all starts by this kind of code :

var __extends = (window && window.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var __decorate = (window && window.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (window && window.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};

I suppose this is polyfills, which are incorrectly checking on window, supposing a browser environment.

I don't know how the bundling is done so I can't help, but I think it's not a big deal to correct that. It's really blocking to not be able to use Universal with Material just because of this.

@PatrickJS
Copy link
Member

PatrickJS commented Sep 17, 2016

if you're using webpack you can use a string-replace-loader to fix the material2 package by replacing the string value of each file. I'll update the universal-starter to include it as an example

Tipe CMS

@cyrilletuzi
Copy link
Contributor

@gdi2290 Problem is server-side, so I don't use webpack, I directly launch the TypeScript code with ts-node.

@PatrickJS
Copy link
Member

PatrickJS commented Sep 17, 2016

if you use ts-node directly then you have to wait for an update or just include a fake window object for now

var window = global
global.window = window

I have the universal-starter updated to fix the material package during build
https://github.com/angular/universal-starter

Tipe CMS

@cyrilletuzi
Copy link
Contributor

@gdi2290 Thanks, global patching is working as a workaround for now.

Now I have another issue I already met before, and I have no idea where it comes from :

Error: This method is not implemented in Parse5DomAdapter: Parse5DomAdapter#getCookie
    at _notImplemented (/app/node_modules/angular2-platform-node/parse5-adapter.js:22:12)
    at Parse5DomAdapter.getCookie (/app/node_modules/angular2-platform-node/parse5-adapter.js:625:15)

@PatrickJS
Copy link
Member

PatrickJS commented Sep 17, 2016

can you make an issue about the Parse5DomAdapter#getCookie in the universal repo so not to spam this one. We can fix that one now with the newest Universal release

Tipe CMS

@cyrilletuzi
Copy link
Contributor

cyrilletuzi commented Sep 17, 2016

@gdi2290 But I'm not sure this is Universal or Material related, because with no Material, my app works just fine with Universal.

Issue created in Universal repo.

@cyrilletuzi
Copy link
Contributor

For the global patch workaround, just a note for other people interested, you need to do that :

var window = global;
global['window'] = window;

Doing global.window directly causes an error.

@orangesoup
Copy link

@gdi2290 @cyrilletuzi How did you manage to get material work though? I'm getting an error like this:

.../node_modules/@angular2-material/core/ripple/ripple.js:10
import { NgModule, Directive, ElementRef, HostBinding, Input } from '@angular/core';
^^^^^^
SyntaxError: Unexpected token import

It seems like there's no umd for rippe (or anything under core).

@JanStureNielsen
Copy link
Contributor

@orangesoup -- I removed ripple from my application...

tinayuangao pushed a commit that referenced this issue Aug 4, 2017
…trap (#6225)

* docs(hammerjs): new import location for Universal

As mentioned in #308, if hammerjs is imported in AppModule, Universal server-side rendering will fail as hammerjs is a browser specific library using window, document... So it must be imported in browser entry point src/main.ts instead.

* docs(hammerjs): new import location for Universal

As mentioned in #308, if hammerjs is imported in AppModule, Universal server-side rendering will fail as hammerjs is a browser specific library using window, document... So it must be imported in browser entry point src/main.ts instead.
crisbeto pushed a commit to crisbeto/material2 that referenced this issue Aug 5, 2017
…trap (angular#6225)

* docs(hammerjs): new import location for Universal

As mentioned in angular#308, if hammerjs is imported in AppModule, Universal server-side rendering will fail as hammerjs is a browser specific library using window, document... So it must be imported in browser entry point src/main.ts instead.

* docs(hammerjs): new import location for Universal

As mentioned in angular#308, if hammerjs is imported in AppModule, Universal server-side rendering will fail as hammerjs is a browser specific library using window, document... So it must be imported in browser entry point src/main.ts instead.
@joaogarin
Copy link

joaogarin commented Aug 7, 2017

Hello all,

Should MdSelect at this point work in universal? I am getting several issues with it but none with the other components.

ERROR { Error: Uncaught (in promise): TypeError: this._getHostElement(...).focus is not a function

and also

{ TypeError: this.trigger.nativeElement.getBoundingClientRect is not a function

@peterpeterparker
Copy link

peterpeterparker commented Aug 11, 2017

@maciejtreder you are right, just faced the same problem and then moved BrowserAnimationsModule to browser-app.module.ts without specifying anything in server-app.module.ts 👍

@peterpeterparker
Copy link

peterpeterparker commented Aug 11, 2017

@cyrilletuzi such a brillant idea to add hammer.js to main.browser.ts

btw. just gonna let that here, if someone is facing following error:

return window && document && document.all && !window.atob;

ReferenceError: window is not defined

it's probably, because like me, your are importing the css theme with style-loader in an import. in such case, the provided trick about hammer.js also applies, just move you import to main.browser.ts respectively

import 'style-loader!../node_modules/@angular/material/prebuilt-themes/indigo-pink.css';

@peterpeterparker
Copy link

peterpeterparker commented Aug 25, 2017

Importing MdTabsModule in one of my lazy modules result in the following error on the server side:

ERROR ReferenceError: requestAnimationFrame is not defined
    at /Users/me/Documents/project/dist/server.js:56104:13
    at ZoneDelegate.invoke (/Users/me/Documents/project/dist/server.js:115885:26)
    at Zone.run (/Users/me/Documents/project/dist/server.js:115635:43)
    at NgZone.runOutsideAngular (/Users/me/Documents/project/dist/server.js:4798:83)
    at MdInkBar.alignToElement (/Users/me/Documents/project/dist/server.js:56103:22)
    at MdTabHeader._alignInkBarToSelectedTab (/Users/me/Documents/project/dist/server.js:56919:22)
    at SafeSubscriber._next (/Users/me/Documents/project/dist/server.js:56658:23)
    at SafeSubscriber.__tryOrSetError (/Users/me/Documents/project/dist/server.js:607:16)
    at SafeSubscriber.next (/Users/me/Documents/project/dist/server.js:547:27)
    at Subscriber._next (/Users/me/Documents/project/dist/server.js:485:26)

Any one may have a tips how to solve that? Or is it a bug?

@julienR2
Copy link

requestAnimationFrame is a browser function, so you get this error when the server try to pre-render.
To solve this importe a polyfill in you server.main.ts.
You can use this one for example https://github.com/ngryman/raf.js/

@peterpeterparker
Copy link

peterpeterparker commented Aug 25, 2017

@julienR2 coolio thx, you are right that was the problem

I solved the problem like @johnnysainz suggested in following post #308

Respectively:

  1. Install raf

    npm install --save raf

  2. In main.server.ts added

    require('raf/polyfill');

@neilhem
Copy link

neilhem commented Sep 4, 2017

Is it possible to polyfill document, so Current document does not have a doctype. This may cause some Angular Material components not to behave as expected. will not occur on server side?

@fdambrosio
Copy link

hi, when we'll have a full support of Universal+Material on Angular?

@vikerman
Copy link
Contributor

The basic test for Angular Material support has been added. Please open individual issues for anything else you might encounter with using Angular material on the server.

@BlankHrt
Copy link

Hello, same problem with angular material universal
/Users/liuqinghua/workspace/example/activity-front/dist/ngfactory/node_modules/@angular/material/typings/index.ngfactory.ts:9
import * as i0 from '@angular/core';
^^^^^^
SyntaxError: Unexpected token import

The bug has existed for a long time ! No one has a good solution for it?

@galtalmor
Copy link

@BlankHrt see this comment for a solution that works around the issue.

@glemiere
Copy link

Same problem than @BlankHrt , hammerjs seems to have nothing to do with this error. I didn't import it anywhere, but I have the exact same error :
/dist/ngfactory/node_modules/@angular/material/typings/index.ngfactory.ts:9
import * as i0 from '@angular/core';
^^^^^^

SyntaxError: Unexpected token import

Any idea?

@julienR2
Copy link

julienR2 commented Sep 16, 2017

Hi ! I would need some info to help you out.

  • Do you have this error building in AOT ? (seeing the ngfactory folder I guess so). Does it work in JIT ?
  • Does it happen for any module from material you would use ? Or just the ToolBar as it happended also in some comments above
  • Can you share us you tsconfig ?

Hope we can figure out what's going on !

@tomerBZ
Copy link

tomerBZ commented Sep 16, 2017

@glemiere I am having the exact same issue here:

import * as i0 from '@angular/core';
^^^^^^

SyntaxError: Unexpected token import

I didn't import HammerJs anywhere.

@glemiere
Copy link

glemiere commented Sep 17, 2017

Hey guys!
For some reasons this repos works with material design, SSR and AOT. You can see it in action right here.

I think the problem is coming from a misconfiguration of the server side rendering in my (our) setup(s), because I've been able to fix this issue by double checking the official instructions.

I'm going to use this repo for my own needs, just to earn some time, it's a pretty good seed. Thanks to @JayChase for his answer on my stackoverflow post

@atmman9001
Copy link

Hey guys.

I need to render matDialog on the server side. I see that it's impossible for now because @angular/material uses the document object for the dialogs rendering.

Could you please tell me will you add possibility to render dialogs on the backend?

If yes please tell me do you have an idea when this changes will be released?

@jelbourn
Copy link
Member

We don't have plans to support overlay-based components rendering on the server at this time (dialogs, menus, etc.). For the vast majority of cases, these components are only rendered in response to user interaction

@atmman9001
Copy link

atmman9001 commented Oct 25, 2017 via email

@longhoang2984
Copy link

How about the error

Users/hoangcuulong/website-cli-beecow/dist/server.js:218913
    __extends(LoginFormModel, _super);
    ^

ReferenceError: __extends is not defined
    at /Users/hoangcuulong/website-cli-beecow/dist/server.js:218913:5
    at Object.../../../../../src/app/_models/login.model.ts (/Users/hoangcuulong/website-cli-beecow/dist/server.js:218920:2)
    at __webpack_require__ (/Users/hoangcuulong/website-cli-beecow/dist/server.js:164408:30)
    at Object.../../../../../src/app/_models/index.ts (/Users/hoangcuulong/website-cli-beecow/dist/server.js:218497:10)
    at __webpack_require__ (/Users/hoangcuulong/website-cli-beecow/dist/server.js:164408:30)
    at Object.../../../../../src/app/_shared/utils/beecow.utils.ts (/Users/hoangcuulong/website-cli-beecow/dist/server.js:224130:15)
    at __webpack_require__ (/Users/hoangcuulong/website-cli-beecow/dist/server.js:164408:30)
    at Object.../../../../../src/app/market/popup-location/popup-location.component.ts (/Users/hoangcuulong/website-cli-beecow/dist/server.js:229039:22)
    at __webpack_require__ (/Users/hoangcuulong/website-cli-beecow/dist/server.js:164408:30)
    at Object.../../../../../src/$$_gendir/app/market/popup-location/popup-location.component.ngfactory.ts (/Users/hoangcuulong/website-cli-beecow/dist/server.js:177242:10)

While I extends two Model?

@damienwebdev
Copy link

@jelbourn In reference to MatDialog, MatMenu, and render-only-on-interaction components, how are we supposed to properly handle this?

I couldn't quickly find any documentation on SSR with angular material, I checked here: https://material.angular.io/guides as well as on the component itself, https://material.angular.io/components/menu/overview

Additionally, in the given example, https://material.angular.io/components/menu/examples mat-menu fails on universal.

If you could give some guidance on what we're supposed to do, I'd happily write the guide and submit a PR.

@fdambrosio
Copy link

I agree with @damienwebdev
there's no docs about SSR and Material

@jelbourn
Copy link
Member

Closing this now since everything should mostly work with SRR this this point in time. Individual bugs can be tracked via standalone issues.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: dev-infra Issue related to internal project infrastructure feature This issue represents a new feature or feature request rather than a bug or bug fix P2 The issue is important to a large percentage of users, with a workaround
Projects
None yet
Development

No branches or pull requests