Skip to content

fix(ivy): prevent ngcc from referencing missing ɵsetClassMetadata#27055

Closed
JoostK wants to merge 4 commits into
angular:masterfrom
JoostK:ngcc-fix-invalid-setmetadata-call
Closed

fix(ivy): prevent ngcc from referencing missing ɵsetClassMetadata#27055
JoostK wants to merge 4 commits into
angular:masterfrom
JoostK:ngcc-fix-invalid-setmetadata-call

Conversation

@JoostK
Copy link
Copy Markdown
Member

@JoostK JoostK commented Nov 11, 2018

When ngtsc compiles @angular/core, it rewrites core imports to the
r3_symbols.ts file that exposes all internal symbols under their
external name. When creating the FESM bundle, the r3_symbols.ts file
causes the external symbol names to be rewritten to their internal name.

Under ngcc compilations of FESM bundles, the indirection of
r3_symbols.ts is no longer in place such that the external names are
retained in the bundle. Previously, the external name ɵdefineNgModule
was explicitly declared internally to resolve this issue, but the
recently added setClassMetadata was not declared as such, causing
runtime errors.

Instead of relying on the r3_symbols.ts file to perform the rewrite of
the external modules to their internal variants, the translation is
moved into the ImportManager during the compilation itself. This
avoids the need for providing the external name manually.

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.io application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

ngcc compiled @angular/core would reference setClassMetadata by its private name ɵsetClassMetadata which wouldn't be available during runtime.

What is the new behavior?

External references are rewritten to their internal names during compilation, instead of relying on r3_symbols.ts as that is not in use when ngcc processes the FESM bundles of @angular/core.

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Comment thread packages/core/src/core_render3_private_export.ts Outdated
@petebacondarwin
Copy link
Copy Markdown
Contributor

The source needs formatting: https://circleci.com/gh/angular/angular/104308

@petebacondarwin
Copy link
Copy Markdown
Contributor

It seems that these changes are still not enough to fix the FESM5 situation. The ngcc-CLI integration test is complaining: https://circleci.com/gh/angular/angular/104316.

@petebacondarwin petebacondarwin added type: bug/fix action: review The PR is still awaiting reviews from at least one requested reviewer effort1: hours freq2: medium severity3: broken target: major This PR is targeted for the next major release labels Nov 11, 2018
@ngbot ngbot Bot modified the milestone: needsTriage Nov 11, 2018
@petebacondarwin petebacondarwin modified the milestones: needsTriage, Ivy Nov 11, 2018
@JoostK
Copy link
Copy Markdown
Member Author

JoostK commented Nov 11, 2018

I figured out why the integration test fails:

The .d.ts transform is preferred to run for the FESM2015 bundle, for which no r3_symbols file can be located. Hence, the imports that are generated for @angular/core are not rewritten at all. Because the symbols are now rewritten to their internal names, they fail to be resolved from @angular/core (as expected).

If I force the .d.ts transform to run for ESM2015 bundles, I do end up with a relative import but unfortunately that is of the form:

import * as ɵngcc0 from '../esm2015/src/r3_symbols';

Makes sense, given that the ESM2015 bundle path was used for searching for r3_symbols. For the .d.ts transform we should find the r3_symbols.d.ts file instead.

Please mark this PR as WIP for now, I will try to resolve the above issue tomorrow evening.

@JoostK JoostK force-pushed the ngcc-fix-invalid-setmetadata-call branch 4 times, most recently from 40dfdab to 50c4f02 Compare November 11, 2018 23:19
@JoostK
Copy link
Copy Markdown
Member Author

JoostK commented Nov 11, 2018

Alright, I pushed a very dirty implementation to see if it would work, and it does. CircleCI isn't being triggered for some reason but I have seen the integration tests pass.

The seconds commit needs some cleanup as it has currently gone wild. Also, tests are needed to verify that this works as expected.

@petebacondarwin petebacondarwin added state: WIP and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Nov 12, 2018
Comment thread packages/compiler-cli/src/ngtsc/util/src/path.ts Outdated
@JoostK JoostK force-pushed the ngcc-fix-invalid-setmetadata-call branch from 37a0a43 to a1f1271 Compare November 12, 2018 19:14
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be exported from a utility class? Duplicating it already proved brittle

@petebacondarwin petebacondarwin added action: review The PR is still awaiting reviews from at least one requested reviewer and removed state: WIP labels Nov 12, 2018
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the concept of an object to hold this stuff, I am not happy with the name though. Bundle is too generic.

Also I still switch back and forth between passing everything into the constructor versus passing everything to the renderProgram method versus (our current situation) of passing some things to each.

When ngtsc compiles @angular/core, it rewrites core imports to the
r3_symbols.ts file that exposes all internal symbols under their
external name. When creating the FESM bundle, the r3_symbols.ts file
causes the external symbol names to be rewritten to their internal name.

Under ngcc compilations of FESM bundles, the indirection of
r3_symbols.ts is no longer in place such that the external names are
retained in the bundle. Previously, the external name `ɵdefineNgModule`
was explicitly declared internally to resolve this issue, but the
recently added `setClassMetadata` was not declared as such, causing
runtime errors.

Instead of relying on the r3_symbols.ts file to perform the rewrite of
the external modules to their internal variants, the translation is
moved into the `ImportManager` during the compilation itself. This
avoids the need for providing the external name manually.
@JoostK JoostK force-pushed the ngcc-fix-invalid-setmetadata-call branch from a1f1271 to 789d323 Compare November 18, 2018 20:18
@mhevery mhevery self-assigned this Nov 20, 2018
@JoostK
Copy link
Copy Markdown
Member Author

JoostK commented Nov 20, 2018

@mhevery FYI, I'm planning on rebasing this on top of #26906 as it's quite conflicty, and @petebacondarwin's PR should be considered ahead of this one.

@petebacondarwin
Copy link
Copy Markdown
Contributor

And after a review from Alex R, I am currently rewriting some portion of that PR, but it should be ready in a few hours.

const isCore = entryPoint.name === '@angular/core';
const r3SymbolsPath = isCore ? this.findR3SymbolsPath(dirname(entryPointFilePath)) : null;
const r3SymbolsPath =
isCore ? this.findR3SymbolsPath(dirname(entryPointFilePath), 'r3_symbols.js') : null;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work even if we're compiling a FESM entrypoint?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. For FESMs, the NgccImportManager will prevent core imports from being generated if core itself is being compiled.

if (this.isFlat && this.isCore && moduleName === '@angular/core') {
return {moduleImport: null, symbol: this.rewriteSymbol(moduleName, symbol)};
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad that is sorted :-)

@petebacondarwin
Copy link
Copy Markdown
Contributor

@mhevery - can you review this for integration and core PullApprove?

@mhevery mhevery added the action: merge The PR is ready for merge by the caretaker label Nov 21, 2018
@mhevery
Copy link
Copy Markdown
Contributor

mhevery commented Nov 21, 2018

@mhevery mhevery removed the action: review The PR is still awaiting reviews from at least one requested reviewer label Nov 21, 2018
@mhevery mhevery closed this in c8c8648 Nov 21, 2018
@JoostK JoostK deleted the ngcc-fix-invalid-setmetadata-call branch December 10, 2018 22:00
@angular-automatic-lock-bot
Copy link
Copy Markdown

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot Bot locked and limited conversation to collaborators Sep 14, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

action: merge The PR is ready for merge by the caretaker cla: yes effort1: hours freq2: medium target: major This PR is targeted for the next major release type: bug/fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants