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):
angular.json
"projects": {
"projectName": {
...
"architect": {
...
"server": {
...
"options": {
"outputPath": "dist/server",
//"main": "src/main.server.ts", //removed
"main": "server.ts", //added
...
}
}
}
}
}
- 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';
- 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';
- 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
- 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