fix(ngcc): render UMD global imports correctly (#34012)
The current UMD rendering formatter did not handle a number of corner cases, such as imports from namespaced packages. PR Close #34012
This commit is contained in:
parent
51a56bc4c6
commit
44225e4010
|
@ -240,8 +240,34 @@ function isCommaExpression(value: ts.Node): value is ts.BinaryExpression {
|
|||
return ts.isBinaryExpression(value) && value.operatorToken.kind === ts.SyntaxKind.CommaToken;
|
||||
}
|
||||
|
||||
function getGlobalIdentifier(i: Import) {
|
||||
return i.specifier.replace('@angular/', 'ng.').replace(/^\//, '');
|
||||
/**
|
||||
* Compute a global identifier for the given import (`i`).
|
||||
*
|
||||
* The identifier used to access a package when using the "global" form of a UMD bundle usually
|
||||
* follows a special format where snake-case is conveted to camelCase and path separators are
|
||||
* converted to dots. In addition there are special cases such as `@angular` is mapped to `ng`.
|
||||
*
|
||||
* For example
|
||||
*
|
||||
* * `@ns/package/entry-point` => `ns.package.entryPoint`
|
||||
* * `@angular/common/testing` => `ng.common.testing`
|
||||
* * `@angular/platform-browser-dynamic` => `ng.platformBrowserDynamic`
|
||||
*
|
||||
* It is possible for packages to specify completely different identifiers for attaching the package
|
||||
* to the global, and so there is no guaranteed way to compute this.
|
||||
* Currently, this approach appears to work for the known scenarios; also it is not known how common
|
||||
* it is to use globals for importing packages.
|
||||
*
|
||||
* If it turns out that there are packages that are being used via globals, where this approach
|
||||
* fails, we should consider implementing a configuration based solution, similar to what would go
|
||||
* in a rollup configuration for mapping import paths to global indentifiers.
|
||||
*/
|
||||
function getGlobalIdentifier(i: Import): string {
|
||||
return i.specifier.replace(/^@angular\//, 'ng.')
|
||||
.replace(/^@/, '')
|
||||
.replace(/\//g, '.')
|
||||
.replace(/[-_]+(.?)/g, (_, c) => c.toUpperCase())
|
||||
.replace(/^./, c => c.toLowerCase());
|
||||
}
|
||||
|
||||
function find<T>(node: ts.Node, test: (node: ts.Node) => node is ts.Node & T): T|undefined {
|
||||
|
|
|
@ -240,6 +240,25 @@ typeof define === 'function' && define.amd ? define('file', ['exports','/tslib',
|
|||
`(factory(global.file,global.someSideEffect,global.localDep,global.ng.core,global.ng.core,global.ng.common));`);
|
||||
});
|
||||
|
||||
it('should remap import identifiers to valid global properties', () => {
|
||||
const {renderer, program} = setup(PROGRAM);
|
||||
const file = getSourceFileOrError(program, _('/node_modules/test-package/some/file.js'));
|
||||
const output = new MagicString(PROGRAM.contents);
|
||||
renderer.addImports(
|
||||
output,
|
||||
[
|
||||
{specifier: '@ngrx/store', qualifier: 'i0'},
|
||||
{specifier: '@angular/platform-browser-dynamic', qualifier: 'i1'},
|
||||
{specifier: '@angular/common/testing', qualifier: 'i2'},
|
||||
{specifier: '@angular-foo/package', qualifier: 'i3'}
|
||||
],
|
||||
file);
|
||||
expect(output.toString())
|
||||
.toContain(
|
||||
`(factory(global.file,global.someSideEffect,global.localDep,global.ng.core,` +
|
||||
`global.ngrx.store,global.ng.platformBrowserDynamic,global.ng.common.testing,global.angularFoo.package));`);
|
||||
});
|
||||
|
||||
it('should append the given imports into the global initialization, if it has a global/self initializer',
|
||||
() => {
|
||||
const {renderer, program} = setup(PROGRAM_WITH_GLOBAL_INITIALIZER);
|
||||
|
@ -256,6 +275,7 @@ typeof define === 'function' && define.amd ? define('file', ['exports','/tslib',
|
|||
.toContain(
|
||||
`(global = global || self, factory(global.file,global.someSideEffect,global.localDep,global.ng.core,global.ng.core,global.ng.common));`);
|
||||
});
|
||||
|
||||
it('should append the given imports as parameters into the factory function definition',
|
||||
() => {
|
||||
const {renderer, program} = setup(PROGRAM);
|
||||
|
|
Loading…
Reference in New Issue