SAP / spartacus

Spartacus is a lean, Angular-based JavaScript storefront for SAP Commerce Cloud that communicates exclusively through the Commerce REST API.
Apache License 2.0
733 stars 379 forks source link

"NullInjectorError: No provider for InjectionToken REQUEST!" in Spartacus Server Side Rendering #16109

Open frenci8 opened 2 years ago

frenci8 commented 2 years ago

Hello,

I am using spartacus and I would like to render static versions of pages on the server side. I added SSR support using the manual instructions on this page https://sap.github.io/spartacus-docs/server-side-rendering-in-spartacus/ followed by support for domino in order to fix the error ReferenceError: window is not defined.

I run angular now using either one of the 2 following commands: npm run dev:ssr or npm run build:ssr && npm run serve:ssr and I get the following error:

NullInjectorError: R3InjectorError(AppServerModule)[ApplicationModule -> ApplicationRef -> ApplicationInitStatus -> InjectionToken Application Initializer -> [object Object] -> MultiCartStatePersistenceService -> StatePersistenceService -> WindowRef -> InjectionToken SERVER_REQUEST_URL -> InjectionToken SERVER_REQUEST_URL -> InjectionToken SERVER_REQUEST_URL -> InjectionToken REQUEST]: 
  NullInjectorError: No provider for InjectionToken REQUEST!
    at NullInjector.get (/Users/myuser/Documents/shop/dist/projectname/server/main.js:1:1182668)
    at R3Injector.get (/Users/myuser/Documents/shop/dist/projectname/server/main.js:1:1185046)
    at injectInjectorOnly (/Users/myuser/Documents/shop/dist/projectname/server/main.js:1:1113556)
    at ɵɵinject (/Users/myuser/Documents/shop/dist/projectname/server/main.js:1:1113726)
    at injectArgs (/Users/myuser/Documents/shop/dist/projectname/server/main.js:1:1114307)
    at Object.factory (/Users/myuser/Documents/shop/dist/projectname/server/main.js:1:1190085)
    at R3Injector.hydrate (/Users/myuser/Documents/shop/dist/projectname/server/main.js:1:1187867)
    at R3Injector.get (/Users/myuser/Documents/shop/dist/projectname/server/main.js:1:1184836)
    at R3Injector.get (/Users/myuser/Documents/shop/dist/projectname/server/main.js:1:1185046)
    at R3Injector.get (/Users/myuser/Documents/shop/dist/projectname/server/main.js:1:1185046)

REQUEST is not being used in any of the modules created by me, so I am not sure where to provide REQUEST. Any has any ideas why this error happens and how to fix it?

Thank you

janwidmer commented 1 year ago

@frenci8 did you get some solution on your problem? We have the same problem, when injecting REQUEST / RESPONSE via server.ts:

server.get('*', (req: Request, res: Response) => {
    res.render(indexHtml, {
      req,
      providers: [
        { provide: APP_BASE_HREF, useValue: req.baseUrl },
        { provide: 'REQUEST', useValue: req },
        { provide: 'RESPONSE', useValue: res },
      ],
    });
  });

When using the tokens later in the app code, we get the same error as you mentioned above..

frenci8 commented 1 year ago

@janwidmer Hi, unfortunately, I have not found a solution, but if you find one, feel free to share it here.

janwidmer commented 1 year ago

@dunqan @Platonn any statement from you guys if that should work with CCV2? Error does also seem to Occur for Injection Token SERVER_REQUEST_URL WITHOUT ANY usage of any injection tokens in my code..

Has there been a recent change in the CCV2 Cloud which breaks the usage of such tokens? According to ticket https://github.com/SAP/spartacus/issues/11016 I would understand that they should work in general?

janwidmer commented 1 year ago

@frenci8 I have tracked down the issue to invalid combinations of dependency versions of the following packages:

// working
"@angular/platform-server": "~12.2.0",
"@angular/service-worker": "~12.2.0",
"@nguniversal/express-engine": "~12.1.3",

// not working (in cloud)
"@angular/platform-server": "~12.0.5",
"@angular/service-worker": "~12.0.5",
"@nguniversal/express-engine": "~12.0.2",

// not working (in cloud)
"@angular/platform-server": "~12.2.0",
"@angular/service-worker": "~12.2.0",
"@nguniversal/express-engine": "~12.0.2",

In my case, I was somehow using the second / third combination, which was leading to that error

A note on Caret (^) vs Tilde (~): Spartacus generates the package json for a fresh spartacus by adding carets (^) for all dependencies. This approach is kinda dangerous because it lets the system use any minor version of packages from the set version and above.

Therefore we usually replace the caret with tilde or even with a fix pinned version. This now caused the above exception to be throughn when starting spartacus in production ssr mode.

If the above package version combinations still don't work, I recommend you to generate a fresh spartacus instance on the current version and take the exact version combinations from there.

janwidmer commented 1 year ago

@dunqan @Platonn would it make sense to increase the min version of @nguniversal/express-engine to 12.1.3 (when generating / updating a spartacus via schematics? There are several people having this problem (see slack help channel)