angular: Improve error message: `TypeError: Cannot read property 'type' of null`
I’m submitting a…
[x] Feature request
Current behavior
If a custom library module, lets call it library-a
, imports another custom library module, library-b
, and the library-b
module exports components/modules which are not also exported via typescript/javascript (i.e. library-b
has @NgModule({exports: [...]})
but not export { ... }
), then a very non-descriptive BUILD ERROR TypeError: Cannot read property 'type' of null
is thrown with the following trace when performing ng build library-a
.
BUILD ERROR
Cannot read property 'type' of null
TypeError: Cannot read property 'type' of null
at /Users/John/apps/tests/service-work/node_modules/@angular/compiler/bundles/compiler.umd.js:15378:27
at Array.forEach (<anonymous>)
at removeSummaryDuplicates (/Users/John/apps/tests/service-work/node_modules/@angular/compiler/bundles/compiler.umd.js:15377:11)
at TemplateParser.tryParseHtml (/Users/John/apps/tests/service-work/node_modules/@angular/compiler/bundles/compiler.umd.js:14806:34)
at TemplateParser.tryParse (/Users/John/apps/tests/service-work/node_modules/@angular/compiler/bundles/compiler.umd.js:14799:21)
at TemplateParser.parse (/Users/John/apps/tests/service-work/node_modules/@angular/compiler/bundles/compiler.umd.js:14780:27)
at AotCompiler._parseTemplate (/Users/John/apps/tests/service-work/node_modules/@angular/compiler/bundles/compiler.umd.js:20483:43)
at AotCompiler._createTypeCheckBlock (/Users/John/apps/tests/service-work/node_modules/@angular/compiler/bundles/compiler.umd.js:20250:23)
at /Users/John/apps/tests/service-work/node_modules/@angular/compiler/bundles/compiler.umd.js:20220:27
at Array.forEach (<anonymous>)
This made the problem very difficult to debug.
Expected behavior
Provide a better, more descriptive error message to aid in debugging.
Environment
Angular CLI: 6.0.5
Node: 8.9.1
OS: darwin x64
Angular: 6.0.3
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router
Package Version
------------------------------------------------------------
@angular-devkit/architect 0.6.5
@angular-devkit/build-angular 0.6.5
@angular-devkit/build-ng-packagr 0.6.5
@angular-devkit/build-optimizer 0.6.5
@angular-devkit/core 0.6.5
@angular-devkit/schematics 0.6.5
@angular/cdk 6.1.0
@angular/cli 6.0.5
@angular/material 6.1.0
@angular/material-moment-adapter 6.1.0
@ngtools/json-schema 1.1.0
@ngtools/webpack 6.0.5
@schematics/angular 0.6.5
@schematics/update 0.6.5
ng-packagr 3.0.0
rxjs 6.2.0
typescript 2.7.2
webpack 4.8.3
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 8
- Comments: 28 (9 by maintainers)
I had some time looking into the compiler to find out, what is actually going on here. Also posted some details over at ng-packagr/ng-packagr#1087, but I think my findings make better use in the angular repo here.
@Ventzy was on the right track already.
The problem is actually related to yarn/npm link.
Internally the following happens:
null
objects in the list of pipes …Ultimately this is something the compiler team has to fix. Without further testing, I would expect that this only happens on Windows and the way symlinks work on this OS.
One important point:
For possible solutions / workarounds I could think of:
Thus - so far - and based on @pfeigl answer (thanks @pfeigl), what we do to automatically build a library (i.e. iri-loader), that is a dependency to another library, is to use the following alias in our package.json:
"iri-loader:build": "ng build iri-loader && npm i dist/iri-loader --save && rmdir node_modules\\@iri\\loader && xcopy /E /I dist\\iri-loader node_modules\\@iri\\loader"
PS. The issue holds true in macOS as well; below is the respective script to build the library there:
"iri-loader:build": "ng build iri-loader && npm i dist/iri-loader --save && rm node_modules/@iri/loader && cp -R dist/iri-loader node_modules/@iri/loader"
The issue seems to be with symlinked libraries in node_modules (I am on Windows). I am building library as usual into ./dist and then do npm link dist/library-b, which creates symlink node_modules/library-b -> dist/library-b. If library-b is installed that way, then ng build library-a fails with “Cannot read property ‘type’ of null” (only if components are listed in module exports). If I copy dist/library-b into node_modules, then ng build library-a is fine.
The reason behind npm link is to be able to build libraries with --watch and get changes propagated to the app, which won’t happen with copy. The only workaround that seems to be working so far is to list libraries in tsconfig.json paths like so
“ng g library” adds this automatically btw, but I had removed added paths each time. Up until now, “npm link” approach worked for libraries which does not export components used directly in templates of other libraries. I have libraries which export classes, services, and components which are dynamically instantiated and used by the app. It seems it chokes in above cross-library use case however.
Nice job debugging this, @pfeigl.
The good news is that Angular Ivy completely removes
.metadata.json
(and greatly simplifies path handling in the compiler in general), so this problem should be fixed completely with the Ivy compiler.We’ve found the solution working for our project. Removing the components from the
exports
array inlibrary-b
’s module and keeping them exported only inpublic_api.ts
.Not sure whether it is relevant but I don’t use yarn/npm link and I still get this error. I only get it when I use
If I skip the template code generation it builds fine. My library also doesn’t depend on another library in my monorepo, only on 3rd party libs (primeng, bootstrap, fontawesome etc)
@dherges easy. Let’s consider a setup as in original post above with
library-a
andlibrary-b
modules.if you import this module into
library-a
module you get the error while buildinglibrary-a
. But if you don’t export the components (marked with<--
) from the module the build will work. And of course to be able to import them elsewhere you need to export them from the librarypublic_api.ts
barrel: