The injectable 'PlatformLocation' needs to be compiled using the JIT compiler, but '@angular/compiler' is not available

I believe I have found the solution (presuming you are using jest as your test runner). In the test-setup.ts file my project still was using the outdated import for jest-preset-angular. Instead of import 'jest-preset-angular'; try using import 'jest-preset-angular/setup-jest';.

This addressed the issue for me.


If I correctly understand, you use Angular Universal also.

I want to share my experience with the same problem which came to my project after updating Angular from v8 to v13.

First of all, I want to say that the main problem was with the incorrect started file for SSR. In my project, it was server.js and now it's main.js. So, maybe your project also tries to start from the incorrect file which doesn't have the necessary code to start it.

More details:

I updated the project step by step, increasing the version as recommended by the Angular team and according to https://update.angular.io/?l=3&v=8.2-13.0

Unfortunately, at every step, I only checked the version of SPA without SSR and only compiled the project to check that all is OK, but didn't start it with SSR. Now I can't say when the problem with the JIT compiler started.

And when I finished updating and fixing bugs with SPA, compiled the project with SSR, and tried to start it I saw this problem:

Error: The injectable 'PlatformLocation' needs to be compiled using the JIT compiler, but '@angular/compiler' is not available.

I tried different solutions like you, but nothing helped. After that, I created a new clean project with ng13 and added Angular Universal. And compare my project with new, generated by Angular-CLI.

What I changed in my project(sorry, I can't show the project - NDA):

  1. angular.json

"projects": {
  "projectName": {
    ...
    "architect": {
      ...
      "server": {
        ...
        "options": {
            "outputPath": "dist/server",
            //"main": "src/main.server.ts", //removed
            "main": "server.ts", //added
            ...
        }
      }
    }
  }
}
  1. package.json

"scripts": {
  ...
  //"serve:production:ssr":   "node dist/server --production" // removed. It was incorrect file server.js which gave the error from this case
  "serve:production:ssr":   "node dist/server/main --production", // added
  ...
  "postinstall": "ngcc --properties es5 browser module main --first-only" // added. In my case, actual version is es5
}

3.server.ts

import 'zone.js/node';

import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { join } from 'path';

import { AppServerModule } from './src/main.server';
...
// after all imports I inserted previous code into function run()

...
export function run() {
  // previous code from project with some small changes
}

//and added next code from clean project:

// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
    run();
}

export * from '../src/main.server';
  1. src/main.server.ts

// was only:
export { AppServerModule } from './app/app.server.module';

// replaced by code from clean project:

/***************************************************************************************************
 * Initialize the server environment - for example, adding DOM built-in types to the global scope.
 *
 * NOTE:
 * This import must come before any imports (direct or transitive) that rely on DOM built-ins being
 * available, such as `@angular/elements`.
 */
import '@angular/platform-server/init';

import { enableProdMode } from '@angular/core';

import { environment } from './environments/environment';

if (environment.production) {
    enableProdMode();
}

export { AppServerModule } from './app/app.server.module';
export { renderModule, renderModuleFactory } from '@angular/platform-server';
  1. src/main.ts

...
//this part of code
document.addEventListener("DOMContentLoaded", () => {
    platformBrowserDynamic()
        .bootstrapModule(AppModule)
        .catch(err => console.log(err));
});

// replaced by

function bootstrap() {
    platformBrowserDynamic().bootstrapModule(AppModule)
        .catch(err => console.error(err));
};


if (document.readyState === 'complete') {
    bootstrap();
} else {
    document.addEventListener('DOMContentLoaded', bootstrap);
}

//but I don't think it plays a role in solving the JIT problem. Wrote just in case
  1. tsconfig.server.json

{
  "extends": "./tsconfig.app.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app-server",
    "module": "commonjs",// it's only in my case, I don't have time for rewrote server.ts now
    "types": ["node"],
  },
  "files": [
    "src/main.server.ts",
    "server.ts"
  ],
  "include":["server/**/*.ts","node/*.ts"],
  
  "angularCompilerOptions": {
    "entryModule": "./src/app/app.server.module#AppServerModule"
  }
}

Ok, I think that's all. After all these edits I don't have file /dist/server.js and start the project from /dist/server/main.js without error from this case.

N.B.: When I was updating the project step-by-step I noticed that the process of updating nguniversal by Angular-CLI didn't change anything in the project. Only the version of packages. That's why I recommend comparing your project with an actual clean project manually