build: enable bundle_dts for core package (#28884)
`ng_module` will now include an `src/r3_symbol.d.ts` when compiling the core package under `ngc` togather with `dts bundling`, This is due that `ngcc` relies on this file to be present, but the `r3_symbols` file which is not part of our public api. With this change, we can now ship an addition dts file which is flattened. PR Close #28884
This commit is contained in:
parent
a746b5b1ea
commit
7b0e9eddd1
|
@ -114,5 +114,19 @@ api-extractor: running with
|
|||
}
|
||||
|
||||
const [tsConfig, entryPoint, dtsBundleOut] = process.argv.slice(2);
|
||||
process.exitCode = runMain(tsConfig, entryPoint, dtsBundleOut);
|
||||
const entryPoints = entryPoint.split(',');
|
||||
const dtsBundleOuts = dtsBundleOut.split(',');
|
||||
|
||||
if (entryPoints.length !== entryPoints.length) {
|
||||
throw new Error(
|
||||
`Entry points count (${entryPoints.length}) does not match Bundle out count (${dtsBundleOuts.length})`);
|
||||
}
|
||||
|
||||
for (let i = 0; i < entryPoints.length; i++) {
|
||||
process.exitCode = runMain(tsConfig, entryPoints[i], dtsBundleOuts[i]);
|
||||
|
||||
if (process.exitCode !== 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ load(
|
|||
)
|
||||
|
||||
_FLAT_DTS_FILE_SUFFIX = ".bundle.d.ts"
|
||||
_R3_SYMBOLS_DTS_FILE = "src/r3_symbols.d.ts"
|
||||
|
||||
def compile_strategy(ctx):
|
||||
"""Detect which strategy should be used to implement ng_module.
|
||||
|
@ -142,6 +143,25 @@ def _should_produce_dts_bundle(ctx):
|
|||
# see: https://github.com/Microsoft/web-build-tools/issues/1029
|
||||
return _is_legacy_ngc(ctx) and hasattr(ctx.attr, "bundle_dts") and ctx.attr.bundle_dts
|
||||
|
||||
def _should_produce_r3_symbols_bundle(ctx):
|
||||
"""Should we produce r3_symbols bundle.
|
||||
|
||||
NGCC relies on having r3_symbols file. This file is located in @angular/core
|
||||
And should only be included when bundling core in legacy mode.
|
||||
|
||||
Args:
|
||||
ctx: skylark rule execution context
|
||||
|
||||
Returns:
|
||||
true when we should produce r3_symbols dts.
|
||||
"""
|
||||
|
||||
# iif we are compiling @angular/core with ngc we should add this addition dts bundle
|
||||
# because ngcc relies on having this file.
|
||||
# see: https://github.com/angular/angular/blob/84406e4d6d93b28b23efbb1701bc5ae1084da67b/packages/compiler-cli/src/ngcc/src/packages/entry_point_bundle.ts#L56
|
||||
# todo: alan-agius4: remove when ngcc doesn't need this anymore
|
||||
return _is_legacy_ngc(ctx) and ctx.attr.module_name == "@angular/core"
|
||||
|
||||
def _should_produce_flat_module_outs(ctx):
|
||||
"""Should we produce flat module outputs.
|
||||
|
||||
|
@ -221,13 +241,16 @@ def _expected_outs(ctx):
|
|||
if not _is_bazel():
|
||||
metadata_files += [ctx.actions.declare_file(basename + ext) for ext in metadata]
|
||||
|
||||
dts_bundle = None
|
||||
dts_bundles = None
|
||||
if _should_produce_dts_bundle(ctx):
|
||||
# We need to add a suffix to bundle as it might collide with the flat module dts.
|
||||
# The flat module dts out contains several other exports
|
||||
# https://github.com/angular/angular/blob/master/packages/compiler-cli/src/metadata/index_writer.ts#L18
|
||||
# https://github.com/angular/angular/blob/84406e4d6d93b28b23efbb1701bc5ae1084da67b/packages/compiler-cli/src/metadata/index_writer.ts#L18
|
||||
# the file name will be like 'core.bundle.d.ts'
|
||||
dts_bundle = ctx.actions.declare_file(ctx.label.name + _FLAT_DTS_FILE_SUFFIX)
|
||||
dts_bundles = [ctx.actions.declare_file(ctx.label.name + _FLAT_DTS_FILE_SUFFIX)]
|
||||
|
||||
if _should_produce_r3_symbols_bundle(ctx):
|
||||
dts_bundles.append(ctx.actions.declare_file(_R3_SYMBOLS_DTS_FILE.replace(".d.ts", _FLAT_DTS_FILE_SUFFIX)))
|
||||
|
||||
# We do this just when producing a flat module index for a publishable ng_module
|
||||
if _should_produce_flat_module_outs(ctx):
|
||||
|
@ -254,7 +277,7 @@ def _expected_outs(ctx):
|
|||
declarations = declaration_files,
|
||||
summaries = summary_files,
|
||||
metadata = metadata_files,
|
||||
dts_bundle = dts_bundle,
|
||||
dts_bundles = dts_bundles,
|
||||
bundle_index_typings = bundle_index_typings,
|
||||
i18n_messages = i18n_messages_files,
|
||||
)
|
||||
|
@ -337,7 +360,7 @@ def ngc_compile_action(
|
|||
node_opts,
|
||||
locale = None,
|
||||
i18n_args = [],
|
||||
dts_bundle_out = None):
|
||||
dts_bundles_out = None):
|
||||
"""Helper function to create the ngc action.
|
||||
|
||||
This is exposed for google3 to wire up i18n replay rules, and is not intended
|
||||
|
@ -353,7 +376,7 @@ def ngc_compile_action(
|
|||
node_opts: list of strings, extra nodejs options.
|
||||
locale: i18n locale, or None
|
||||
i18n_args: additional command-line arguments to ngc
|
||||
dts_bundle_out: produced flattened dts file
|
||||
dts_bundles_out: produced flattened dts file
|
||||
|
||||
Returns:
|
||||
the parameters of the compilation which will be used to replay the ngc action for i18N.
|
||||
|
@ -412,25 +435,28 @@ def ngc_compile_action(
|
|||
mnemonic = "Angular2MessageExtractor",
|
||||
)
|
||||
|
||||
if dts_bundle_out != None:
|
||||
if dts_bundles_out != None:
|
||||
# combine the inputs and outputs and filter .d.ts and json files
|
||||
filter_inputs = [f for f in inputs + outputs if f.path.endswith(".d.ts") or f.path.endswith(".json")]
|
||||
|
||||
if _should_produce_flat_module_outs(ctx):
|
||||
dts_entry_point = "%s.d.ts" % _flat_module_out_file(ctx)
|
||||
dts_entry_points = ["%s.d.ts" % _flat_module_out_file(ctx)]
|
||||
else:
|
||||
dts_entry_point = ctx.attr.entry_point.replace(".ts", ".d.ts")
|
||||
dts_entry_points = [ctx.attr.entry_point.replace(".ts", ".d.ts")]
|
||||
|
||||
if _should_produce_r3_symbols_bundle(ctx):
|
||||
dts_entry_points.append(_R3_SYMBOLS_DTS_FILE)
|
||||
|
||||
ctx.actions.run(
|
||||
progress_message = "Bundling DTS %s" % str(ctx.label),
|
||||
mnemonic = "APIExtractor",
|
||||
executable = ctx.executable._api_extractor,
|
||||
inputs = filter_inputs,
|
||||
outputs = [dts_bundle_out],
|
||||
outputs = dts_bundles_out,
|
||||
arguments = [
|
||||
tsconfig_file.path,
|
||||
"/".join([ctx.bin_dir.path, ctx.label.package, dts_entry_point]),
|
||||
dts_bundle_out.path,
|
||||
",".join(["/".join([ctx.bin_dir.path, ctx.label.package, f]) for f in dts_entry_points]),
|
||||
",".join([f.path for f in dts_bundles_out]),
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -454,7 +480,7 @@ def _filter_ts_inputs(all_inputs):
|
|||
if f.path.endswith(".js") or f.path.endswith(".ts") or f.path.endswith(".json")
|
||||
]
|
||||
|
||||
def _compile_action(ctx, inputs, outputs, dts_bundle_out, messages_out, tsconfig_file, node_opts):
|
||||
def _compile_action(ctx, inputs, outputs, dts_bundles_out, messages_out, tsconfig_file, node_opts):
|
||||
# Give the Angular compiler all the user-listed assets
|
||||
file_inputs = list(ctx.files.assets)
|
||||
|
||||
|
@ -483,7 +509,7 @@ def _compile_action(ctx, inputs, outputs, dts_bundle_out, messages_out, tsconfig
|
|||
],
|
||||
)
|
||||
|
||||
return ngc_compile_action(ctx, ctx.label, action_inputs, outputs, messages_out, tsconfig_file, node_opts, None, [], dts_bundle_out)
|
||||
return ngc_compile_action(ctx, ctx.label, action_inputs, outputs, messages_out, tsconfig_file, node_opts, None, [], dts_bundles_out)
|
||||
|
||||
def _prodmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts):
|
||||
outs = _expected_outs(ctx)
|
||||
|
@ -492,7 +518,7 @@ def _prodmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts):
|
|||
def _devmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts):
|
||||
outs = _expected_outs(ctx)
|
||||
compile_action_outputs = outputs + outs.devmode_js + outs.declarations + outs.summaries + outs.metadata
|
||||
_compile_action(ctx, inputs, compile_action_outputs, outs.dts_bundle, None, tsconfig_file, node_opts)
|
||||
_compile_action(ctx, inputs, compile_action_outputs, outs.dts_bundles, None, tsconfig_file, node_opts)
|
||||
|
||||
def _ts_expected_outs(ctx, label, srcs_files = []):
|
||||
# rules_typescript expects a function with two or more arguments, but our
|
||||
|
@ -553,8 +579,8 @@ def ng_module_impl(ctx, ts_compile_actions):
|
|||
flat_module_out_file = _flat_module_out_file(ctx),
|
||||
)
|
||||
|
||||
if outs.dts_bundle != None:
|
||||
providers["dts_bundle"] = outs.dts_bundle
|
||||
if outs.dts_bundles != None:
|
||||
providers["dts_bundles"] = outs.dts_bundles
|
||||
|
||||
return providers
|
||||
|
||||
|
|
|
@ -229,8 +229,8 @@ def _ng_package_impl(ctx):
|
|||
# fallback to a reasonable default
|
||||
flat_module_out_file = "index.js"
|
||||
|
||||
if hasattr(dep, "dts_bundle"):
|
||||
bundled_type_definitions.append(dep.dts_bundle)
|
||||
if hasattr(dep, "dts_bundles"):
|
||||
bundled_type_definitions += dep.dts_bundles
|
||||
elif len(type_definitions) == 0:
|
||||
# Filter out all TypeScript definitions generated by NGC as well as definition files
|
||||
# that do not belong to the current package. We only want to package types that belong
|
||||
|
|
|
@ -27,13 +27,9 @@ function p(templateStringArray: TemplateStringsArray) {
|
|||
return path.join(...segments);
|
||||
}
|
||||
|
||||
|
||||
describe('@angular/core ng_package', () => {
|
||||
|
||||
describe('misc root files', () => {
|
||||
|
||||
describe('README.md', () => {
|
||||
|
||||
it('should have a README.md file with basic info', () => {
|
||||
expect(shx.cat('README.md')).toContain(`Angular`);
|
||||
expect(shx.cat('README.md')).toContain(`https://github.com/angular/angular`);
|
||||
|
@ -41,17 +37,13 @@ describe('@angular/core ng_package', () => {
|
|||
});
|
||||
});
|
||||
|
||||
|
||||
describe('primary entry-point', () => {
|
||||
|
||||
describe('package.json', () => {
|
||||
|
||||
const packageJson = 'package.json';
|
||||
|
||||
it('should have a package.json file',
|
||||
() => { expect(shx.grep('"name":', packageJson)).toContain(`@angular/core`); });
|
||||
|
||||
|
||||
it('should contain correct version number with the PLACEHOLDER string replaced', () => {
|
||||
expect(shx.grep('"version":', packageJson)).toMatch(/\d+\.\d+\.\d+(?!-PLACEHOLDER)/);
|
||||
});
|
||||
|
@ -72,31 +64,33 @@ describe('@angular/core ng_package', () => {
|
|||
});
|
||||
});
|
||||
|
||||
|
||||
describe('typescript support', () => {
|
||||
it('should have an index d.ts file',
|
||||
() => { expect(shx.cat('core.d.ts')).toContain(`export *`); });
|
||||
if (ivyEnabled) {
|
||||
it('should have an index d.ts file',
|
||||
() => { expect(shx.cat('core.d.ts')).toContain(`export *`); });
|
||||
|
||||
it('should not have amd module names',
|
||||
() => { expect(shx.cat('public_api.d.ts')).not.toContain('<amd-module name'); });
|
||||
it('should not have amd module names',
|
||||
() => { expect(shx.cat('public_api.d.ts')).not.toContain('<amd-module name'); });
|
||||
} else {
|
||||
it('should have an index d.ts file',
|
||||
() => { expect(shx.cat('core.d.ts')).toContain('export declare'); });
|
||||
it('should have an r3_symbols d.ts file',
|
||||
() => { expect(shx.cat('src/r3_symbols.d.ts')).toContain('export declare'); });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
describe('closure', () => {
|
||||
it('should contain externs', () => {
|
||||
expect(shx.cat('src/testability/testability.externs.js')).toContain('/** @externs */');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
obsoleteInIvy('metadata files are no longer needed or produced in Ivy')
|
||||
.describe('angular metadata', () => {
|
||||
|
||||
it('should have metadata.json files',
|
||||
() => { expect(shx.cat('core.metadata.json')).toContain(`"__symbolic":"module"`); });
|
||||
});
|
||||
|
||||
|
||||
describe('fesm2015', () => {
|
||||
it('should have a fesm15 file in the /fesm2015 directory',
|
||||
() => { expect(shx.cat('fesm2015/core.js')).toContain(`export {`); });
|
||||
|
@ -117,9 +111,7 @@ describe('@angular/core ng_package', () => {
|
|||
});
|
||||
});
|
||||
|
||||
|
||||
describe('fesm5', () => {
|
||||
|
||||
it('should have a fesm5 file in the /fesm5 directory',
|
||||
() => { expect(shx.cat('fesm5/core.js')).toContain(`export {`); });
|
||||
|
||||
|
@ -151,7 +143,6 @@ describe('@angular/core ng_package', () => {
|
|||
() => { expect(shx.cat('fesm5/core.js')).toMatch('export {.*makeParamDecorator'); });
|
||||
});
|
||||
|
||||
|
||||
describe('esm2015', () => {
|
||||
it('should not contain any *.ngfactory.js files', () => {
|
||||
expect(shx.find('esm2015').filter(f => f.endsWith('.ngfactory.js'))).toEqual([]);
|
||||
|
@ -162,7 +153,6 @@ describe('@angular/core ng_package', () => {
|
|||
});
|
||||
});
|
||||
|
||||
|
||||
describe('esm5', () => {
|
||||
it('should not contain any *.ngfactory.js files',
|
||||
() => { expect(shx.find('esm5').filter(f => f.endsWith('.ngfactory.js'))).toEqual([]); });
|
||||
|
@ -171,9 +161,7 @@ describe('@angular/core ng_package', () => {
|
|||
() => { expect(shx.find('esm5').filter(f => f.endsWith('.ngsummary.js'))).toEqual([]); });
|
||||
});
|
||||
|
||||
|
||||
describe('umd', () => {
|
||||
|
||||
it('should have a umd file in the /bundles directory',
|
||||
() => { expect(shx.ls('bundles/core.umd.js').length).toBe(1, 'File not found'); });
|
||||
|
||||
|
@ -204,7 +192,6 @@ describe('@angular/core ng_package', () => {
|
|||
|
||||
describe('secondary entry-point', () => {
|
||||
describe('package.json', () => {
|
||||
|
||||
const packageJson = p `testing/package.json`;
|
||||
|
||||
it('should have a package.json file',
|
||||
|
@ -222,9 +209,15 @@ describe('@angular/core ng_package', () => {
|
|||
});
|
||||
|
||||
describe('typings', () => {
|
||||
const typingsFile = p `testing/index.d.ts`;
|
||||
it('should have a typings file',
|
||||
() => { expect(shx.cat(typingsFile)).toContain(`export * from './public_api';`); });
|
||||
if (ivyEnabled) {
|
||||
const typingsFile = p `testing/index.d.ts`;
|
||||
it('should have a typings file',
|
||||
() => { expect(shx.cat(typingsFile)).toContain(`export * from './public_api';`); });
|
||||
} else {
|
||||
const typingsFile = p `testing/testing.d.ts`;
|
||||
it('should have a typings file',
|
||||
() => { expect(shx.cat(typingsFile)).toContain('export declare'); });
|
||||
}
|
||||
|
||||
obsoleteInIvy(
|
||||
'now that we don\'t need metadata files, we don\'t need these redirects to help resolve paths to them')
|
||||
|
@ -268,7 +261,6 @@ describe('@angular/core ng_package', () => {
|
|||
});
|
||||
|
||||
describe('umd', () => {
|
||||
|
||||
it('should have a umd file in the /bundles directory',
|
||||
() => { expect(shx.ls('bundles/core-testing.umd.js').length).toBe(1, 'File not found'); });
|
||||
|
||||
|
@ -292,7 +284,6 @@ describe('@angular/core ng_package', () => {
|
|||
it('should define ng global symbols', () => {
|
||||
expect(shx.cat('bundles/core-testing.umd.js')).toContain('global.ng.core.testing = {}');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,8 +10,6 @@ ng_module(
|
|||
"src/**/*.ts",
|
||||
],
|
||||
),
|
||||
# PR to support this https://github.com/angular/angular/pull/28884
|
||||
bundle_dts = False,
|
||||
deps = [
|
||||
"//packages:types",
|
||||
"//packages/core/src/compiler",
|
||||
|
|
|
@ -19,7 +19,9 @@ import {stringify} from '../util/stringify';
|
|||
import {EMPTY_ARRAY, EMPTY_OBJ} from './empty';
|
||||
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF, NG_MODULE_DEF, NG_PIPE_DEF} from './fields';
|
||||
import {BaseDef, ComponentDef, ComponentDefFeature, ComponentTemplate, ComponentType, ContentQueriesFunction, DirectiveDef, DirectiveDefFeature, DirectiveType, DirectiveTypesOrFactory, FactoryFn, HostBindingsFunction, PipeDef, PipeType, PipeTypesOrFactory, ViewQueriesFunction} from './interfaces/definition';
|
||||
import {CssSelectorList} from './interfaces/projection';
|
||||
// while SelectorFlags is unused here, it's required so that types don't get resolved lazily
|
||||
// see: https://github.com/Microsoft/web-build-tools/issues/1050
|
||||
import {CssSelectorList, SelectorFlags} from './interfaces/projection';
|
||||
|
||||
let _renderCompCount = 0;
|
||||
|
||||
|
|
|
@ -9,8 +9,6 @@ ng_module(
|
|||
srcs = glob(
|
||||
["**/*.ts"],
|
||||
),
|
||||
# PR to support this https://github.com/angular/angular/pull/28884
|
||||
bundle_dts = False,
|
||||
deps = [
|
||||
"//packages:types",
|
||||
"//packages/compiler",
|
||||
|
|
Loading…
Reference in New Issue