feat(bazel): change ng_package rule to APF v6 (#22782)

Angular Package Format v6 stops bundling files in the esm5 and esm2015
directories, now that Webpack 4 can tree-shake per-file.

Adds some missing files like package.json to make packages closer to
what we publish today.

Refactor ng_package to be a type of npm_package and re-use the packaging
action from that rule.

PR Close #22782
This commit is contained in:
Alex Eagle 2018-03-13 11:00:53 -07:00 committed by Miško Hevery
parent 6e5e819e80
commit 88b3198c80
42 changed files with 335 additions and 138 deletions

View File

@ -2,9 +2,9 @@ workspace(name = "angular")
http_archive(
name = "build_bazel_rules_nodejs",
url = "https://github.com/bazelbuild/rules_nodejs/archive/f03c8b5df155da2a640b6775afdd4fe4aa6fec72.zip",
strip_prefix = "rules_nodejs-f03c8b5df155da2a640b6775afdd4fe4aa6fec72",
sha256 = "9d541f49af8cf60c73efb102186bfa5670ee190a088ce52638dcdf90cd9e2de6",
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.5.3.zip",
strip_prefix = "rules_nodejs-0.5.3",
sha256 = "17a5515f59777b00cb25dbc710017a14273f825029b2ec60e0969d28914870be",
)
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories")

View File

@ -2,9 +2,9 @@ workspace(name = "bazel_integration_test")
http_archive(
name = "build_bazel_rules_nodejs",
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.5.0.zip",
strip_prefix = "rules_nodejs-0.5.0",
sha256 = "06aabb253c3867d51724386ac5622a0a238bbd82e2c70ce1d09ee3ceac4c31d6",
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.5.3.zip",
strip_prefix = "rules_nodejs-0.5.3",
sha256 = "17a5515f59777b00cb25dbc710017a14273f825029b2ec60e0969d28914870be",
)
load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories")

View File

@ -18,7 +18,11 @@ ng_module(
ng_package(
name = "npm_package",
srcs = ["package.json"],
srcs = [
"package.json",
"//packages/animations/browser:package.json",
"//packages/animations/browser/testing:package.json",
],
entry_point = "packages/animations/index.js",
secondary_entry_points = [
"browser",

View File

@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"])
exports_files(["package.json"])
load("//tools:defaults.bzl", "ng_module")
ng_module(

View File

@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"])
exports_files(["package.json"])
load("//tools:defaults.bzl", "ng_module")
ng_module(

View File

@ -1,4 +1,4 @@
load("@build_bazel_rules_nodejs//:defs.bzl", "npm_package")
load("//tools:defaults.bzl", "npm_package")
genrule(
name = "workspace",
@ -9,6 +9,7 @@ genrule(
npm_package(
name = "npm_package",
srcs = [
"BUILD.bazel",
"index.bzl",
"package.json",
"//packages/bazel/src:package_assets",
@ -18,6 +19,5 @@ npm_package(
"//packages/bazel/": "//",
"angular/packages/bazel/": "angular/",
},
stamp_data = "//tools:stamp_data",
deps = [":workspace"],
)

View File

@ -18,5 +18,8 @@
"repository": {
"type": "git",
"url": "https://github.com/angular/angular.git"
},
"ng-update": {
"packageGroup": "NG_UPDATE_PACKAGE_GROUP"
}
}

View File

@ -77,6 +77,7 @@ def _esm5_outputs_aspect(target, ctx):
arguments = [tsconfig.path],
executable = target.typescript.replay_params.compiler,
execution_requirements = {
# TODO(alexeagle): enable worker mode for these compilations
"supports-workers": "0",
},
)

View File

@ -246,6 +246,7 @@ def _write_bundle_index(ctx):
tsconfig_file = ctx.actions.declare_file("%s.tsconfig.json" % basename)
metadata_file = ctx.actions.declare_file("%s.metadata.json" % basename)
tstyping_file = ctx.actions.declare_file("%s.d.ts" % basename)
js_file = ctx.actions.declare_file("%s.js" % basename)
tsconfig = dict(tsc_wrapped_tsconfig(ctx, ctx.files.srcs, ctx.files.srcs), **{
"angularCompilerOptions": {
@ -271,7 +272,7 @@ def _write_bundle_index(ctx):
ctx.actions.write(tsconfig_file, json_marshal(tsconfig))
outputs = [metadata_file, tstyping_file]
outputs = [metadata_file, tstyping_file, js_file]
ctx.action(
progress_message = "Producing metadata for bundle %s" % ctx.label.name,

View File

@ -11,6 +11,11 @@ load("@build_bazel_rules_nodejs//:internal/rollup/rollup_bundle.bzl",
"rollup_module_mappings_aspect",
"run_uglify",
"ROLLUP_ATTRS")
load("@build_bazel_rules_nodejs//:internal/npm_package/npm_package.bzl",
"NPM_PACKAGE_ATTRS",
"NPM_PACKAGE_OUTPUTS",
"create_package")
load("@build_bazel_rules_nodejs//:internal/node.bzl", "sources_aspect")
load("//packages/bazel/src:esm5.bzl", "esm5_outputs_aspect", "ESM5Info")
# TODO(alexeagle): this list is incomplete, add more as material ramps up
@ -198,10 +203,10 @@ def _rollup(ctx, rollup_config, entry_point, inputs, js_output, format = "es"):
args.add(externals, join_with=",")
other_inputs = [ctx.executable._rollup, rollup_config]
if ctx.file.stamp_data:
other_inputs.append(ctx.file.stamp_data)
if ctx.file.license_banner:
other_inputs.append(ctx.file.license_banner)
if ctx.file.stamp_data:
other_inputs.append(ctx.file.stamp_data)
ctx.actions.run(
progress_message = "Angular Packaging: rolling up %s" % ctx.label.name,
mnemonic = "AngularPackageRollup",
@ -220,12 +225,14 @@ def _rollup(ctx, rollup_config, entry_point, inputs, js_output, format = "es"):
def _flatten_paths(directory):
result = []
for f in directory:
result.extend([f.js.path, f.map.path])
result.append(f.js.path)
if f.map:
result.append(f.map.path)
return result
# ng_package produces package that is npm-ready.
def _ng_package_impl(ctx):
npm_package_directory = ctx.actions.declare_directory(ctx.label.name)
npm_package_directory = ctx.actions.declare_directory("%s.ng_pkg" % ctx.label.name)
esm_2015_files = collect_es6_sources(ctx)
@ -248,6 +255,15 @@ def _ng_package_impl(ctx):
esm5 = []
bundles = []
# For Angular Package Format v6, we put all the individual .js files in the
# esm5/ and esm2015/ folders.
for f in esm5_sources.to_list():
if f.path.endswith(".js"):
esm5.append(struct(js = f, map = None))
for f in esm_2015_files.to_list():
if f.path.endswith(".js"):
esm2015.append(struct(js = f, map = None))
for entry_point in [""] + ctx.attr.secondary_entry_points:
es2015_entry_point = "/".join([p for p in [
ctx.bin_dir.path,
@ -279,8 +295,12 @@ def _ng_package_impl(ctx):
min_output = ctx.outputs.umd_min
config = write_rollup_config(ctx, [], root_dirs)
esm2015.append(_rollup(ctx, config, es2015_entry_point, esm_2015_files, fesm2015_output))
esm5.append(_rollup(ctx, config, es5_entry_point, esm5_sources, fesm5_output))
# Currently we don't include these rollup "FESM" files in the package.
# They are only accessible as named outputs from the rule.
_rollup(ctx, config, es2015_entry_point, esm_2015_files, fesm2015_output)
_rollup(ctx, config, es5_entry_point, esm5_sources, fesm5_output)
bundles.append(_rollup(ctx, config, es5_entry_point, esm5_sources, umd_output, format = "umd"))
uglify_sourcemap = run_uglify(ctx, umd_output, min_output,
config_name = entry_point.replace("/", "_"))
@ -294,20 +314,19 @@ def _ng_package_impl(ctx):
args.use_param_file("%s", use_always = True)
args.add(npm_package_directory.path)
args.add(ctx.label.package)
args.add(primary_entry_point_name(ctx.attr.name, ctx.attr.entry_point))
args.add(ctx.attr.secondary_entry_points, join_with=",")
args.add([ctx.bin_dir.path, ctx.label.package], join_with="/")
args.add(ctx.file.readme_md.path if ctx.file.readme_md else "")
args.add(_flatten_paths(esm2015), join_with=",")
args.add(_flatten_paths(esm5), join_with=",")
args.add(_flatten_paths(bundles), join_with=",")
args.add([s.path for s in ctx.files.srcs], join_with=",")
args.add(ctx.file.stamp_data.path if ctx.file.stamp_data else "")
args.add(ctx.file.license_banner.path if ctx.file.license_banner else "")
other_inputs = (metadata_files.to_list() +
[f.js for f in esm2015 + esm5 + bundles] +
[f.map for f in esm2015 + esm5 + bundles])
if ctx.file.stamp_data:
other_inputs.append(ctx.file.stamp_data)
[f.map for f in esm2015 + esm5 + bundles if f.map])
if ctx.file.readme_md:
other_inputs.append(ctx.file.readme_md)
if ctx.file.license_banner:
@ -323,24 +342,32 @@ def _ng_package_impl(ctx):
ctx.files.srcs +
other_inputs,
outputs = [npm_package_directory],
executable = ctx.executable._packager,
executable = ctx.executable._ng_packager,
arguments = [args],
)
devfiles = depset()
if ctx.attr.include_devmode_srcs:
for d in ctx.attr.deps:
devfiles = depset(transitive = [devfiles, d.files, d.node_sources])
package_dir = create_package(ctx, devfiles.to_list(), [npm_package_directory])
return struct(
files = depset([npm_package_directory])
files = depset([package_dir])
)
NG_PACKAGE_ATTRS = dict(ROLLUP_ATTRS, **{
NG_PACKAGE_ATTRS = dict(NPM_PACKAGE_ATTRS, **dict(ROLLUP_ATTRS, **{
"srcs": attr.label_list(allow_files = True),
"deps": attr.label_list(aspects = [
rollup_module_mappings_aspect,
esm5_outputs_aspect,
sources_aspect,
]),
"include_devmode_srcs": attr.bool(default = False),
"readme_md": attr.label(allow_single_file = FileType([".md"])),
"globals": attr.string_dict(default={}),
"secondary_entry_points": attr.string_list(),
"_packager": attr.label(
"_ng_packager": attr.label(
default=Label("//packages/bazel/src/ng_package:packager"),
executable=True, cfg="host"),
"_rollup": attr.label(
@ -352,22 +379,32 @@ NG_PACKAGE_ATTRS = dict(ROLLUP_ATTRS, **{
"_uglify": attr.label(
default=Label("@build_bazel_rules_nodejs//internal/rollup:uglify"),
executable=True, cfg="host"),
})
}))
# Angular wants these named after the entry_point,
# eg. for //packages/core it looks like "packages/core/index.js", we want
# core.js produced by this rule.
# Currently we just borrow the entry point for this, if it looks like
# some/path/to/my/package/index.js
# we assume the files should be named "package.*.js"
def primary_entry_point_name(name, entry_point):
return entry_point.split("/")[-2] if entry_point.find("/") >=0 else name
def ng_package_outputs(name, entry_point):
# Angular wants these named after the entry_point,
# eg. for //packages/core it looks like "packages/core/index.js", we want
# core.js produced by this rule.
# Currently we just borrow the entry point for this, if it looks like
# some/path/to/my/package/index.js
# we assume the files should be named "package.*.js"
basename = entry_point.split("/")[-2] if entry_point.find("/") >=0 else name
return {
basename = primary_entry_point_name(name, entry_point)
outputs = {
"fesm5": "fesm5/%s.js" % basename,
"fesm2015": "fesm2015/%s.js" % basename,
"umd": "%s.umd.js" % basename,
"umd_min": "%s.umd.min.js" % basename,
}
for key in NPM_PACKAGE_OUTPUTS:
# NPM_PACKAGE_OUTPUTS is a "normal" dict-valued outputs so it looks like
# "pack": "%{name}.pack",
# But this is a function-valued outputs.
# Bazel won't replace the %{name} token so we have to do it.
outputs[key] = NPM_PACKAGE_OUTPUTS[key].replace("%{name}", name)
return outputs
ng_package = rule(
implementation = _ng_package_impl,

View File

@ -16,34 +16,19 @@ function filter(ext: string): (path: string) => boolean {
function main(args: string[]): number {
shx.set('-e');
args = fs.readFileSync(args[0], {encoding: 'utf-8'}).split('\n').map(s => s === '\'\'' ? '' : s);
const
[out, srcDir, binDir, readmeMd, fesms2015Arg, fesms5Arg, bundlesArg, srcsArg, stampData,
licenseFile] = args;
const fesms2015 = fesms2015Arg.split(',').filter(s => !!s);
const fesms5 = fesms5Arg.split(',').filter(s => !!s);
[out, srcDir, primaryEntryPoint, secondaryEntryPointsArg, binDir, readmeMd, esm2015Arg,
esm5Arg, bundlesArg, srcsArg, licenseFile] = args;
const esm2015 = esm2015Arg.split(',').filter(s => !!s);
const esm5 = esm5Arg.split(',').filter(s => !!s);
const bundles = bundlesArg.split(',').filter(s => !!s);
const srcs = srcsArg.split(',').filter(s => !!s);
const secondaryEntryPoints = secondaryEntryPointsArg.split(',').filter(s => !!s);
shx.mkdir('-p', out);
let primaryEntryPoint: string|null = null;
const secondaryEntryPoints = new Set<string>();
function replaceVersionPlaceholders(filePath: string, content: string) {
if (stampData) {
const version = shx.grep('BUILD_SCM_VERSION', stampData).split(' ')[1].trim();
// Split the replacement into separate strings so we don't match it while publishing
return content.replace(
new RegExp(
'0.0.0' +
'-PLACEHOLDER',
'g'),
version);
}
return content;
}
/**
* Inserts properties into the package.json file(s) in the package so that
* they point to all the right generated artifacts.
@ -60,22 +45,18 @@ function main(args: string[]): number {
if (!rel) {
rel = '.';
}
const indexFile = nameParts[nameParts.length - 1];
const basename = nameParts[nameParts.length - 1];
const indexName = [...nameParts, `${basename}.js`].splice(1).join('/');
parsedPackage['main'] = `${rel}/bundles/${nameParts.join('-')}.umd.js`;
parsedPackage['module'] = `${rel}/esm5/${indexFile}.js`;
parsedPackage['es2015'] = `${rel}/esm2015/${indexFile}.js`;
parsedPackage['typings'] = `./${indexFile}.d.ts`;
parsedPackage['module'] = `${rel}/esm5/${indexName}`;
parsedPackage['es2015'] = `${rel}/esm2015/${indexName}`;
parsedPackage['typings'] = `./${basename}.d.ts`;
return JSON.stringify(parsedPackage, null, 2);
}
function writeFesm(file: string, baseDir: string) {
const parts = path.basename(file).split('__');
const entryPointName = parts.join('/').replace(/\..*/, '');
if (primaryEntryPoint === null || primaryEntryPoint === entryPointName) {
primaryEntryPoint = entryPointName;
} else {
secondaryEntryPoints.add(entryPointName);
}
const filename = parts.splice(-1)[0];
const dir = path.join(baseDir, ...parts);
shx.mkdir('-p', dir);
@ -83,36 +64,45 @@ function main(args: string[]): number {
shx.mv(path.join(dir, path.basename(file)), path.join(dir, filename));
}
function moveBundleIndex(f: string) {
let ext: string;
if (f.endsWith('.d.ts'))
ext = '.d.ts';
else if (f.endsWith('.metadata.json'))
ext = '.metadata.json';
else
throw new Error('Bundle index files should be .d.ts or .metadata.json');
function writeFile(file: string, relative: string, baseDir: string) {
const dir = path.join(baseDir, path.dirname(relative));
shx.mkdir('-p', dir);
shx.cp(file, dir);
}
// Copy these bundle_index outputs from the ng_module rules in the deps
// Mapping looks like:
// $bin/_core.bundle_index.d.ts
// -> $out/core.d.ts
// $bin/testing/_testing.bundle_index.d.ts
// -> $out/testing/testing.d.ts
// $bin/_core.bundle_index.metadata.json
// -> $out/core.metadata.json
// $bin/testing/_testing.bundle_index.metadata.json
// -> $out/testing/testing.metadata.json
// JS is a little different, as controlled by the `dir` parameter
// $bin/_core.bundle_index.js
// -> $out/esm5/core.js
// $bin/testing/_testing.bundle_index.js
// -> $out/esm5/testing.js
function moveBundleIndex(f: string, dir = '.') {
const relative = path.relative(binDir, f);
let outputPath: string|undefined = undefined;
for (const secondary of secondaryEntryPoints.values()) {
if (relative.startsWith(secondary)) {
const filename = secondary.split('/').pop();
outputPath = path.join(out, secondary, filename + ext);
}
}
if (!outputPath) {
outputPath = path.join(out, primaryEntryPoint + ext);
}
return outputPath;
return path.join(out, dir, relative.replace(/_(.*)\.bundle_index/, '$1'));
}
if (readmeMd) {
shx.cp(readmeMd, path.join(out, 'README.md'));
}
fesms2015.forEach(fesm2015 => writeFesm(fesm2015, path.join(out, 'esm2015')));
fesms5.forEach(fesm5 => writeFesm(fesm5, path.join(out, 'esm5')));
function writeEsmFile(file, suffix, outDir) {
const root = file.substr(0, file.lastIndexOf(suffix + path.sep) + suffix.length + 1);
const rel = path.relative(path.join(root, srcDir), file);
if (!rel.startsWith('..')) {
writeFile(file, rel, path.join(out, outDir));
}
}
esm2015.forEach(file => writeEsmFile(file, '.es6', 'esm2015'));
esm5.forEach(file => writeEsmFile(file, '.esm5', 'esm5'));
const bundlesDir = path.join(out, 'bundles');
shx.mkdir('-p', bundlesDir);
@ -132,10 +122,14 @@ function main(args: string[]): number {
shx.mkdir('-p', path.dirname(outputPath));
fs.writeFileSync(outputPath, content);
});
allsrcs.filter(filter('.bundle_index.js')).forEach((f: string) => {
const content = fs.readFileSync(f, {encoding: 'utf-8'});
fs.writeFileSync(moveBundleIndex(f, 'esm5'), content);
fs.writeFileSync(moveBundleIndex(f, 'esm2015'), content);
});
for (const src of srcs) {
let content = fs.readFileSync(src, {encoding: 'utf-8'});
content = replaceVersionPlaceholders(src, content);
if (path.basename(src) === 'package.json') {
content = amendPackageJson(src, content);
}
@ -145,14 +139,14 @@ function main(args: string[]): number {
}
allsrcs.filter(filter('.bundle_index.metadata.json')).forEach((f: string) => {
fs.writeFileSync(
moveBundleIndex(f), replaceVersionPlaceholders(f, fs.readFileSync(f, {encoding: 'utf-8'})));
fs.writeFileSync(moveBundleIndex(f), fs.readFileSync(f, {encoding: 'utf-8'}));
});
const licenseBanner = licenseFile ? fs.readFileSync(licenseFile, {encoding: 'utf-8'}) : '';
for (const secondaryEntryPoint of secondaryEntryPoints.values()) {
for (const secondaryEntryPoint of secondaryEntryPoints) {
const baseName = secondaryEntryPoint.split('/').pop();
if (!baseName) throw new Error('secondaryEntryPoint has no slash');
const dirName = path.join(...secondaryEntryPoint.split('/').slice(0, -1));
fs.writeFileSync(path.join(out, dirName, `${baseName}.metadata.json`), JSON.stringify({

View File

@ -6,12 +6,13 @@
* found in the LICENSE file at https://angular.io/license
*/
import * as fs from 'fs';
import * as path from 'path';
import * as shx from 'shelljs';
shx.cd(path.join(process.env['TEST_SRCDIR'], 'angular', 'packages', 'common', 'npm_package'));
describe('ng_package', () => {
describe('@angular/common ng_package', () => {
it('should have right bundle files', () => {
expect(shx.ls('-R', 'bundles').stdout.split('\n').filter(n => !!n).sort()).toEqual([
'common-http-testing.umd.js',
@ -32,7 +33,8 @@ describe('ng_package', () => {
'common.umd.min.js.map',
]);
});
it('should have right fesm files', () => {
// FESMS currently not part of APF v6
xit('should have right fesm files', () => {
const expected = [
'common.js',
'common.js.map',
@ -47,4 +49,32 @@ describe('ng_package', () => {
expect(shx.ls('-R', 'esm5').stdout.split('\n').filter(n => !!n).sort()).toEqual(expected);
expect(shx.ls('-R', 'esm2015').stdout.split('\n').filter(n => !!n).sort()).toEqual(expected);
});
describe('should have module resolution properties in the package.json file for', () => {
// https://github.com/angular/common-builds/blob/master/package.json
it('/', () => {
const actual = JSON.parse(fs.readFileSync('package.json', {encoding: 'utf-8'}));
expect(actual['main']).toEqual('./bundles/common.umd.js');
});
// https://github.com/angular/common-builds/blob/master/http/package.json
it('/http', () => {
const actual = JSON.parse(fs.readFileSync('http/package.json', {encoding: 'utf-8'}));
expect(actual['main']).toEqual('../bundles/common-http.umd.js');
expect(actual['es2015']).toEqual('../esm2015/http/http.js');
expect(actual['module']).toEqual('../esm5/http/http.js');
expect(actual['typings']).toEqual('./http.d.ts');
});
// https://github.com/angular/common-builds/blob/master/testing/package.json
it('/testing', () => {
const actual = JSON.parse(fs.readFileSync('testing/package.json', {encoding: 'utf-8'}));
expect(actual['main']).toEqual('../bundles/common-testing.umd.js');
});
// https://github.com/angular/common-builds/blob/master/http/testing/package.json
it('/http/testing', () => {
const actual = JSON.parse(fs.readFileSync('http/testing/package.json', {encoding: 'utf-8'}));
expect(actual['main']).toEqual('../../bundles/common-http-testing.umd.js');
expect(actual['es2015']).toEqual('../../esm2015/http/testing/testing.js');
expect(actual['module']).toEqual('../../esm5/http/testing/testing.js');
expect(actual['typings']).toEqual('./testing.d.ts');
});
});
});

View File

@ -26,7 +26,7 @@ function p(templateStringArray: TemplateStringsArray) {
}
describe('ng_package', () => {
describe('@angular/core ng_package', () => {
describe('misc root files', () => {
@ -55,12 +55,17 @@ describe('ng_package', () => {
});
it('should contain module resolution mappings', () => {
const packageJson = 'package.json';
expect(shx.grep('"main":', packageJson)).toContain(`./bundles/core.umd.js`);
expect(shx.grep('"module":', packageJson)).toContain(`./esm5/core.js`);
expect(shx.grep('"es2015":', packageJson)).toContain(`./esm2015/core.js`);
expect(shx.grep('"typings":', packageJson)).toContain(`./core.d.ts`);
});
it('should contain metadata for ng update', () => {
expect(shx.cat(packageJson)).not.toContain('NG_UPDATE_PACKAGE_GROUP');
expect(JSON.parse(shx.cat(packageJson))['ng-update']['packageGroup'])
.toContain('@angular/core');
});
});
@ -87,8 +92,8 @@ describe('ng_package', () => {
});
describe('fesm15', () => {
// FESMS currently not part of APF v6
xdescribe('esm2015', () => {
it('should have a fesm15 file in the /esm2015 directory',
() => { expect(shx.cat('esm2015/core.js')).toContain(`export {`); });
@ -98,23 +103,24 @@ describe('ng_package', () => {
});
it('should have the version info in the header', () => {
expect(shx.cat('esm2015/core.js'))
expect(shx.cat('esm2015/index.js'))
.toMatch(/@license Angular v\d+\.\d+\.\d+(?!-PLACEHOLDER)/);
});
});
describe('fesm5', () => {
describe('esm5', () => {
it('should have a fesm5 file in the /esm5 directory',
() => { expect(shx.cat('esm5/core.js')).toContain(`export {`); });
it('should have a source map', () => {
// FESMS currently not part of APF v6
xit('should have a fesm5 file in the /esm5 directory',
() => { expect(shx.cat('esm5/core.js')).toContain(`export {`); });
// FESMS currently not part of APF v6
xit('should have a source map', () => {
expect(shx.cat('esm5/core.js.map')).toContain(`{"version":3,"file":"core.js","sources":`);
});
it('should not be processed by tsickle', () => {
expect(shx.cat('esm5/core.js')).not.toContain('@fileoverview added by tsickle');
expect(shx.cat('esm5/index.js')).not.toContain('@fileoverview added by tsickle');
});
});
@ -132,6 +138,11 @@ describe('ng_package', () => {
it('should have a source map next to the minified umd file',
() => { expect(shx.ls('bundles/core.umd.min.js.map').length).toBe(1, 'File not found'); });
it('should have the version info in the header', () => {
expect(shx.cat('bundles/core.umd.js'))
.toMatch(/@license Angular v\d+\.\d+\.\d+(?!-PLACEHOLDER)/);
});
});
});
@ -146,14 +157,14 @@ describe('ng_package', () => {
it('should have its module resolution mappings defined in the nested package.json', () => {
const packageJson = p `testing/package.json`;
expect(shx.grep('"main":', packageJson)).toContain(`../bundles/core-testing.umd.js`);
expect(shx.grep('"module":', packageJson)).toContain(`../esm5/testing.js`);
expect(shx.grep('"es2015":', packageJson)).toContain(`../esm2015/testing.js`);
expect(shx.grep('"module":', packageJson)).toContain(`../esm5/testing/testing.js`);
expect(shx.grep('"es2015":', packageJson)).toContain(`../esm2015/testing/testing.js`);
expect(shx.grep('"typings":', packageJson)).toContain(`./testing.d.ts`);
});
});
describe('typings', () => {
const typingsFile = p `testing/testing.d.ts`;
const typingsFile = p `testing/index.d.ts`;
it('should have a typings file',
() => { expect(shx.cat(typingsFile)).toContain('export * from \'./public_api\';'); });
});
@ -164,7 +175,7 @@ describe('ng_package', () => {
() => { expect(shx.cat('testing.d.ts')).toContain(`export *`); });
it('should have a \'actual\' d.ts file in the parent dir', () => {
expect(shx.cat('testing/testing.d.ts')).toContain(`export * from './public_api';`);
expect(shx.cat('testing/index.d.ts')).toContain(`export * from './public_api';`);
});
});
@ -180,8 +191,8 @@ describe('ng_package', () => {
});
});
describe('fesm15', () => {
// FESMS currently not part of APF v6
xdescribe('esm2015', () => {
it('should have a fesm15 file in the /esm2015 directory',
() => { expect(shx.cat('esm2015/testing.js')).toContain(`export {`); });
@ -191,12 +202,13 @@ describe('ng_package', () => {
});
it('should have the version info in the header', () => {
expect(shx.cat('esm2015/testing.js'))
expect(shx.cat('esm2015/index.js'))
.toMatch(/@license Angular v\d+\.\d+\.\d+(?!-PLACEHOLDER)/);
});
});
describe('fesm5', () => {
// FESMS currently not part of APF v6
xdescribe('esm5', () => {
it('should have a fesm5 file in the /esm5 directory',
() => { expect(shx.cat('esm5/testing.js')).toContain(`export {`); });

View File

@ -18,7 +18,7 @@ shx.cd(path.join(
process.env['TEST_SRCDIR'], 'angular', 'packages', 'bazel', 'test', 'ng_package', 'example',
'npm_package'));
describe('ng_package', () => {
describe('example ng_package', () => {
it('should have right bundle files', () => {
expect(shx.ls('-R', 'bundles').stdout.split('\n').filter(n => !!n).sort()).toEqual([
'example-secondary.umd.js',
@ -31,7 +31,8 @@ describe('ng_package', () => {
'example.umd.min.js.map',
]);
});
it('should have right fesm files', () => {
// FESMS currently not part of APF v6
xit('should have right fesm files', () => {
const expected = [
'example.js',
'example.js.map',
@ -61,8 +62,8 @@ describe('ng_package', () => {
it('should have secondary entry point package.json properties set', () => {
const packageJson = JSON.parse(fs.readFileSync(path.join('secondary', 'package.json'), UTF8));
expect(packageJson['main']).toBe('../bundles/example-secondary.umd.js');
expect(packageJson['module']).toBe('../esm5/secondary.js');
expect(packageJson['es2015']).toBe('../esm2015/secondary.js');
expect(packageJson['module']).toBe('../esm5/secondary/secondary.js');
expect(packageJson['es2015']).toBe('../esm2015/secondary/secondary.js');
expect(packageJson['typings']).toBe('./secondary.d.ts');
});
});

View File

@ -19,7 +19,12 @@ ng_module(
ng_package(
name = "npm_package",
srcs = ["package.json"],
srcs = [
"package.json",
"//packages/common/http:package.json",
"//packages/common/http/testing:package.json",
"//packages/common/testing:package.json",
],
entry_point = "packages/common/index.js",
secondary_entry_points = [
"testing",

View File

@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"])
exports_files(["package.json"])
load("//tools:defaults.bzl", "ng_module")
ng_module(

View File

@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"])
exports_files(["package.json"])
load("//tools:defaults.bzl", "ng_module")
ng_module(

View File

@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"])
exports_files(["package.json"])
load("//tools:defaults.bzl", "ng_module")
ng_module(

View File

@ -1,5 +1,6 @@
package(default_visibility = ["//visibility:public"])
load("//tools:defaults.bzl", "npm_package")
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library", "ts_config")
ts_config(
@ -16,7 +17,6 @@ ts_library(
"src/**/*.ts",
],
exclude = [
"src/extract_i18n.ts",
"src/integrationtest/**/*.ts",
],
),
@ -27,3 +27,11 @@ ts_library(
"//packages/compiler",
],
)
npm_package(
name = "npm_package",
srcs = [
"package.json",
],
deps = [":compiler-cli"],
)

View File

@ -11,12 +11,17 @@ ts_library(
],
),
module_name = "@angular/compiler",
# module_root = "index.d.ts",
)
ng_package(
name = "npm_package",
srcs = ["package.json"],
srcs = [
"package.json",
"//packages/compiler/testing:package.json",
],
entry_point = "packages/compiler/compiler.js",
include_devmode_srcs = True,
secondary_entry_points = [
"testing",
],

View File

@ -1,13 +1,19 @@
package(default_visibility = ["//visibility:public"])
load("//tools:defaults.bzl", "ts_library")
exports_files(["package.json"])
ts_library(
load("//tools:defaults.bzl", "ng_module")
ng_module(
name = "testing",
srcs = glob(["**/*.ts"]),
srcs = glob(
["**/*.ts"],
exclude = ["testing.ts"],
),
module_name = "@angular/compiler/testing",
deps = [
"//packages:types",
"//packages/compiler",
"//packages/core",
],
)

View File

@ -11,4 +11,4 @@
// replaces this file with production index.ts when it rewrites private symbol
// names.
export * from './testing';
export * from './public_api';

View File

@ -19,10 +19,10 @@ ng_module(
ng_package(
name = "npm_package",
srcs = glob([
"**/*.externs.js",
"**/package.json",
]) + ["//packages/core/testing:npm_package_assets"],
srcs = glob(["**/*.externs.js"]) + [
"package.json",
"//packages/core/testing:package.json",
],
entry_point = "packages/core/index.js",
secondary_entry_points = ["testing"],
deps = [

View File

@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"])
exports_files(["package.json"])
load("//tools:defaults.bzl", "ng_module")
ng_module(
@ -13,8 +15,3 @@ ng_module(
"//packages/core",
],
)
filegroup(
name = "npm_package_assets",
srcs = ["package.json"],
)

View File

@ -20,7 +20,10 @@ ng_module(
ng_package(
name = "npm_package",
srcs = ["package.json"],
srcs = [
"package.json",
"//packages/http/testing:package.json",
],
entry_point = "packages/http/index.js",
secondary_entry_points = [
"testing",

View File

@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"])
exports_files(["package.json"])
load("//tools:defaults.bzl", "ng_module")
ng_module(

View File

@ -1,6 +1,6 @@
package(default_visibility = ["//visibility:public"])
load("//tools:defaults.bzl", "ts_library")
load("//tools:defaults.bzl", "ts_library", "npm_package")
ts_library(
name = "language-service",
@ -18,3 +18,9 @@ ts_library(
"//packages/core",
],
)
npm_package(
name = "npm_package",
srcs = ["package.json"],
deps = [":language-service"],
)

View File

@ -22,7 +22,10 @@ ng_module(
ng_package(
name = "npm_package",
srcs = ["package.json"],
srcs = [
"package.json",
"//packages/platform-browser-dynamic/testing:package.json",
],
entry_point = "packages/platform-browser-dynamic/index.js",
secondary_entry_points = [
"testing",

View File

@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"])
exports_files(["package.json"])
load("//tools:defaults.bzl", "ng_module")
ng_module(

View File

@ -20,7 +20,11 @@ ng_module(
ng_package(
name = "npm_package",
srcs = ["package.json"],
srcs = [
"package.json",
"//packages/platform-browser/animations:package.json",
"//packages/platform-browser/testing:package.json",
],
entry_point = "packages/platform-browser/index.js",
secondary_entry_points = [
"animations",

View File

@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"])
exports_files(["package.json"])
load("//tools:defaults.bzl", "ng_module")
ng_module(

View File

@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"])
exports_files(["package.json"])
load("//tools:defaults.bzl", "ng_module")
ng_module(

View File

@ -27,7 +27,10 @@ ng_module(
ng_package(
name = "npm_package",
srcs = ["package.json"],
srcs = [
"package.json",
"//packages/platform-server/testing:package.json",
],
entry_point = "packages/platform-server/index.js",
secondary_entry_points = [
"testing",

View File

@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"])
exports_files(["package.json"])
load("//tools:defaults.bzl", "ng_module")
ng_module(

View File

@ -22,7 +22,11 @@ ng_module(
ng_package(
name = "npm_package",
srcs = ["package.json"],
srcs = [
"package.json",
"//packages/router/testing:package.json",
"//packages/router/upgrade:package.json",
],
entry_point = "packages/router/index.js",
secondary_entry_points = [
"testing",

View File

@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"])
exports_files(["package.json"])
load("//tools:defaults.bzl", "ng_module")
ng_module(

View File

@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"])
exports_files(["package.json"])
load("//tools:defaults.bzl", "ng_module")
ng_module(

View File

@ -20,7 +20,10 @@ ng_module(
ng_package(
name = "npm_package",
srcs = ["package.json"],
srcs = [
"package.json",
"//packages/service-worker/config:package.json",
],
entry_point = "packages/service-worker/index.js",
secondary_entry_points = ["config"],
deps = [

View File

@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"])
exports_files(["package.json"])
load("//tools:defaults.bzl", "ng_module")
ng_module(

View File

@ -20,7 +20,10 @@ ng_module(
ng_package(
name = "npm_package",
srcs = ["package.json"],
srcs = [
"package.json",
"//packages/upgrade/static:package.json",
],
entry_point = "packages/upgrade/index.js",
secondary_entry_points = [
"static",

View File

@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"])
exports_files(["package.json"])
load("//tools:defaults.bzl", "ng_module")
ng_module(

View File

@ -1,9 +1,37 @@
"""Re-export of some bazel rules with repository-wide defaults."""
load("@build_bazel_rules_nodejs//:defs.bzl", _npm_package = "npm_package")
load("@build_bazel_rules_typescript//:defs.bzl", _ts_library = "ts_library")
load("//packages/bazel:index.bzl", _ng_module = "ng_module", _ng_package = "ng_package")
DEFAULT_TSCONFIG = "//packages:tsconfig-build.json"
# Packages which are versioned together on npm
ANGULAR_SCOPED_PACKAGES = ["@angular/%s" % p for p in [
"bazel",
"core",
"common",
"compiler",
"compiler-cli",
"animations",
"platform-browser",
"platform-browser-dynamic",
"forms",
"http",
"platform-server",
"platform-webworker",
"platform-webworker-dynamic",
"upgrade",
"router",
"language-service",
"service-worker",
]]
PKG_GROUP_REPLACEMENTS = {
"\"NG_UPDATE_PACKAGE_GROUP\"": """[
%s
]""" % ",\n ".join(["\"%s\"" % s for s in ANGULAR_SCOPED_PACKAGES])
}
def ts_library(tsconfig = None, **kwargs):
if not tsconfig:
tsconfig = DEFAULT_TSCONFIG
@ -29,4 +57,12 @@ def ng_package(name, readme_md = None, license_banner = None, stamp_data = None,
readme_md = readme_md,
license_banner = license_banner,
stamp_data = stamp_data,
replacements = PKG_GROUP_REPLACEMENTS,
**kwargs)
def npm_package(name, replacements = {}, **kwargs):
_npm_package(
name = name,
stamp_data = "//tools:stamp_data",
replacements = dict(replacements, **PKG_GROUP_REPLACEMENTS),
**kwargs)