Repository navigation
"Unexpected token import" with angularfire2 on angular-cli, AOT, SSR, and firebase-functions #1073
Description
Has anyone done this? I'm stuck, would love some suggestions, or pointers if I'm missing something obvious or misunderstanding the problem.
Version info
Angular: 4.2.4
Firebase: 4.1.3
AngularFire: 4.0.0-rc1
Firebase-functions: 0.5.9
How to reproduce these conditions
Using AOT compiling, and server-side rendering, as described in this blagpost:
https://medium.com/@evertonrobertoauler/angular-4-universal-app-with-angular-cli-db8b53bba07d
Repo:
https://github.com/SparksNetwork/exp-angular-firebase/tree/shared-code
(note I am working from the shared-code branch)
(the repo structure is kind of haphazard, everything lives in /functions because thats what firebase-functions requires)
Steps to set up and reproduce
App runs successfully JIT running ng serve.
Compile client and server with ng run build.
Serve via standalone node express server with ts-node src/server.ts or via firebase-functions local emulator with firebase serve --only functions.
Debug output
FirebaseError: Error occurred while parsing your function triggers.
/Users/sdebaun/exp-angular-firebase/functions/node_modules/angularfire2/app/firebase.app.module.js:1
(function (exports, require, module, __filename, __dirname) { import { InjectionToken, } from '@angular/core';
^^^^^^
SyntaxError: Unexpected token import
at createScript (vm.js:53:10)
at Object.runInThisContext (vm.js:95:10)
at Module._compile (module.js:543:28)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
at Function.Module._load (module.js:439:3)
at Module.require (module.js:498:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/Users/sdebaun/exp-angular-firebase/functions/fn/dist/dist/ngfactory/src/app/app.server.module.ngfactory.js:23:13)
i functions: No HTTPS functions emulated. Support for other function types are coming soon.
Diagnosis
I suspect it's choking because the angularfire2 npm module is compiled with es2015 syntax which doesn't work in node (which firebase-functions is based on).
Possible fix?
I don’t know a lot about how NPM works, but I’m wondering if I:
- Fork angularfire2
- change the
targetand/ormodulesettings in forked tsconfig until I find something that works - in my app,
npm installfrom my forked angularfire2
Only thing I don’t know how to do there is: how do I ensure that my forked angularfire2 gets built? There’s a bunch of stuff in the repo that has to do with the build process that is totally alien to me.
The only other thing I can think of is to try to write my own firebase wrapper for angular, with blackjack and hookers that compiles to commonjs. That sounds like an awful idea.
Things I’ve Tried
Using DI to swap out AngularFire2 on server
Per the discussion in this thread (angular/universal-starter#127 (comment)), I started writing a fake service that adhered to the angularfire2 interfaces that I could use in my app.server.module.ts. Quickly I realized that because all my services actually have to import from the real angularfire2 module, it still wouldn’t work, because the error gets thrown when the file is imported, not when it’s run.
Copying angularfire2/src into a local lib directory and building it with the project
When I try this, I get all sorts of errors about Zone not being found. I can’t figure out what needs to be included, or how, in order to get it to compile the ts.
Activity
davideast commentedon Jul 21, 2017
@sdebaun I recently ran into this myself. I have a fix in the works but I just moved halfway across the country so my schedule is pretty jammed right now. I do expect to get something out next week.
There's a big overhaul needed in how we package these modules. We need a UMD bundle for each feature (auth, db) rather than one larger one. I'm looking into mimicking the structure that the main Angular repo uses with their package.json and tsconfig.files. A good example is with the HTTP module.
sdebaun commentedon Jul 25, 2017
@davideast thankyouthankyouthankyouthankyouthankyouthankyouthankyou! I was so excited that I got a client/server monorepo working with SSR, and then wanted to cry when I found out angularfire didn't play nicely.
So I should just hold off for a bit, eventually angularfire will work with ssr?
YOURETHEBEST!!!
justingrayston commentedon Jul 31, 2017
I've just run into this too trying out universal build with angular-cli, so would love to know what your work around was. I was going to try to build targeting commonjs and pull in to packages.json direct from my own branch. Alternatively I was thinking about swapping out for the firebase admin sdk using
getPlatformand some jigging about with the code.Both seemed horrid options atm, the later in particular.
I haven't tried either yet. I'll keep my fingers crossed, in the mean time I will continue to play if I get the chance.
davideast commentedon Jul 31, 2017
@justingrayston @sdebaun I'm close to a
nextrelease for this fix. If all goes well I'll be testing an Angular Universal build with the CLI. I'll keep you updated.KrGyan commentedon Aug 2, 2017
@davideast when can we expect this release. I am using "angularfire2": "^4.0.0-rc.1" with "firebase": "^4.2.0" . AOT with angular cli . I am getting the same issue.
E:\Angular\designcourse\angular-seo\node_modules\angularfire2\app\firebase.app.module.js:1
(function (exports, require, module, __filename, __dirname) { import { InjectionToken, } from '@angular/core';
^^^^^^
SyntaxError: Unexpected token import
at Object.exports.runInThisContext (vm.js:76:16)
at Module._compile (module.js:542:28)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at Object. (E:\Angular\designcourse\angular-seo\dist\ngfactory\src\app\app.server.module.ngfactory.ts:26:1)
at Module._compile (module.js:570:32)
Waiting eagerly for your positive response and next release as well. :)
sdebaun commentedon Aug 2, 2017
@justingrayston my workaround was... disable SSR until the fix is posted :)
KrGyan commentedon Aug 4, 2017
@davideast , does rc2 fixes this issue ?
davideast commentedon Aug 4, 2017
@sdebaun @justingrayston @KrGyan
Yes and no. Mostly no. #1088 fixed the problem that @sdebaun ran into. The Angular Compiler used deep imports to import the feature modules, when I needed to use the UMD bundle. I spent a lot of time getting the packaging of each module correct.
Now, if you use AngularFire2 with Angular Universal, there will be no errors*. However, the data will not render on the server. You'll get back
nullin your templates. This is because AngularFire2 uses the Firebase SDK which uses websockets. Websockets are long-lived persistent connections. Angular Universal doesn't know when this socket will end. I can fix this by wrapping the calls for Universal, but that will be another PR. I plan on working on that next week.*i think
MichaelSolati commentedon Aug 11, 2017
@davideast when you say that you intend to wrap the calls, how do you plan on doing so? I imagine there is the possibility to wrap the socket connection into an RxJS websocket but I imagine that would require a lot of work and wouldn't be the right approach... If you want though I would love to help you in any endeavor/steps you want to move forward with this!
SpeedoPasanen commentedon Aug 11, 2017
Is the data null because Universal isn't waiting or because it doesn't even open the socket? If the first case, for now, I could grab the master and force Universal to wait - with a mock HTTP req, timeout or sth, until I got the first data?
EreckGordon commentedon Aug 22, 2017
@davideast any progress with getting AngularFire2 to play nice with Universal?
SpeedoPasanen commentedon Sep 1, 2017
Got around the problem by providing firebase-admin to a FirebaseAdminService, then using that instead of Angularfire2 in a ServerDatabaseModule. Sorry, not a complete example but hope this gives you ideas:
https://gist.github.com/funkizer/6d6559787c17a88c60cf2ddc9ca06527
https://gist.github.com/funkizer/e162adff4191cae3c897e6bc5b7fd605
If you're hosting Universal on your own server, you might get away with not getting rid of all Angularfire2 stuff, but at least on Cloud Functions, you'll get ctor is not a constructor or other funny errors or timeouts because injectors fail, so I just got rid of everything related to FB client on server. Key thing is to run firebase-admin related things wrapped in zone.runOutsideAngular().
AnthonyNahas commentedon Sep 12, 2017
I fixed a similar problem in @ngx-translate/core. Please take a look to my comment
here.
or even better the full explanation
i did it locally too for the angularfire2 module.
I used the cli of babel to compile all js file into es5 - commonjs so that i can use them in nodejs (express) with angular universal --> finally no more SyntaxError: Unexpected token import!
iiAtlas commentedon Oct 3, 2017
Any fix for this?
patrickmichalina commentedon Oct 7, 2017
@davideast what is the timeframe for this? do you need any help with this? SSR is critical for the stuff we are building and I would love to use firebase for it.
12 remaining items
hiepxanh commentedon Nov 29, 2017
wow, you deserve this 🥇
I love that, finally, I can't wait to use this, thanks you for your initiative. That help me a lot and make my dream come true. I still didn't using any different database to only work with firebase
khalid-halo commentedon Dec 13, 2017
Looking forward to SSR support
hiepsieuviet commentedon Dec 14, 2017
well, without support for socket method from angular. We (angularfire, or anything use socket) cannot work with universal. That really bad news,
there are some investment in socket.io with ssr from angular universal but look like very slow. They are trying to doing something with ZoneMacroTaskWrapper but i don't understand.
Sir @jamesdaniels is trying to doing something different, Support Angular Universal he work with
service workerandxmlhttprequestto make our dream come true. I hope that work. 👍 everything I can help, you just mention, sir.hiepxanh commentedon Jan 21, 2018
still looking forward to make my web go production 👍 , event I have dedicated server, when calling to firebase, my data still not render with universal. I can't SEO
kpsrinivas commentedon Jan 31, 2018
Quick question - can this not be resolved using Cloud apis on server - https://cloud.google.com/firestore/docs/reference/rest/ . With isPlatformBrowser, isPlatformServer can't we control it ?
doczoidberg commentedon Feb 6, 2018
are there already results of an AngularFire Lite cooperation? When can we expect SSR in AngularFire?
ceolinwill commentedon Feb 6, 2018
@doczoidberg there's a pull request (#1454) for that, so probably soon :)
kpsrinivas commentedon Feb 8, 2018
"angularfire2": "^5.0.0-rc.6" seems to be working with ssr. Did anything change ?
andreaaschei commentedon Apr 13, 2018
@kpsrinivas were you able to make the ssr work with rc.6?
kpsrinivas commentedon Apr 13, 2018
@andreaaschei yes.
jamesdaniels commentedon Apr 13, 2018
anasbaddyr commentedon Apr 19, 2018
Seems to be working with RC.7 although some modifications are needed to the official universal guide if you're using material and other libraries in the server.ts file. Thanks @jamesdaniels and the team at angular firebase for the very helpful video highly recommend checking it out.
https://www.youtube.com/watch?v=wij2-gyG12E
Still will need to test it further but great job guys!
patrickmichalina commentedon Apr 19, 2018
SSR in the minimal sense. It still does not have state transfer nor does it have auth.
jamesdaniels commentedon Apr 19, 2018