angular: AOT on case insensitive file systems fails

I’m submitting a … (check one with “x”)

[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior When i run compilation with AOT enabled it fails with following error:

ERROR in Error encountered resolving symbol values statically. Calling function ‘ɵmakeDecorator’, function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol Injectable in f:/git/universal-demo/node_modules/@angular/core/core.d.ts, resolving symbol BaseAnimatedComponent in f:/git/universal-demo/app/misc/baseAnimatedComponent.ts, resolving symbol BaseAnimatedComponent in f:/git/universal-demo/app/misc/baseAnimatedComponent.ts

ERROR in Error encountered resolving symbol values statically. Calling function ‘ɵmakeDecorator’, function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol Component in f:/git/universal-demo/node_modules/@angular/core/core.d.ts, resolving symbol NotFoundComponent in f:/git/universal-demo/app/pages/notFound/notFound.component.ts, resolving symbol NotFoundComponent in f:/git/universal-demo/app/pages/notFound/notFound.component.ts

Expected behavior AOT should work.

Minimal reproduction of the problem with instructions Here are two branches which illustrates both of mentioned errors.

https://github.com/kukjevov/ng-universal-demo/tree/emakeerror Branch: emakeerror run npm install then npm run build:aot

https://github.com/kukjevov/ng-universal-demo/tree/emakeerror2 Branch: emakeerror2 run npm install then npm run build:aot

Please can somebody at least look at this? It is making impossible to use AOT.

Please tell us about your environment: Windows 10, VSCode

  • Angular version: 4.0.1

  • Browser: [all]

  • Language: [TypeScript 2.2.1]

  • Node (for AoT issues): node --version = v6.9.4

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 8
  • Comments: 19 (12 by maintainers)

Most upvoted comments

A workaround that is worked for me, is add inside the file tsconfig.app.json a path "@angular/“: [”…/node_modules/@angular/"]

"compilerOptions": {
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "lib": [
      "es2016",
      "dom"
    ],
    "outDir": "../out-tsc/app",
    "module": "es2015",
    "baseUrl": "",
    "types": [],
      "paths": {
      "@angular/*": ["../node_modules/@angular/*"] 
    }
  }

I was having the exact same issue, and after spending 2 days in the devtools, I came with this patch:

import { CompilerHost } from '@angular/compiler-cli';
import * as fs from 'fs';

CompilerHost.prototype.getCanonicalFileName =
  function mockGetCanonicalFileName(fileName: string, index: number = 0): string {
    const segments = fileName.replace(/^\//, '').split('/');

    if (!segments[index]) {
      return fileName;
    }

    const ls = fs.readdirSync(index ? '/' + segments.slice(0, index).join('/') : '/');

    segments[index] = ls.find(item => {
      return item.toLowerCase() === segments[index].toLowerCase();
    }) as string;

    return mockGetCanonicalFileName('/' + segments.join('/'), index + 1);
  };

Put that at the beginning of your webpack config

What is does is to override getCanonicalFileName that now simply returns the same path given, with the corrected path (with the right case in filesystem)

So for example if the route in your disk is /Users/test/Documents/project/file.ts but typescript is returning /users/test/documents/project/file.ts (the cause of this issue), this function will go looking folder from folder in that path and building the url again with the correct case.

Tested in my project and it worked without a complain.

@tbosch, feel free to use this code, or a modification to patch this if you think it’s the right solution.

At least if error message can give you any advice but error message is useless in this case.

I’m just writing that after the imports in my webpack.config.ts file, just make sure to include/write it before you instance the AotPlugin plugin. You can even write it down to a file and import it in you webpack.config.ts, so when this bug is fixed you just remove the import.

@patrickhousley No, you should be able to use absolute imports. However, there is a bug on case insensitive file systems (see above)…

@tbosch thank you very very much, you are awesome 😃, using relative paths works.

Funny thing is that those absolute paths are added automaticaly by vscode new feature (missing import feature) from previous release if you have in tscofng.json "baseUrl": "." and i never realized that this could be problem.

By the way, i think you tested it, but if i set all paths to app.aot it does not work either with absolute paths. Copy of app directory to app.aot are done by me in gulpfile.js because i need some transformations to be done for aot. So maybe 1. in your post is maybe not really bug.

But those absolute paths would be nice if they work 😃.

Btw it looks like that absolute paths are also cause of this https://github.com/angular/angular/issues/15571. I am going to test it properly tomorrow, but it looks like same case.

Anyway thank you again 😃.

I.e. workaround: Make sure you don’t have imports like app/... in your application, and replace them with relative imports.

Hi, there are 2 bugs here:

  1. angular-cli copies your files temporarily into an app.aot folder. However, your code has absolute imports form app/.... I.e. even if ngc succeeded, your bundle would contain your application 2x. To solve this, change the import ... from 'app/...' statements to be relative imports. This will also make the error that your are seeing go away.
  2. the error originates as the angular compiler internally does not respect ts.sys.useCaseSensitiveFileNames / CompilerHost.getCanonicalFileName for caching internal symbols. During the module resolution via ts.resolveModuleName for app/... imports, typescript normalizes the paths with toLowerCase on a case insensitive filesystem (which it doesn’t always do, e.g. when using relative paths). This results in our system getting a filePath with 2 different StaticSymbols for the same underlying symbol in a typescript file, and especially for the symbols of the decorators in @angular/core (e.g. Component / …). You can see this in the error message resolving symbol Component in <somePath> where <somePath> is the all lowercase version of the actual path (on my system, I use /Users/... and the error message contains /users/...

Note: macOS by default is case insensitive for accessing files, although it preserves the case when listing files in a directory.

Please can someone from angular team look at this 😃 ? @tbosch, @IgorMinar @matsko

Thank you