feat(bazel): add dts bundler as action to ng_module (#28588)
This enabled dts flattening in the final distrubutable package. Notes: - For the time being this is an opt-in feature via the `ng_module` attribute `bundle_dts`, however in the near future this will be turned on by default. - This only supports the legacy compiler `ngc`, as `ngtsc` emits namespaced imports `import * as __` from local modules which is not supported for the time being by API Extractor. See: https://github.com/Microsoft/web-build-tools/issues/1029 Ref: TOOL-611 PR Close #28588
This commit is contained in:
27
packages/bazel/src/api-extractor/BUILD.bazel
Normal file
27
packages/bazel/src/api-extractor/BUILD.bazel
Normal file
@ -0,0 +1,27 @@
|
||||
package(default_visibility = ["//packages:__subpackages__"])
|
||||
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")
|
||||
load("//tools:defaults.bzl", "ts_library")
|
||||
|
||||
ts_library(
|
||||
name = "lib",
|
||||
srcs = [
|
||||
"index.ts",
|
||||
],
|
||||
deps = [
|
||||
"@ngdeps//@bazel/typescript",
|
||||
"@ngdeps//@microsoft/api-extractor",
|
||||
"@ngdeps//@types/node",
|
||||
],
|
||||
)
|
||||
|
||||
nodejs_binary(
|
||||
name = "api_extractor",
|
||||
data = [
|
||||
":lib",
|
||||
"@ngdeps//@bazel/typescript",
|
||||
"@ngdeps//@microsoft/api-extractor",
|
||||
],
|
||||
entry_point = "angular/packages/bazel/src/api-extractor/index.js",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
115
packages/bazel/src/api-extractor/index.ts
Normal file
115
packages/bazel/src/api-extractor/index.ts
Normal file
@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/// <reference types="node"/>
|
||||
/// <reference lib="es2017"/>
|
||||
|
||||
import {format, parseTsconfig} from '@bazel/typescript';
|
||||
import {Extractor, ExtractorValidationRulePolicy, IExtractorConfig, IExtractorOptions} from '@microsoft/api-extractor';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
const DEBUG = false;
|
||||
|
||||
export function runMain(
|
||||
tsConfig: string, entryPoint: string, dtsBundleOut?: string, apiReviewFolder?: string,
|
||||
acceptApiUpdates = false): 1|0 {
|
||||
const [parsedConfig, errors] = parseTsconfig(tsConfig);
|
||||
if (errors && errors.length) {
|
||||
console.error(format('', errors));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const pkgJson = path.resolve(path.dirname(entryPoint), 'package.json');
|
||||
if (!fs.existsSync(pkgJson)) {
|
||||
fs.writeFileSync(pkgJson, JSON.stringify({
|
||||
'name': 'GENERATED-BY-BAZEL',
|
||||
'version': '0.0.0',
|
||||
'description': 'This is a dummy package.json as API Extractor always requires one.',
|
||||
}));
|
||||
}
|
||||
|
||||
// API extractor doesn't always support the version of TypeScript used in the repo
|
||||
// example: at the moment it is not compatable with 3.2
|
||||
// to use the internal TypeScript we shall not create a program but rather pass a parsed tsConfig.
|
||||
const parsedTsConfig = parsedConfig !.config as any;
|
||||
const compilerOptions = parsedTsConfig.compilerOptions;
|
||||
for (const [key, values] of Object.entries<string[]>(compilerOptions.paths)) {
|
||||
if (key === '*') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// we shall not pass ts files as this will need to be parsed, and for example rxjs,
|
||||
// cannot be compiled with our tsconfig, as ours is more strict
|
||||
// hence amend the paths to point always to the '.d.ts' files.
|
||||
compilerOptions.paths[key] = values.map(path => {
|
||||
const pathSuffix = /(\*|index)$/.test(path) ? '.d.ts' : '/index.d.ts';
|
||||
|
||||
return path + pathSuffix;
|
||||
});
|
||||
}
|
||||
|
||||
const extractorOptions: IExtractorOptions = {
|
||||
localBuild: acceptApiUpdates,
|
||||
customLogger: DEBUG ? undefined : {
|
||||
// don't log verbose messages when not in debug mode
|
||||
logVerbose: _message => {}
|
||||
}
|
||||
};
|
||||
|
||||
const extractorConfig: IExtractorConfig = {
|
||||
compiler: {
|
||||
configType: 'tsconfig',
|
||||
overrideTsconfig: parsedTsConfig,
|
||||
rootFolder: path.resolve(path.dirname(tsConfig))
|
||||
},
|
||||
project: {
|
||||
entryPointSourceFile: path.resolve(entryPoint),
|
||||
},
|
||||
apiReviewFile: {
|
||||
enabled: !!apiReviewFolder,
|
||||
apiReviewFolder: apiReviewFolder && path.resolve(apiReviewFolder),
|
||||
},
|
||||
apiJsonFile: {
|
||||
enabled: false,
|
||||
},
|
||||
policies: {
|
||||
namespaceSupport: 'permissive',
|
||||
},
|
||||
validationRules: {
|
||||
missingReleaseTags: ExtractorValidationRulePolicy.allow,
|
||||
},
|
||||
dtsRollup: {
|
||||
enabled: !!dtsBundleOut,
|
||||
publishFolder: dtsBundleOut && path.resolve(path.dirname(dtsBundleOut)),
|
||||
mainDtsRollupPath: dtsBundleOut && path.basename(dtsBundleOut),
|
||||
}
|
||||
};
|
||||
|
||||
const extractor = new Extractor(extractorConfig, extractorOptions);
|
||||
const isSuccessful = extractor.processProject();
|
||||
|
||||
// API extractor errors are emitted by it's logger.
|
||||
return isSuccessful ? 0 : 1;
|
||||
}
|
||||
|
||||
// Entry point
|
||||
if (require.main === module) {
|
||||
if (DEBUG) {
|
||||
console.error(`
|
||||
api-extractor: running with
|
||||
cwd: ${process.cwd()}
|
||||
argv:
|
||||
${process.argv.join('\n ')}
|
||||
`);
|
||||
}
|
||||
|
||||
const [tsConfig, entryPoint, dtsBundleOut] = process.argv.slice(2);
|
||||
process.exitCode = runMain(tsConfig, entryPoint, dtsBundleOut);
|
||||
}
|
@ -30,3 +30,4 @@ ts_providers_dict_to_struct = _ts_providers_dict_to_struct
|
||||
|
||||
DEFAULT_NG_COMPILER = "@angular//:@angular/bazel/ngc-wrapped"
|
||||
DEFAULT_NG_XI18N = "@npm//@angular/bazel/bin:xi18n"
|
||||
FLAT_DTS_FILE_SUFFIX = ".bundle.d.ts"
|
||||
|
@ -12,6 +12,7 @@ load(
|
||||
"DEFAULT_NG_COMPILER",
|
||||
"DEFAULT_NG_XI18N",
|
||||
"DEPS_ASPECTS",
|
||||
"FLAT_DTS_FILE_SUFFIX",
|
||||
"NodeModuleInfo",
|
||||
"collect_node_modules_aspect",
|
||||
"compile_ts",
|
||||
@ -121,6 +122,24 @@ def _flat_module_out_file(ctx):
|
||||
return ctx.attr.flat_module_out_file
|
||||
return "%s_public_index" % ctx.label.name
|
||||
|
||||
def _should_produce_dts_bundle(ctx):
|
||||
"""Should we produce dts bundles.
|
||||
|
||||
We only produce flatten dts outs when we expect the ng_module is meant to be published,
|
||||
based on the value of the bundle_dts attribute.
|
||||
|
||||
Args:
|
||||
ctx: skylark rule execution context
|
||||
|
||||
Returns:
|
||||
true when we should produce bundled dts.
|
||||
"""
|
||||
|
||||
# At the moment we cannot use this with ngtsc compiler since it emits
|
||||
# import * as ___ from local modules which is not supported
|
||||
# see: https://github.com/Microsoft/web-build-tools/issues/1029
|
||||
return _is_legacy_ngc(ctx) and ctx.attr.bundle_dts
|
||||
|
||||
def _should_produce_flat_module_outs(ctx):
|
||||
"""Should we produce flat module outputs.
|
||||
|
||||
@ -200,6 +219,14 @@ def _expected_outs(ctx):
|
||||
if not _is_bazel():
|
||||
metadata_files += [ctx.actions.declare_file(basename + ext) for ext in metadata]
|
||||
|
||||
dts_bundle = 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
|
||||
# the file name will be like 'core.bundle.d.ts'
|
||||
dts_bundle = ctx.actions.declare_file(ctx.label.name + 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):
|
||||
flat_module_out = _flat_module_out_file(ctx)
|
||||
@ -225,6 +252,7 @@ def _expected_outs(ctx):
|
||||
declarations = declaration_files,
|
||||
summaries = summary_files,
|
||||
metadata = metadata_files,
|
||||
dts_bundle = dts_bundle,
|
||||
bundle_index_typings = bundle_index_typings,
|
||||
i18n_messages = i18n_messages_files,
|
||||
)
|
||||
@ -302,6 +330,7 @@ def ngc_compile_action(
|
||||
label,
|
||||
inputs,
|
||||
outputs,
|
||||
dts_bundle_out,
|
||||
messages_out,
|
||||
tsconfig_file,
|
||||
node_opts,
|
||||
@ -317,6 +346,7 @@ def ngc_compile_action(
|
||||
label: the label of the ng_module being compiled
|
||||
inputs: passed to the ngc action's inputs
|
||||
outputs: passed to the ngc action's outputs
|
||||
dts_bundle_out: produced flattened dts file
|
||||
messages_out: produced xmb files
|
||||
tsconfig_file: tsconfig file with settings used for the compilation
|
||||
node_opts: list of strings, extra nodejs options.
|
||||
@ -380,6 +410,28 @@ def ngc_compile_action(
|
||||
mnemonic = "Angular2MessageExtractor",
|
||||
)
|
||||
|
||||
if dts_bundle_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)
|
||||
else:
|
||||
dts_entry_point = ctx.attr.entry_point.replace(".ts", ".d.ts")
|
||||
|
||||
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],
|
||||
arguments = [
|
||||
tsconfig_file.path,
|
||||
"/".join([ctx.bin_dir.path, ctx.label.package, dts_entry_point]),
|
||||
dts_bundle_out.path,
|
||||
],
|
||||
)
|
||||
|
||||
if not locale and not ctx.attr.no_i18n:
|
||||
return struct(
|
||||
label = label,
|
||||
@ -400,7 +452,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, messages_out, tsconfig_file, node_opts):
|
||||
def _compile_action(ctx, inputs, outputs, dts_bundle_out, messages_out, tsconfig_file, node_opts):
|
||||
# Give the Angular compiler all the user-listed assets
|
||||
file_inputs = list(ctx.files.assets)
|
||||
|
||||
@ -427,16 +479,16 @@ def _compile_action(ctx, inputs, outputs, messages_out, tsconfig_file, node_opts
|
||||
],
|
||||
)
|
||||
|
||||
return ngc_compile_action(ctx, ctx.label, action_inputs, outputs, messages_out, tsconfig_file, node_opts)
|
||||
return ngc_compile_action(ctx, ctx.label, action_inputs, outputs, dts_bundle_out, messages_out, tsconfig_file, node_opts)
|
||||
|
||||
def _prodmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts):
|
||||
outs = _expected_outs(ctx)
|
||||
return _compile_action(ctx, inputs, outputs + outs.closure_js, outs.i18n_messages, tsconfig_file, node_opts)
|
||||
return _compile_action(ctx, inputs, outputs + outs.closure_js, None, outs.i18n_messages, 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, None, tsconfig_file, node_opts)
|
||||
_compile_action(ctx, inputs, compile_action_outputs, outs.dts_bundle, 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
|
||||
@ -497,6 +549,9 @@ 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
|
||||
|
||||
return providers
|
||||
|
||||
def _ng_module_impl(ctx):
|
||||
@ -551,6 +606,11 @@ NG_MODULE_ATTRIBUTES = {
|
||||
executable = True,
|
||||
cfg = "host",
|
||||
),
|
||||
"_api_extractor": attr.label(
|
||||
default = Label("//packages/bazel/src/api-extractor:api_extractor"),
|
||||
executable = True,
|
||||
cfg = "host",
|
||||
),
|
||||
"_supports_workers": attr.bool(default = True),
|
||||
}
|
||||
|
||||
@ -630,6 +690,7 @@ NG_MODULE_RULE_ATTRS = dict(dict(COMMON_ATTRIBUTES, **NG_MODULE_ATTRIBUTES), **{
|
||||
# See the flatModuleOutFile documentation in
|
||||
# https://github.com/angular/angular/blob/master/packages/compiler-cli/src/transformers/api.ts
|
||||
"flat_module_out_file": attr.string(),
|
||||
"bundle_dts": attr.bool(default = False),
|
||||
})
|
||||
|
||||
ng_module = rule(
|
||||
|
@ -29,6 +29,7 @@ load(
|
||||
"NPM_PACKAGE_OUTPUTS",
|
||||
"create_package",
|
||||
)
|
||||
load("//packages/bazel/src:external.bzl", "FLAT_DTS_FILE_SUFFIX")
|
||||
load("//packages/bazel/src:esm5.bzl", "esm5_outputs_aspect", "esm5_root_dir", "flatten_esm5")
|
||||
load("//packages/bazel/src/ng_package:collect-type-definitions.bzl", "collect_type_definitions")
|
||||
|
||||
@ -188,15 +189,6 @@ def _ng_package_impl(ctx):
|
||||
esm_2015_files = _filter_out_generated_files(collect_es6_sources(ctx), "js")
|
||||
esm5_sources = _filter_out_generated_files(flatten_esm5(ctx), "js")
|
||||
|
||||
# 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
|
||||
# to the current package.
|
||||
type_definitions = _filter_out_generated_files(
|
||||
collect_type_definitions(ctx),
|
||||
"d.ts",
|
||||
ctx.label.package,
|
||||
)
|
||||
|
||||
# These accumulators match the directory names where the files live in the
|
||||
# Angular package format.
|
||||
fesm2015 = []
|
||||
@ -204,6 +196,8 @@ def _ng_package_impl(ctx):
|
||||
esm2015 = []
|
||||
esm5 = []
|
||||
bundles = []
|
||||
bundled_type_definitions = []
|
||||
type_definitions = []
|
||||
|
||||
# For Angular Package Format v6, we put all the individual .js files in the
|
||||
# esm5/ and esm2015/ folders.
|
||||
@ -235,6 +229,22 @@ 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)
|
||||
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
|
||||
# to the current package.
|
||||
type_definitions = _filter_out_generated_files(
|
||||
collect_type_definitions(ctx),
|
||||
"d.ts",
|
||||
ctx.label.package,
|
||||
).to_list()
|
||||
|
||||
if len(type_definitions) > 0 and len(bundled_type_definitions) > 0:
|
||||
# bundle_dts needs to be enabled/disabled for all ng module packages.
|
||||
fail("Expected all or none of the 'ng_module' dependencies to have 'bundle_dts' enabled.")
|
||||
|
||||
es2015_entry_point = "/".join([p for p in [
|
||||
ctx.bin_dir.path,
|
||||
ctx.label.package,
|
||||
@ -304,7 +314,8 @@ def _ng_package_impl(ctx):
|
||||
ctx.files.srcs +
|
||||
ctx.files.data +
|
||||
esm5_sources.to_list() +
|
||||
type_definitions.to_list() +
|
||||
type_definitions +
|
||||
bundled_type_definitions +
|
||||
[f.js for f in fesm2015 + fesm5 + esm2015 + esm5 + bundles] +
|
||||
[f.map for f in fesm2015 + fesm5 + esm2015 + esm5 + bundles if f.map]
|
||||
)
|
||||
@ -355,6 +366,9 @@ def _ng_package_impl(ctx):
|
||||
# placeholder
|
||||
packager_args.add("")
|
||||
|
||||
packager_args.add_joined([d.path for d in bundled_type_definitions], join_with = ",", omit_if_empty = False)
|
||||
packager_args.add(FLAT_DTS_FILE_SUFFIX)
|
||||
|
||||
ctx.actions.run(
|
||||
progress_message = "Angular Packaging: building npm package %s" % str(ctx.label),
|
||||
mnemonic = "AngularPackage",
|
||||
|
@ -45,7 +45,7 @@ function main(args: string[]): number {
|
||||
// flat module metadata, for example
|
||||
// {"@angular/core": {
|
||||
// "index": "bazel-bin/packages/core/core.js",
|
||||
// "typing": "bazel-bin/packages/core/core.d.ts",
|
||||
// "typings": "bazel-bin/packages/core/core.d.ts",
|
||||
// "metadata": "bazel-bin/packages/core/core.metadata.json"
|
||||
// },
|
||||
// ...
|
||||
@ -81,6 +81,12 @@ function main(args: string[]): number {
|
||||
|
||||
// Path to the package's LICENSE.
|
||||
licenseFile,
|
||||
|
||||
// List of all dts bundles generated by the API extractor.
|
||||
dtsBundleArg,
|
||||
|
||||
// The dts bundle file suffix example: '.bundle.d.ts'
|
||||
dtsBundleFileSuffix,
|
||||
] = params;
|
||||
|
||||
const fesm2015 = fesm2015Arg.split(',').filter(s => !!s);
|
||||
@ -92,6 +98,7 @@ function main(args: string[]): number {
|
||||
const srcs = srcsArg.split(',').filter(s => !!s);
|
||||
const dataFiles: string[] = dataArg.split(',').filter(s => !!s);
|
||||
const modulesManifest = JSON.parse(modulesManifestArg);
|
||||
const dtsBundles: string[] = dtsBundleArg.split(',').filter(s => !!s);
|
||||
|
||||
if (readmeMd) {
|
||||
copyFile(readmeMd, out);
|
||||
@ -155,12 +162,7 @@ function main(args: string[]): number {
|
||||
|
||||
// Copy all type definitions into the package. This is necessary so that developers can use
|
||||
// the package with type definitions.
|
||||
typeDefinitions.forEach((f: string) => {
|
||||
const content = fs.readFileSync(f, 'utf-8')
|
||||
// Strip the named AMD module for compatibility with non-bazel users
|
||||
.replace(/^\/\/\/ <amd-module name=.*\/>[\r\n]+/gm, '');
|
||||
writeFileFromInputPath(f, content);
|
||||
});
|
||||
typeDefinitions.forEach(f => writeFileFromInputPath(f, readTypingsAndStripAmdModule(f)));
|
||||
|
||||
// Copy all `data` files into the package. These are files that aren't built by the ng_package
|
||||
// rule, but instead are just straight copied into the package, e.g. global CSS assets.
|
||||
@ -176,7 +178,30 @@ function main(args: string[]): number {
|
||||
moduleFiles['esm5_index'] = path.join(binDir, 'esm5', relative);
|
||||
moduleFiles['esm2015_index'] = path.join(binDir, 'esm2015', relative);
|
||||
|
||||
copyFileFromInputPath(moduleFiles['metadata']);
|
||||
const metadataFile = moduleFiles['metadata'];
|
||||
const typingsOutFile = moduleFiles['typings'];
|
||||
|
||||
// We only support all modules within a package to be dts bundled
|
||||
// ie: if @angular/common/http has flat dts, so should @angular/common
|
||||
if (dtsBundles.length) {
|
||||
const metadataContent = rewireMetadata(metadataFile, typingsOutFile);
|
||||
writeFileFromInputPath(metadataFile, metadataContent);
|
||||
} else {
|
||||
copyFileFromInputPath(metadataFile);
|
||||
}
|
||||
});
|
||||
|
||||
const licenseBanner = licenseFile ? fs.readFileSync(licenseFile, 'utf-8') : '';
|
||||
|
||||
dtsBundles.forEach(bundleFile => {
|
||||
const cleanDistPath = bundleFile.replace(dtsBundleFileSuffix, '.d.ts');
|
||||
// API extractor will not dedupe license comments from various files
|
||||
// this will remove all the license comments and append the license banner.
|
||||
const content = licenseBanner + '\n' +
|
||||
readTypingsAndStripAmdModule(bundleFile)
|
||||
.replace(/(\/\*\*\s+\*\s\@license(((?!\*\/).|\s)*)\*\/)/gm, '');
|
||||
|
||||
writeFileFromInputPath(cleanDistPath, content);
|
||||
});
|
||||
|
||||
// Root package name (e.g. '@angular/common'), captures as we iterate through sources below.
|
||||
@ -210,8 +235,6 @@ function main(args: string[]): number {
|
||||
writeFileFromInputPath(src, content);
|
||||
}
|
||||
|
||||
const licenseBanner = licenseFile ? fs.readFileSync(licenseFile, 'utf-8') : '';
|
||||
|
||||
// Generate extra files for secondary entry-points.
|
||||
Object.keys(modulesManifest).forEach(entryPointPackageName => {
|
||||
const entryPointName = entryPointPackageName.substr(rootPackageName.length + 1);
|
||||
@ -368,6 +391,39 @@ export * from '${srcDirRelative(inputPath, typingsFile.replace(/\.d\.tsx?$/, '')
|
||||
* forward slash separators.
|
||||
*/
|
||||
function normalizeSeparators(path: string): string { return path.replace(/\\/g, '/'); }
|
||||
|
||||
/**
|
||||
* Rewires metadata to point to the flattened dts file.
|
||||
*
|
||||
* @param metadataPath the metadata file path
|
||||
* @param typingsPath the typings bundle entrypoint
|
||||
*/
|
||||
function rewireMetadata(metadataPath: string, typingsPath: string): string {
|
||||
const metadata = fs.readFileSync(metadataPath, 'utf-8');
|
||||
|
||||
let typingsRelativePath =
|
||||
normalizeSeparators(path.relative(path.dirname(metadataPath), typingsPath));
|
||||
if (!typingsRelativePath.startsWith('..')) {
|
||||
typingsRelativePath = `./${typingsRelativePath}`;
|
||||
}
|
||||
|
||||
typingsRelativePath = typingsRelativePath.replace('.d.ts', '');
|
||||
|
||||
// the regexp here catches all relative paths such as:
|
||||
// ./src/core/foo.d.ts and ../src/core/foo.d.ts
|
||||
return metadata.replace(/\.?\.\/[\w\.\-_\/]+/g, typingsRelativePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip the named AMD module for compatibility with non-bazel users from typings content
|
||||
* @param filePath dts file path
|
||||
*/
|
||||
function readTypingsAndStripAmdModule(filePath: string): string {
|
||||
return fs
|
||||
.readFileSync(filePath, 'utf-8')
|
||||
// Strip the named AMD module for compatibility with non-bazel users
|
||||
.replace(/^\/\/\/ <amd-module name=.*\/>[\r\n]+/gm, '');
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
|
Reference in New Issue
Block a user