diff --git a/packages/bazel/src/ng_module.bzl b/packages/bazel/src/ng_module.bzl index bb8894e2ba..bff8757579 100644 --- a/packages/bazel/src/ng_module.bzl +++ b/packages/bazel/src/ng_module.bzl @@ -280,6 +280,7 @@ def _write_bundle_index(ctx): tsconfig = dict(tsc_wrapped_tsconfig(ctx, ctx.files.srcs, ctx.files.srcs), **{ "angularCompilerOptions": { "flatModuleOutFile": flat_module_out_file, + "flatModulePrivateSymbolPrefix": "_".join([ctx.workspace_name] + ctx.label.package.split("/") + [ctx.label.name, ""]), }, }) if not ctx.attr.module_name: diff --git a/packages/compiler-cli/integrationtest/bazel/ng_module/spec.js b/packages/compiler-cli/integrationtest/bazel/ng_module/spec.js index 7cd28269f2..eb10e8124d 100644 --- a/packages/compiler-cli/integrationtest/bazel/ng_module/spec.js +++ b/packages/compiler-cli/integrationtest/bazel/ng_module/spec.js @@ -15,7 +15,8 @@ describe('flat module index', () => { require.resolve(`${PKG}/flat_module_filename.metadata.json`), {encoding: 'utf-8'}); expect(metadata).toContain('"__symbolic":"module"'); expect(metadata).toContain('"__symbolic":"reference","module":"@angular/core"'); - expect(metadata).toContain('"origins":{"Child":"./child","ɵa":"./parent"}'); + expect(metadata).toContain( + '"origins":{"Child":"./child","ɵangular_packages_compiler_cli_integrationtest_bazel_ng_module_test_module_a":"./parent"}'); expect(metadata).toContain('"importAs":"some_npm_module"'); }); }); @@ -25,7 +26,8 @@ describe('flat module index', () => { fs.readFileSync(require.resolve(`${PKG}/flat_module_filename.d.ts`), {encoding: 'utf-8'}); expect(dts).toContain('export * from \'./index\';'); - expect(dts).toContain('export { Parent as ɵa } from \'./parent\';'); + expect(dts).toContain( + 'export { Parent as ɵangular_packages_compiler_cli_integrationtest_bazel_ng_module_test_module_a } from \'./parent\';'); }); }); }); \ No newline at end of file diff --git a/packages/compiler-cli/src/metadata/bundle_index_host.ts b/packages/compiler-cli/src/metadata/bundle_index_host.ts index e89aa72b8b..ea071ade88 100644 --- a/packages/compiler-cli/src/metadata/bundle_index_host.ts +++ b/packages/compiler-cli/src/metadata/bundle_index_host.ts @@ -77,8 +77,9 @@ export function createBundleIndexHost( } const file = files[0]; const indexModule = file.replace(/\.ts$/, ''); - const bundler = - new MetadataBundler(indexModule, ngOptions.flatModuleId, new CompilerHostAdapter(host)); + const bundler = new MetadataBundler( + indexModule, ngOptions.flatModuleId, new CompilerHostAdapter(host), + ngOptions.flatModulePrivateSymbolPrefix); const metadataBundle = bundler.getMetadataBundle(); const metadata = JSON.stringify(metadataBundle.metadata); const name = diff --git a/packages/compiler-cli/src/metadata/bundler.ts b/packages/compiler-cli/src/metadata/bundler.ts index c3b60e8182..be8fafd5f8 100644 --- a/packages/compiler-cli/src/metadata/bundler.ts +++ b/packages/compiler-cli/src/metadata/bundler.ts @@ -83,11 +83,14 @@ export class MetadataBundler { private metadataCache = new Map(); private exports = new Map(); private rootModule: string; + private privateSymbolPrefix: string; private exported: Set; constructor( - private root: string, private importAs: string|undefined, private host: MetadataBundlerHost) { + private root: string, private importAs: string|undefined, private host: MetadataBundlerHost, + privateSymbolPrefix?: string) { this.rootModule = `./${path.basename(root)}`; + this.privateSymbolPrefix = (privateSymbolPrefix || '').replace(/\W/g, '_'); } getMetadataBundle(): BundledModule { @@ -244,7 +247,7 @@ export class MetadataBundler { const exportedNames = new Set(exportedSymbols.map(s => s.name)); let privateName = 0; - function newPrivateName(): string { + function newPrivateName(prefix: string): string { while (true) { let digits: string[] = []; let index = privateName++; @@ -253,8 +256,7 @@ export class MetadataBundler { digits.unshift(base[index % base.length]); index = Math.floor(index / base.length); } - digits.unshift('\u0275'); - const result = digits.join(''); + const result = `\u0275${prefix}${digits.join('')}`; if (!exportedNames.has(result)) return result; } } @@ -267,7 +269,7 @@ export class MetadataBundler { let name = symbol.name; const identifier = `${symbol.declaration!.module}:${symbol.declaration !.name}`; if (symbol.isPrivate && !symbol.privateName) { - name = newPrivateName(); + name = newPrivateName(this.privateSymbolPrefix); symbol.privateName = name; } if (symbolsMap.has(identifier)) { diff --git a/packages/compiler-cli/src/transformers/api.ts b/packages/compiler-cli/src/transformers/api.ts index bb06876f0d..33d138b1dc 100644 --- a/packages/compiler-cli/src/transformers/api.ts +++ b/packages/compiler-cli/src/transformers/api.ts @@ -99,6 +99,10 @@ export interface CompilerOptions extends ts.CompilerOptions { // meaningful when `flatModuleOutFile` is also supplied. It is otherwise ignored. flatModuleId?: string; + // A prefix to insert in generated private symbols, e.g. for "my_prefix_" we + // would generate private symbols named like `ɵmy_prefix_a`. + flatModulePrivateSymbolPrefix?: string; + // Whether to generate code for library code. // If true, produce .ngfactory.ts and .ngstyle.ts files for .d.ts inputs. // Default is true. diff --git a/packages/compiler-cli/test/metadata/bundler_spec.ts b/packages/compiler-cli/test/metadata/bundler_spec.ts index 27d317492d..629cdbb2d9 100644 --- a/packages/compiler-cli/test/metadata/bundler_spec.ts +++ b/packages/compiler-cli/test/metadata/bundler_spec.ts @@ -19,10 +19,10 @@ describe('metadata bundler', () => { it('should be able to bundle a simple library', () => { const host = new MockStringBundlerHost('/', SIMPLE_LIBRARY); - const bundler = new MetadataBundler('/lib/index', undefined, host); + const bundler = new MetadataBundler('/lib/index', undefined, host, 'prfx_'); const result = bundler.getMetadataBundle(); expect(Object.keys(result.metadata.metadata).sort()).toEqual([ - 'ONE_CLASSES', 'One', 'OneMore', 'TWO_CLASSES', 'Two', 'TwoMore', 'ɵa', 'ɵb' + 'ONE_CLASSES', 'One', 'OneMore', 'TWO_CLASSES', 'Two', 'TwoMore', 'ɵprfx_a', 'ɵprfx_b' ]); const originalOne = './src/one'; @@ -34,11 +34,11 @@ describe('metadata bundler', () => { {name: 'ONE_CLASSES', value: originalOne}, {name: 'One', value: originalOne}, {name: 'OneMore', value: originalOne}, {name: 'TWO_CLASSES', value: originalTwo}, {name: 'Two', value: originalTwo}, {name: 'TwoMore', value: originalTwo}, - {name: 'ɵa', value: originalOne}, {name: 'ɵb', value: originalTwo} + {name: 'ɵprfx_a', value: originalOne}, {name: 'ɵprfx_b', value: originalTwo} ]); expect(result.privates).toEqual([ - {privateName: 'ɵa', name: 'PrivateOne', module: originalOne}, - {privateName: 'ɵb', name: 'PrivateTwo', module: originalTwo} + {privateName: 'ɵprfx_a', name: 'PrivateOne', module: originalOne}, + {privateName: 'ɵprfx_b', name: 'PrivateTwo', module: originalTwo} ]); });