feat(bazel): ng_package adds package.json props (#22499)
We now add the 'main', 'module', 'es2015', and 'typings' properties, pointing to where the packaging tool lays them out. Fixes #22416 PR Close #22499
This commit is contained in:
parent
c82cef8bc6
commit
b6c941053e
|
@ -29,12 +29,39 @@ function main(args: string[]): number {
|
||||||
let primaryEntryPoint: string|null = null;
|
let primaryEntryPoint: string|null = null;
|
||||||
const secondaryEntryPoints = new Set<string>();
|
const secondaryEntryPoints = new Set<string>();
|
||||||
|
|
||||||
function replaceVersionPlaceholders(filePath: string) {
|
function replaceVersionPlaceholders(filePath: string, content: string) {
|
||||||
if (stampData) {
|
if (stampData) {
|
||||||
const version = shx.grep('BUILD_SCM_VERSION', stampData).split(' ')[1].trim();
|
const version = shx.grep('BUILD_SCM_VERSION', stampData).split(' ')[1].trim();
|
||||||
return shx.sed(/0.0.0-PLACEHOLDER/, version, filePath);
|
return content.replace(/0.0.0-PLACEHOLDER/g, version);
|
||||||
}
|
}
|
||||||
return shx.cat(filePath);
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts properties into the package.json file(s) in the package so that
|
||||||
|
* they point to all the right generated artifacts.
|
||||||
|
*
|
||||||
|
* @param filePath file being copied
|
||||||
|
* @param content current file content
|
||||||
|
*/
|
||||||
|
function amendPackageJson(filePath: string, content: string) {
|
||||||
|
if (path.basename(filePath) === 'package.json') {
|
||||||
|
const parsedPackage = JSON.parse(content);
|
||||||
|
let nameParts = parsedPackage['name'].split('/');
|
||||||
|
// for scoped packages, we don't care about the scope segment of the path
|
||||||
|
if (nameParts[0].startsWith('@')) nameParts = nameParts.splice(1);
|
||||||
|
let rel = Array(nameParts.length - 1).fill('..').join('/');
|
||||||
|
if (!rel) {
|
||||||
|
rel = '.';
|
||||||
|
}
|
||||||
|
const indexFile = nameParts[nameParts.length - 1];
|
||||||
|
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`;
|
||||||
|
return JSON.stringify(parsedPackage, null, 2);
|
||||||
|
}
|
||||||
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeFesm(file: string, baseDir: string) {
|
function writeFesm(file: string, baseDir: string) {
|
||||||
|
@ -103,11 +130,15 @@ function main(args: string[]): number {
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const src of srcs) {
|
for (const src of srcs) {
|
||||||
replaceVersionPlaceholders(src).to(path.join(out, path.relative(srcDir, src)));
|
let content = fs.readFileSync(src, {encoding: 'utf-8'});
|
||||||
|
content = replaceVersionPlaceholders(src, content);
|
||||||
|
content = amendPackageJson(src, content);
|
||||||
|
fs.writeFileSync(path.join(out, path.relative(srcDir, src)), content);
|
||||||
}
|
}
|
||||||
|
|
||||||
allsrcs.filter(filter('.bundle_index.metadata.json')).forEach((f: string) => {
|
allsrcs.filter(filter('.bundle_index.metadata.json')).forEach((f: string) => {
|
||||||
replaceVersionPlaceholders(f).to(moveBundleIndex(f));
|
fs.writeFileSync(
|
||||||
|
moveBundleIndex(f), replaceVersionPlaceholders(f, fs.readFileSync(f, {encoding: 'utf-8'})));
|
||||||
});
|
});
|
||||||
|
|
||||||
const licenseBanner = licenseFile ? fs.readFileSync(licenseFile, {encoding: 'utf-8'}) : '';
|
const licenseBanner = licenseFile ? fs.readFileSync(licenseFile, {encoding: 'utf-8'}) : '';
|
||||||
|
|
|
@ -34,3 +34,16 @@ jasmine_node_test(
|
||||||
srcs = [":common_spec_lib"],
|
srcs = [":common_spec_lib"],
|
||||||
data = ["//packages/common:npm_package"],
|
data = ["//packages/common:npm_package"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ts_library(
|
||||||
|
name = "example_spec_lib",
|
||||||
|
testonly = True,
|
||||||
|
srcs = ["example_package.spec.ts"],
|
||||||
|
deps = ["//packages:types"],
|
||||||
|
)
|
||||||
|
|
||||||
|
jasmine_node_test(
|
||||||
|
name = "example_package",
|
||||||
|
srcs = [":example_spec_lib"],
|
||||||
|
data = ["//packages/bazel/test/ng_package/example:npm_package"],
|
||||||
|
)
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package(default_visibility = ["//packages/bazel/test:__subpackages__"])
|
||||||
|
|
||||||
|
load("//packages/bazel:index.bzl", "ng_module", "ng_package")
|
||||||
|
|
||||||
|
ng_module(
|
||||||
|
name = "example",
|
||||||
|
srcs = glob(["*.ts"]),
|
||||||
|
deps = ["//packages/bazel/test/ng_package/example/secondary"],
|
||||||
|
)
|
||||||
|
|
||||||
|
ng_package(
|
||||||
|
name = "npm_package",
|
||||||
|
srcs = [
|
||||||
|
"package.json",
|
||||||
|
"some-file.txt",
|
||||||
|
"//packages/bazel/test/ng_package/example/secondary:package.json",
|
||||||
|
],
|
||||||
|
entry_point = "packages/bazel/test/ng_package/example/index.js",
|
||||||
|
secondary_entry_points = ["secondary"],
|
||||||
|
deps = [
|
||||||
|
":example",
|
||||||
|
# FIXME(#22419)
|
||||||
|
"//packages/bazel/test/ng_package/example/secondary",
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './mymodule';
|
|
@ -0,0 +1,5 @@
|
||||||
|
import {NgModule} from '@angular/core';
|
||||||
|
|
||||||
|
@NgModule({})
|
||||||
|
export class MyModule {
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"name": "example"
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package(default_visibility = ["//packages/bazel/test:__subpackages__"])
|
||||||
|
|
||||||
|
load("//packages/bazel:index.bzl", "ng_module")
|
||||||
|
|
||||||
|
exports_files(["package.json"])
|
||||||
|
|
||||||
|
ng_module(
|
||||||
|
name = "secondary",
|
||||||
|
srcs = glob(["*.ts"]),
|
||||||
|
deps = ["//packages/core"],
|
||||||
|
)
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './secondarymodule';
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"name": "example/secondary"
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
import {NgModule} from '@angular/core';
|
||||||
|
|
||||||
|
@NgModule({})
|
||||||
|
export class SecondaryModule {
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
This file is just copied into the package.
|
|
@ -0,0 +1,58 @@
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as shx from 'shelljs';
|
||||||
|
|
||||||
|
const UTF8 = {
|
||||||
|
encoding: 'utf-8'
|
||||||
|
};
|
||||||
|
|
||||||
|
shx.cd(path.join(
|
||||||
|
process.env['TEST_SRCDIR'], 'angular', 'packages', 'bazel', 'test', 'ng_package', 'example',
|
||||||
|
'npm_package'));
|
||||||
|
|
||||||
|
describe('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',
|
||||||
|
'example-secondary.umd.js.map',
|
||||||
|
'example-secondary.umd.min.js',
|
||||||
|
'example-secondary.umd.min.js.map',
|
||||||
|
'example.umd.js',
|
||||||
|
'example.umd.js.map',
|
||||||
|
'example.umd.min.js',
|
||||||
|
'example.umd.min.js.map',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
it('should have right fesm files', () => {
|
||||||
|
const expected = [
|
||||||
|
'example.js',
|
||||||
|
'example.js.map',
|
||||||
|
'secondary.js',
|
||||||
|
'secondary.js.map',
|
||||||
|
];
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
it('should have main entry point package.json properties set', () => {
|
||||||
|
const packageJson = JSON.parse(fs.readFileSync('package.json', UTF8));
|
||||||
|
expect(packageJson['main']).toBe('./bundles/example.umd.js');
|
||||||
|
expect(packageJson['module']).toBe('./esm5/example.js');
|
||||||
|
expect(packageJson['es2015']).toBe('./esm2015/example.js');
|
||||||
|
expect(packageJson['typings']).toBe('./example.d.ts');
|
||||||
|
});
|
||||||
|
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['typings']).toBe('./secondary.d.ts');
|
||||||
|
});
|
||||||
|
});
|
|
@ -19,7 +19,10 @@ ng_module(
|
||||||
|
|
||||||
ng_package(
|
ng_package(
|
||||||
name = "npm_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:npm_package_assets"],
|
||||||
entry_point = "packages/core/index.js",
|
entry_point = "packages/core/index.js",
|
||||||
secondary_entry_points = ["testing"],
|
secondary_entry_points = ["testing"],
|
||||||
deps = [
|
deps = [
|
||||||
|
|
Loading…
Reference in New Issue