-
Notifications
You must be signed in to change notification settings - Fork 2.2k
SSR Angular Universal 12 and Firebase troubles #2877
-
Hi everyone,
Not sure if this is a bug for AngularFire to be honest, but this might be the case so, here it is.
I have an app which i could deploy with Angular 11 and Firebase.
I had to put in place the solution with protos described in #2686.
As you can see, the firestore-protos.ts
file returns file-loader?name=...
, which is a command for webpack 4, with the loader file-loader
.
But, in Angular 12, webpack 4 is gone, and we have webpack 5 support, awesome! But, the solution with dir-loader!./firestore-protos
simply doesn't work any more.
1st encountered issue:
I get this error:
./node_modules/dir-loader/index.js!./apps/website/firestore-protos.ts - Error: Module build failed (from ./node_modules/dir-loader/index.js):
TypeError: this.exec is not a function
at Object.module.exports (C:\Users\jct\code00円-wekicards\wekicards\node_modules\dir-loader\index.js:10:22)
And the line in the dir-loader
lib:
var options = this.exec(source, this.resource);
So, I've been looking for a solution for quite some time now and I really can't find anything on the subject.
I saw that in the sample
app example from angularfire
repo, @jamesdaniels removed the use of dir-loader, which seems a good option indeed.
What's the best workaround to do the same thing as the couple [dir-loader / file-loader] to load firestore protos ?
2nd encountered issue:
I also tried to just remove the use of dir-loader
by adding a list of externalDependencies
in the angular.json
file, just like this:
"externalDependencies": [
"firebase",
"@firebase/app",
"@firebase/firestore",
"@firebase/analytics",
"@firebase/auth",
"@firebase/functions",
"@firebase/installations",
"@firebase/messaging",
"@firebase/storage",
"@firebase/performance",
"@firebase/remote-config",
"@firebase/util"
],
But when I try this, I get another error when building my cloud function (well, it's more a Warning at first, but later on deployment it turns into an error):
WARNING in ./apps/functions/dist/website/server/fr/main.js 91:90
Module parse failed: The keyword 'let' is reserved (91:90)
File was processed with these loaders:
* ./node_modules/ts-loader/index.js
You may need an additional loader to handle the result of these loaders.
| constructor() { super(...arguments), this.overrides = { pinch: { enable: !1 }, rotate: { enable: !1 } }; }
| }
> exports.MyHammerConfig = MyHammerConfig, MyHammerConfig.\u0275fac = function () { let \u0275MyHammerConfig_BaseFactory; return function MyHammerConfig_Factory(t) { return (\u0275MyHammerConfig_BaseFactory || (\u0275MyHammerConfig_BaseFactory =
i0.\u0275\u0275getInheritedFactory(MyHammerConfig)))(t || MyHammerConfig); }; }(), MyHammerConfig.\u0275prov = i0.\u0275\u0275defineInjectable({ token: MyHammerConfig, factory: MyHammerConfig.\u0275fac });
| const customConfig = { include: ["facebook", "twitter", "whatsapp", "linkedin", "email", "sms"], gaTracking: !0, sharerMethod: ngx_sharebuttons_1.SharerMethod.Window };
| class AppModule {
WARNING in ./apps/functions/dist/website/server/en/main.js 91:90
Module parse failed: The keyword 'let' is reserved (91:90)
File was processed with these loaders:
* ./node_modules/ts-loader/index.js
You may need an additional loader to handle the result of these loaders.
| constructor() { super(...arguments), this.overrides = { pinch: { enable: !1 }, rotate: { enable: !1 } }; }
| }
> exports.MyHammerConfig = MyHammerConfig, MyHammerConfig.\u0275fac = function () { let \u0275MyHammerConfig_BaseFactory; return function MyHammerConfig_Factory(t) { return (\u0275MyHammerConfig_BaseFactory || (\u0275MyHammerConfig_BaseFactory =
i0.\u0275\u0275getInheritedFactory(MyHammerConfig)))(t || MyHammerConfig); }; }(), MyHammerConfig.\u0275prov = i0.\u0275\u0275defineInjectable({ token: MyHammerConfig, factory: MyHammerConfig.\u0275fac });
| const customConfig = { include: ["facebook", "twitter", "whatsapp", "linkedin", "email", "sms"], gaTracking: !0, sharerMethod: ngx_sharebuttons_1.SharerMethod.Window };
| class AppModule {
! functions: package.json indicates an outdated version of firebase-functions.
Please upgrade using npm install --save firebase-functions@latest in your functions directory.
=== Deploying to 'myproject-staging'...
i deploying functions
+ functions: Finished running predeploy script.
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
+ functions: required API cloudbuild.googleapis.com is enabled
+ functions: required API cloudfunctions.googleapis.com is enabled
i functions: preparing / directory for uploading...
Error: Error occurred while parsing your function triggers.
Error: Module parse failed: The keyword 'let' is reserved (91:90)
File was processed with these loaders:
* ./node_modules/ts-loader/index.js
You may need an additional loader to handle the result of these loaders.
| constructor() { super(...arguments), this.overrides = { pinch: { enable: !1 }, rotate: { enable: !1 } }; }
| }
> exports.MyHammerConfig = MyHammerConfig, MyHammerConfig.\u0275fac = function () { let \u0275MyHammerConfig_BaseFactory; return function MyHammerConfig_Factory(t) { return (\u0275MyHammerConfig_BaseFactory || (\u0275MyHammerConfig_BaseFactory =
i0.\u0275\u0275getInheritedFactory(MyHammerConfig)))(t || MyHammerConfig); }; }(), MyHammerConfig.\u0275prov = i0.\u0275\u0275defineInjectable({ token: MyHammerConfig, factory: MyHammerConfig.\u0275fac });
| const customConfig = { include: ["facebook", "twitter", "whatsapp", "linkedin", "email", "sms"], gaTracking: !0, sharerMethod: ngx_sharebuttons_1.SharerMethod.Window };
| class AppModule {
at Object.<anonymous> (C:\Users\jct\code\mypath\repo\dist\apps\functions\main.js:211:7)
at __webpack_require__ (C:\Users\jct\code\mypath\repo\dist\apps\functions\main.js:20:30)
at webpackContext (C:\Users\jct\code\mypath\repo\dist\apps\functions\main.js:190:9)
at C:\Users\jct\code\mypath\repo\dist\apps\functions\main.js:166:61
at Array.forEach (<anonymous>)
at Object.<anonymous> (C:\Users\jct\code\mypath\repo\dist\apps\functions\main.js:165:19)
at __webpack_require__ (C:\Users\jct\code\mypath\repo\dist\apps\functions\main.js:20:30)
at Object.<anonymous> (C:\Users\jct\code\mypath\repo\dist\apps\functions\main.js:121:52)
at __webpack_require__ (C:\Users\jct\code\mypath\repo\dist\apps\functions\main.js:20:30)
at Object.<anonymous> (C:\Users\jct\code\mypath\repo\dist\apps\functions\main.js:109:18)
The problem here is that the main.js files in the 'fr' or 'en' folder are all minified so I can't know exactly the origin of the problem.
A note: the functions
app is a node app in our monorepo, which contains the cloud functions to deploy.
And a reminder: everything deploys correctly with Angular Universal 11, and after upgrade to version 12, it stopped at build time for the Cloud Function part.
Also: I did manage to easily migrate all other apps from the monorepo from Angular 11 to Angular 12. All apps started locally, build, and deployed without trouble.
So, I really narrowed down to the problem to SSR Universal, with AngularFire and Firebase (which is kind of very large scope, i know ^^).
Version info
Angular: 12
Firebase: 8.6.1
AngularFire: 6.1.5
Node: 12.22.3 (same in 14.17.3)
** Windows 10 **
Other (e.g. Ionic/Cordova, Node, browser, operating system):
Expected behavior
I expect the SSR Universal to not broke the workflow, when dealing with those protos / dir-loader / webpack 5.
Actual behavior
It's a no go for now for the adoption of Angular 12, because of those points.
Beta Was this translation helpful? Give feedback.
All reactions
-
👀 1
Replies: 4 comments 3 replies
This comment has been hidden.
This comment has been hidden.
-
If you update your Firebase JS SDK to the latest version I don't think you need the proto-loader or to bundle the dependencies anymore. I'm going to be testing this more now that I'm back from leave.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
Thanks for your reply @jamesdaniels.
I've tried to do just that too in my trials. But then, I got into some issues about the functions
folder. For now, for our cloud functions, we have a node app in apps\functions
in which we build the Cloud Functions, and we're using a single package.json
to manage our Nx monorepo. The thing with the latest versions of Firebase, is that it expects to have a package.json
within the same folder as the functions
(if i remember well), which is not the case in our monorepo. So, quite uneasy migration for me.
But I'll give that a shot when I can.
Beta Was this translation helpful? Give feedback.
All reactions
-
Ah yeah, I've not done any work to support NX in the schematics & no doubt firebase CLI is unhappy too. If you get things working in NX LMK, would love for that to be on the happy path but I don't have the bandwidth to look into it myself.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
Sure.
What I know is that it's working with Angular 11.2.1 and Firebase 8.6.1, within a Nx 12.0.6 monorepo. The functions
folder for our Cloud Functions is a node app. We manage mulitple functional projects, each one with 2 or 3 staging environments with 2-3 firebase projects behind. Everything works fine.
On one of our project, we need to do SSR with i18n, and there comes the complexity, using Universal with Firebase Cloud Functions and i18n was quite tricky.
Up until now, I was able to migrate the whole stack for each version increment. But, this one is quite a bit tricky I have to say.
I also tried to use the experimental clover way for doing SSR instead of Universal, but I struggled with i18n... So for now, all tries and directions taken were dead ends... Hoping to find a way to innovation and better performances soon ^^.
Beta Was this translation helpful? Give feedback.
All reactions
-
Hi @jamesdaniels , I wonder if you had any time to investigate a bit in this blocking issue. From my side, I'll be able to test latest versions of firebase. What package from firebase should I update ? Only firebase ?
Beta Was this translation helpful? Give feedback.
All reactions
-
👀 1
-
Hi @JamesDaniel, I upgraded as suggested to latest version of firebase sdk and removed the code for dealing with protos, and added the externaldependencies within the angular.json
. Unfortunately, it ended up like this:
✔ Server application bundle generation complete.
✔ Localized bundle generation complete.
Initial Chunk Files | Names | Size
main.js | main | 10.21 MB
| Initial Total | 10.21 MB
Lazy Chunk Files | Names | Size
682.js | - | 170 bytes
977.js | - | 170 bytes
Build at: 2021年08月04日T09:22:28.196Z - Hash: b98510291ad31142d487 - Time: 89449ms
Warning: C:/Users/jct/code/path/apps/website/firestore-protos.ts is part of the TypeScript compilation but it's unused.
Add only entry points to the 'files' or 'include' properties in your tsconfig.
> wekicards@0.8.0 lint:functions C:\Users\jct\code\path
> npm run lint functions
> wekicards@0.8.0 lint C:\Users\jct\code\path
> nx workspace-lint && ng lint "functions"
TSLint's support is discontinued and we're deprecating its support in Angular CLI.
To opt-in using the community driven ESLint builder, see: https://github.com/angular-eslint/angular-eslint#migrating-an-angular-cli-project-from-codelyzer-and-tslint.
Linting "functions"...
All files pass linting.
src C:\Users\jct\code\path/dist/website
copy C:\Users\jct\code\path/apps/functions/dist/website
> wekicards@0.8.0 build:asprod:functions:forWebsite C:\Users\jct\code\path
> node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng build functions -c=production,wkc-website
> NX Using webpack 5. Reason: detected version 5 in node_modules/webpack/package.json
Found an outdated version of webpack-node-externals
If you want to use webpack 5, try installing compatible versions of the plugins.
See: https://nx.dev/guides/webpack-5
> NX Falling back to webpack 4 due to incompatible plugin versions
Hash: 294d8063e08956cb2bc9
Built at: 08/04/2021 11:24:33
Entrypoint main = main.js
chunk {0} main.js (main) 44.8 KiB [entry] [rendered]
WARNING in ./apps/functions/dist/website/server/en/main.js 96:90
Module parse failed: The keyword 'let' is reserved (96:90)
File was processed with these loaders:
* ./node_modules/ts-loader/index.js
You may need an additional loader to handle the result of these loaders.
| constructor() { super(...arguments), this.overrides = { pinch: { enable: !1 }, rotate: { enable: !1 } }; }
| }
> exports.MyHammerConfig = MyHammerConfig, MyHammerConfig.\u0275fac = function () { let \u0275MyHammerConfig_BaseFactory; return function MyHammerConfig_Factory(t) { return (\u0275MyHammerConfig_BaseFactory || (\u0275MyHammerConfig_BaseFactory = i0.\u0275\u0275getInheritedFactory(MyHammerConfig)))(t || MyHammerConfig); }; }(), MyHammerConfig.\u0275prov = i0.\u0275\u0275defineInjectable({ token: MyHammerConfig, factory: MyHammerConfig.\u0275fac });
| const customConfig = { include: ["facebook", "twitter", "whatsapp", "linkedin", "email", "sms"], gaTracking: !0, sharerMethod: ngx_sharebuttons_1.SharerMethod.Window };
| class AppModule {
WARNING in ./apps/functions/dist/website/server/fr/main.js 96:90
Module parse failed: The keyword 'let' is reserved (96:90)
File was processed with these loaders:
* ./node_modules/ts-loader/index.js
You may need an additional loader to handle the result of these loaders.
| constructor() { super(...arguments), this.overrides = { pinch: { enable: !1 }, rotate: { enable: !1 } }; }
| }
> exports.MyHammerConfig = MyHammerConfig, MyHammerConfig.\u0275fac = function () { let \u0275MyHammerConfig_BaseFactory; return function MyHammerConfig_Factory(t) { return (\u0275MyHammerConfig_BaseFactory || (\u0275MyHammerConfig_BaseFactory = i0.\u0275\u0275getInheritedFactory(MyHammerConfig)))(t || MyHammerConfig); }; }(), MyHammerConfig.\u0275prov = i0.\u0275\u0275defineInjectable({ token: MyHammerConfig, factory: MyHammerConfig.\u0275fac });
| const customConfig = { include: ["facebook", "twitter", "whatsapp", "linkedin", "email", "sms"], gaTracking: !0, sharerMethod: ngx_sharebuttons_1.SharerMethod.Window };
| class AppModule {
! functions: package.json indicates an outdated version of firebase-functions.
Please upgrade using npm install --save firebase-functions@latest in your functions directory.
=== Deploying to 'project-staging'...
i deploying functions
+ functions: Finished running predeploy script.
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
+ functions: required API cloudbuild.googleapis.com is enabled
+ functions: required API cloudfunctions.googleapis.com is enabled
i functions: preparing / directory for uploading...
Error: Error occurred while parsing your function triggers.
Error: Module parse failed: The keyword 'let' is reserved (96:90)
File was processed with these loaders:
* ./node_modules/ts-loader/index.js
You may need an additional loader to handle the result of these loaders.
| constructor() { super(...arguments), this.overrides = { pinch: { enable: !1 }, rotate: { enable: !1 } }; }
| }
> exports.MyHammerConfig = MyHammerConfig, MyHammerConfig.\u0275fac = function () { let \u0275MyHammerConfig_BaseFactory; return function MyHammerConfig_Factory(t) { return (\u0275MyHammerConfig_BaseFactory || (\u0275MyHammerConfig_BaseFactory = i0.\u0275\u0275getInheritedFactory(MyHammerConfig)))(t || MyHammerConfig); }; }(), MyHammerConfig.\u0275prov = i0.\u0275\u0275defineInjectable({ token: MyHammerConfig, factory: MyHammerConfig.\u0275fac });
| const customConfig = { include: ["facebook", "twitter", "whatsapp", "linkedin", "email", "sms"], gaTracking: !0, sharerMethod: ngx_sharebuttons_1.SharerMethod.Window };
| class AppModule {
at Object.<anonymous> (C:\Users\jct\code\path\dist\apps\functions\main.js:211:7)
at __webpack_require__ (C:\Users\jct\code\path\dist\apps\functions\main.js:20:30)
at webpackContext (C:\Users\jct\code\path\dist\apps\functions\main.js:190:9)
at C:\Users\jct\code\path\dist\apps\functions\main.js:166:61
at Array.forEach (<anonymous>)
at Object.<anonymous> (C:\Users\jct\code\path\dist\apps\functions\main.js:165:19)
at __webpack_require__ (C:\Users\jct\code\path\dist\apps\functions\main.js:20:30)
at Object.<anonymous> (C:\Users\jct\code\path\dist\apps\functions\main.js:121:52)
at __webpack_require__ (C:\Users\jct\code\path\dist\apps\functions\main.js:20:30)
at Object.<anonymous> (C:\Users\jct\code\path\dist\apps\functions\main.js:109:18)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
From main.js
(line 166):
SUPPORTED_LOCALES.forEach((locale) => {
const translatedAppServerModule = __webpack_require__(7)(`./${locale}/main.js`);
server.use(`/${locale}`, translatedAppServerModule.app(locale));
});
exports.globalSsr = functions.https.onRequest(server);
What I find odd is that the output of server
generation is that I now have 2 files of 170 bytes (682.js and 977.js) in the /dist/website/server/${locale}/
folder.
With the same build, at server
target, I had 2 files for firebase-auth.js
, and firebase-vendors.js
.
More over, to get to this point I added in angular.json
the external dependencies for the server
target, the same as @JamesDaniel in the sample
folder. I therefore removed all logic with dir-loader
and firestore-protos
.
I also, as suggested, updated to latest version my firebase
sdk (v8.8.1).
The version of firebase-functions
is 3.13.2.
Yesterday, I updated to latest version of nrwl/nx (v.12.3.6). Initially, I was with 12.0.6.
I also checked the proposed link for debug from NX https://nx.dev/guides/webpack-5, and tried to install webpack-5 plugins for node apps, as the functions
app is a node app: npx nx g @nrwl/node:webpack5
. This failed to install anything.
[error] Error: Cannot find module 'webpack'
Require stack:
- C:\Users\jct\code\path\node_modules\@angular-devkit\build-webpack\src\webpack\index.js
- C:\Users\jct\code\path\node_modules\@angular-devkit\build-webpack\src\index.js
- C:\Users\jct\code\path\node_modules\@angular-devkit\build-angular\src\browser\index.js
- C:\Users\jct\code\path\node_modules\@angular\cli\node_modules\@angular-devkit\architect\node\node-modules-architect-host.js
- C:\Users\jct\code\path\node_modules\@angular\cli\node_modules\@angular-devkit\architect\node\index.js
- C:\Users\jct\code\path\node_modules\@angular\cli\models\architect-command.js
- C:\Users\jct\code\path\node_modules\@angular\cli\commands\build-impl.js
- C:\Users\jct\code\path\node_modules\@angular\cli\node_modules\@angular-devkit\schematics\tools\export-ref.js
- C:\Users\jct\code\path\node_modules\@angular\cli\node_modules\@angular-devkit\schematics\tools\index.js
- C:\Users\jct\code\path\node_modules\@angular\cli\utilities\json-schema.js
- C:\Users\jct\code\path\node_modules\@angular\cli\models\command-runner.js
- C:\Users\jct\code\path\node_modules\@angular\cli\lib\cli\index.js
- C:\Users\jct\code\path\node_modules\@angular\cli\lib\init.js
- C:\Users\jct\code\path\node_modules\@angular\cli\bin\ng
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15)
at Function.Module._load (internal/modules/cjs/loader.js:667:27)
at Module.require (internal/modules/cjs/loader.js:887:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object.<anonymous> (C:\Users\jct\code\path\node_modules\@angular-devkit\build-webpack\src\webpack\index.js:37:35)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Module.require (internal/modules/cjs/loader.js:887:19)
I had to revert it back with npm install
.
So, basically, I'm back with what seems to be the root cause of 1st set of logs:
Error: Module parse failed: The keyword 'let' is reserved (96:90)
File was processed with these loaders:
* ./node_modules/ts-loader/index.js
You may need an additional loader to handle the result of these loaders.
Do you happen to have some clues to proceed further with that migration ng11 -> ng12 ?
Something clearly broke our deploy process:
- before: webpack 4 under the hood with ng11,
- now: webpack5 with ng12,
- before and now: i18n and angular-universal
Beta Was this translation helpful? Give feedback.
All reactions
-
😕 1