Meteor 1.10.1 breaks Angular integration when AOT is enabled

Hi there,

TLDR: Meteor 1.10.1 + Angular with AOT enabled breaks with method not found errors in angular-compilers library (part of angular-meteor project).

I’m having a lot of trouble trying to find a solution to allow me to update my project from meteor 1.8 to 1.10.1. The main issue is that the integration with Angular done through the angular-meteor library breaks the project - seems like this library is not maintained anymore (last update was in May 2019).

There are a couple of major issues with 1.10.1 + Angular:

  1. If you do ‘meteor add angular-compilers’ you get this error related to node-sass:
gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit
[...]
gyp ERR! node -v v12.16.1
gyp ERR! node-gyp -v v3.6.2
gyp ERR! not ok 
Build failed with error code: 1
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! node-sass@4.7.2 postinstall: `node scripts/build.js`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the node-sass@4.7.2 postinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

I was able to solve this by installing mibto:angular-compilers instead of original angular-compilers. It updates some versions for angular-compilers dependencies. This works ok, provided you disable AOT by setting this environment variable AOT=0 (by default it’s set to 1).

  1. Building with AOT enabled breaks with these errors:
  • with Angular 7/8 I get: compiler.ts:843:42: host.isSourceFile is not a function
  • with Angular 9 I get: angular-typescript-compiler/index.js:370:42: compiler.analyzeModulesAsync is not a function

This is the what I am struggling with because I really need to get AOT to work for performance reasons.

What makes this worse and urgent is that updating to 1.10.1 is mandatory for a lot of people because the latest version of Xcode doesn’t support the old version of Swift produced by Cordova 7 bundled with pre 1.10.1 version of meteor.

Any help figuring this out would be much appreciated!

Hi cosmin,

You might try to disable Ivy within the angular-typescript-compiler package:

--- a/packages/angular-typescript-compiler/index.js
+++ b/packages/angular-typescript-compiler/index.js
@@ -65,6 +65,7 @@ const ngcOptions = {
   traceResolution: false,
   skipTemplateCodegen: false,
   fullTemplateTypeCheck: true,
+       enableIvy: false,
   disableTypeScriptVersionCheck: true
 };

This should solve your problem. To change this it might be necessary to fork the package and copy it to your top level packages folder.

This issue is caused by a breaking change in Angular 9 which caused a wrong return for “createProgram”. It is not returning the compiler anymore, which is causing the issue.


Found here (Angular project)

I am also trying to find a solution to this problem. I believe the problem is first introduced in the Meteor 1.8.2 update. I narrowed down the problem to the angular-meteor package and so I filed a bug with the angular-meteor package on GitHub as I found that the “Bare” example in that project breaks in Meteor 1.8.2 (with a minor tweak). See https://github.com/Urigo/angular-meteor/issues/1979.
I’m not sure whether the angular-meteor package is still being supported, which is a little concerning as I don’t know of another way to do AOT with Meteor and Angular. I really don’t want to go back to the loading of modules at runtime as it’s far too slow for larger projects. I would welcome any suggestions for how AOT can be done in a different way.

1 Like

Did you find any soluton to da problem? I’ve just put a local packages folder into my project root with source for angular-compilers and added to angular-typescript-compiler the enableIvy: false to ngcOptions.

Cheers

@p3pp8 - did doing that fix the problem for you?

Thanks @benjaminlueken and @p3pp8 . I’ve created a new version of angular-compilers in Atmosphere that has the “enableIvy: false” tweak. If it’s useful for anyone else, you can find the atmosphere package here, and the git repo here.

However, even with angular 9 or 10, now I get the other issue while processing with angular-compilers: [...]/packages/compiler/src/aot/compiler.ts:854:42: host.isSourceFile is not a function

Again, this only seems to be an issue when having AOT turned on. If I disable AOT (by setting the AOT env variable to 0), it works.

Any clue on how to fix this one? I haven’t been able to find anything online. If anyone familiar with angular-compilers could help, it would be much appreciated by quite a few people I think.

Hello, i’ve made a custom version of angular-compilers module disabling ivy, removing the meteor typescript compiler and updating it with one made my own that uses latest Typescript release, then i’ve been able to compile my project using latest angular version with AOT enabled. The app now is very fast in rendering pages!

@p3pp8 Nice!

Can you please share more detailed info on how to do it?

From what you’re saying there seem to be 2 parts to the solution:

  1. Disable Ivy in angular-typescript-compiler package
  2. Update the meteor-typescript dependency inside angular-typescript-compiler (this one)

I got #1 but having some difficulty with #2. Can you share what needs done to update meteor-typescript?

I’ve tried just updating the typescript dependency to the latest one 4.0.2 here in the meteor-typescript package. Build works, but then two tests fail when I run “npm run test”:

Failures:

  1) meteor-typescript ->  testing diagnostics and typings ->  should contain a semantic error when some module undefined
   Message:
     TypeError: Cannot read property 'code' of undefined
   Stacktrace:
     TypeError: Cannot read property 'code' of undefined
    at jasmine.Spec.<anonymous> (/Users/cosmin/Documents/meteor-typescript/tests/typings.spec.js:9:1580)

  2) meteor-typescript ->  testing diagnostics and typings ->  diagnostics re-evaluation works fine
   Message:
     TypeError: Cannot read property 'code' of undefined
   Stacktrace:
     TypeError: Cannot read property 'code' of undefined
    at jasmine.Spec.<anonymous> (/Users/cosmin/Documents/meteor-typescript/tests/typings.spec.js:9:2183)

Finished in 2.69 seconds
40 tests, 77 assertions, 2 failures, 0 skipped

Easy,

  • create a packages folder inside the root of your Meteor project
  • unpack angular-compilers inside
  • remove meteor-typescript dependency from package.js
  • create your own TS builder where u use the transpileModule function from latest Typescript version to transpile you scripts.
  • Update index.js plugin script inside angular-typescript-compiler to use you builder substituting the old TSBuild from meteor-typescript. Of course update compiler options in order to disable ivy
  • Enable AOT using environment variables

Of course you have to remove angular-compilers from your meteor project as the local one will be used. ie: meteor remove angular-compilers.

You than update all dependencies of angular-compilers plugins like the scss node-sass plugin or the latest ecmascript version, just edit their package.js but don’t touch the cheerio plugin from the html compiler that must be kept to 0.22.0 or your angular project will not execute.

I’m using Angular v9.2.4 with AOT enabled without any problem.

I had to update regex from index.js inside angular-typescript-compiler, quite honestly i don’t remember what i changed, i c&p my code below:

const TEMPLATE_URL_REGEX = /templateUrl\s*:(\s*['"`](.*?)['"`]\s*([,}]))/gm;
const STYLES_URLS_REGEX = /styleUrls *:(\s*\[[^\]]*?\])/g;
const LOAD_CHILDREN_REGEX = /loadChildren[\s]*:[\s]*(['|"].*#{1}.*['|"])/gm;
const STRING_REGEX = /(['`"])((?:[^\\]\\\1|.)*?)\1/g;

I hope u’ll be able to update your project!

Thanks @p3pp8. This is super helpful.

I’m still confused on this point though: create your own TS builder where u use the transpileModule function from latest Typescript version to transpile you scripts.

So you basically got rid of the meteor-typescript npm depdendency and built your own version of TSBuild() on top of the typescript package using the transpileModule() function. I don’t even know where to begin to do that, looks like it requires deep knowledge of the typescript compiler.

Would you be willing to share any code you used for doing this? Like say ‘angular-typescript-compiler/index.js’ and any other relevant files? Doesn’t have to be a git repo, even a gist would suffice.

PS: If I manage to get this working I’ll publish the necessary atmosphere + npm packages to get it working for other people struggling with this issue.

Can’t share my code as it’s on a copyright, but it’s easy to use typescript to transpile:

import ts from 'typescript';

// transpile ts to js as a string
const result = ts.transpileModule(source, { 
       compilerOptions: this.buildOptions.compilerOptions, 
       reportDiagnostics: true 
});

Where source is your typescript script as a string.
I created a simple memory cache to avoid to transpile several times scripts that are already transplied.
You can create a class named the same TSBuild as the orignal from meteor-typescript and add the emit method as well in order to receive the scripts, such as you have to change as less original code as you can from inside the index.js of angular-typescript-compilers.

2 Likes

Thanks for the help @p3pp8. I’ve managed to track down the host.isSourceFile is not a function problem. It was not an issue with the meteor typescript compiler but it was related to some changes made in the updated mibto:angular-compiler package I was using before. Have a look at the github issue here for more details.

So I applied the disable Ivy trick and managed to get it working with Meteor 1.11 and Angular 10 with AOT enabled.

If anyone else is struggling with this, feel free to try my solution. I’ve also created a new angular-compilers package to make it easy. Just replace angular-compilers with digicore:angular-compilers (version 0.4.2).

I’ve tried updating to latest typescript but ran into some other issues so I’m leaving it as is for now.