feat(bazel): add an ng_package rule (#22221)

This produces a directory following the Angular Package layout spec.

Includes integration test coverage by making a minimal ng_package in integration/bazel.
Unit tests verify the content of the @angular/core and @angular/common packages.

This doesn't totally match our current output, but is good enough to unblock some
early adopters.

It re-uses logic from the rollup_bundle rule in rules_nodejs. It should also
eventually have the .pack and .publish secondary targets like npm_package rule.

PR Close #22221
This commit is contained in:
Alex Eagle 2018-02-13 11:26:06 -08:00 committed by Victor Berchet
parent 1dcbc12fd3
commit b43b164a61
23 changed files with 1101 additions and 61 deletions

View File

@ -1,14 +1,14 @@
workspace(name = "angular")
# Using a pre-release snapshot to pick up a commit that makes all nodejs_binary
# programs produce source-mapped stack traces.
RULES_NODEJS_VERSION = "926349cea4cd360afcd5647ccdd09d2d2fb471aa"
# programs produce source-mapped stack traces and uglify sourcemaps.
RULES_NODEJS_VERSION = "4303cbef12e5e252ad66cc35cff1123e3a44ee83"
http_archive(
name = "build_bazel_rules_nodejs",
url = "https://github.com/bazelbuild/rules_nodejs/archive/%s.zip" % RULES_NODEJS_VERSION,
strip_prefix = "rules_nodejs-%s" % RULES_NODEJS_VERSION,
sha256 = "5ba3c8c209078c2e3f0c6aa4abd01a1a561f92a5bfda04e25604af5f4734d69d",
sha256 = "fccb9a7122f339d89c9994dc0fea33c737dd76e66281d0da0cb841da5f1edec7",
)
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories")

View File

@ -2,25 +2,15 @@ package(default_visibility = ["//visibility:public"])
filegroup(
name = "node_modules",
# Workaround https://github.com/bazelbuild/bazel/issues/4242
# Can't just glob(["node_modules/**/*.{js,d.ts,json}"])
srcs = glob(["/".join([
"node_modules",
pkg,
"**",
ext,
]) for pkg in [
"@angular",
"@types",
"bytebuffer",
"protobufjs",
"reflect-metadata",
"tsickle",
"typescript",
"zone.js",
] for ext in [
"*.js",
"*.json",
"*.d.ts",
]]),
srcs = glob(
["node_modules/**/*"],
# Exclude directories that commonly contain filenames which are
# illegal bazel labels
exclude = [
# e.g. node_modules/adm-zip/test/assets/attributes_test/New folder/hidden.txt
"node_modules/**/test/**",
# e.g. node_modules/xpath/docs/function resolvers.md
"node_modules/**/docs/**",
],
),
)

View File

@ -1,10 +1,14 @@
workspace(name = "bazel_integration_test")
# Using a pre-release snapshot to pick up a commit that makes all nodejs_binary
# programs produce source-mapped stack traces and uglify sourcemaps.
RULES_NODEJS_VERSION = "4303cbef12e5e252ad66cc35cff1123e3a44ee83"
http_archive(
name = "build_bazel_rules_nodejs",
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.4.1.zip",
strip_prefix = "rules_nodejs-0.4.1",
sha256 = "e9bc013417272b17f302dc169ad597f05561bb277451f010043f4da493417607",
url = "https://github.com/bazelbuild/rules_nodejs/archive/%s.zip" % RULES_NODEJS_VERSION,
strip_prefix = "rules_nodejs-%s" % RULES_NODEJS_VERSION,
sha256 = "fccb9a7122f339d89c9994dc0fea33c737dd76e66281d0da0cb841da5f1edec7",
)
load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories")

View File

@ -1,6 +1,6 @@
package(default_visibility = ["//visibility:public"])
load("@angular//:index.bzl", "ng_module")
load("@angular//:index.bzl", "ng_module", "ng_package")
load("@io_bazel_rules_sass//sass:sass.bzl", "sass_binary")
sass_binary(
@ -17,3 +17,9 @@ ng_module(
# npm distro of angular there is no ts_library rule to propagate the dep.
deps = ["@rxjs"],
)
ng_package(
name = "npm_package",
entry_point = "src/hello-world/index.js",
deps = [":hello-world"],
)

View File

@ -0,0 +1,2 @@
export * from './hello-world.component';
export * from './hello-world.module';

View File

@ -3,47 +3,79 @@
"@angular/animations@file:../../dist/packages-dist/animations":
version "5.2.0-e94fb16a2"
version "6.0.0-beta.4-7f6fcc1cc"
dependencies:
tslib "^1.7.1"
"@angular/bazel@file:../../dist/packages-dist/bazel":
version "5.2.0-e94fb16a2"
version "6.0.0-beta.4-7f6fcc1cc"
dependencies:
"@types/node" "6.0.84"
"@types/shelljs" "0.7.7"
protobufjs "5.0.0"
rollup "0.47.4"
shelljs "0.7.8"
uglify-js "2.8.29"
"@angular/common@file:../../dist/packages-dist/common":
version "5.2.0-e94fb16a2"
version "6.0.0-beta.4-7f6fcc1cc"
dependencies:
tslib "^1.7.1"
"@angular/compiler-cli@file:../../dist/packages-dist/compiler-cli":
version "5.2.0-e94fb16a2"
version "6.0.0-beta.4-7f6fcc1cc"
dependencies:
chokidar "^1.4.2"
minimist "^1.2.0"
reflect-metadata "^0.1.2"
tsickle "^0.26.0"
tsickle "^0.27.2"
"@angular/compiler@file:../../dist/packages-dist/compiler":
version "5.2.0-e94fb16a2"
version "6.0.0-beta.4-7f6fcc1cc"
dependencies:
tslib "^1.7.1"
"@angular/core@file:../../dist/packages-dist/core":
version "5.2.0-e94fb16a2"
version "6.0.0-beta.4-7f6fcc1cc"
dependencies:
tslib "^1.7.1"
"@angular/platform-browser@file:../../dist/packages-dist/platform-browser":
version "5.2.0-e94fb16a2"
version "6.0.0-beta.4-7f6fcc1cc"
dependencies:
tslib "^1.7.1"
"@types/events@*":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@types/events/-/events-1.1.0.tgz#93b1be91f63c184450385272c47b6496fd028e02"
"@types/glob@*":
version "5.0.35"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.35.tgz#1ae151c802cece940443b5ac246925c85189f32a"
dependencies:
"@types/events" "*"
"@types/minimatch" "*"
"@types/node" "*"
"@types/minimatch@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
"@types/node@*":
version "9.4.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-9.4.6.tgz#d8176d864ee48753d053783e4e463aec86b8d82e"
"@types/node@6.0.84":
version "6.0.84"
resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.84.tgz#193ffe5a9f42864d425ffd9739d95b753c6a1eab"
"@types/shelljs@0.7.7":
version "0.7.7"
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.7.7.tgz#1f7bfa28947661afea06365db9b1135bbc903ec4"
dependencies:
"@types/glob" "*"
"@types/node" "*"
"@types/source-map@0.5.1":
version "0.5.1"
resolved "https://registry.yarnpkg.com/@types/source-map/-/source-map-0.5.1.tgz#7e74db5d06ab373a712356eebfaea2fad0ea2367"
@ -59,6 +91,14 @@ ajv@^4.9.1:
co "^4.6.0"
json-stable-stringify "^1.0.1"
align-text@^0.1.1, align-text@^0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
dependencies:
kind-of "^3.0.2"
longest "^1.0.1"
repeat-string "^1.5.2"
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
@ -95,6 +135,13 @@ array-unique@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
ascli@~1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/ascli/-/ascli-1.0.1.tgz#bcfa5974a62f18e81cabaeb49732ab4a88f906bc"
dependencies:
colour "~0.7.1"
optjs "~3.2.2"
asn1@~0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
@ -164,10 +211,31 @@ braces@^1.8.2:
preserve "^0.2.0"
repeat-element "^1.1.2"
bytebuffer@~5:
version "5.0.1"
resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd"
dependencies:
long "~3"
camelcase@^1.0.2:
version "1.2.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39"
camelcase@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
center-align@^0.1.1:
version "0.1.3"
resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad"
dependencies:
align-text "^0.1.3"
lazy-cache "^1.0.3"
chokidar@^1.4.2:
version "1.7.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
@ -183,6 +251,22 @@ chokidar@^1.4.2:
optionalDependencies:
fsevents "^1.0.0"
cliui@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
dependencies:
center-align "^0.1.1"
right-align "^0.1.1"
wordwrap "0.0.2"
cliui@^3.0.3:
version "3.2.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
dependencies:
string-width "^1.0.1"
strip-ansi "^3.0.1"
wrap-ansi "^2.0.0"
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@ -191,6 +275,10 @@ code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
colour@~0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/colour/-/colour-0.7.1.tgz#9cb169917ec5d12c0736d3e8685746df1cadf778"
combined-stream@^1.0.5, combined-stream@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
@ -227,6 +315,10 @@ debug@^2.2.0:
dependencies:
ms "2.0.0"
decamelize@^1.0.0, decamelize@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
deep-extend@~0.4.0:
version "0.4.2"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
@ -375,7 +467,17 @@ glob-parent@^2.0.0:
dependencies:
is-glob "^2.0.0"
glob@^7.0.5:
glob@^5.0.10:
version "5.0.15"
resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
dependencies:
inflight "^1.0.4"
inherits "2"
minimatch "2 || 3"
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^7.0.0, glob@^7.0.5:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
dependencies:
@ -441,6 +543,14 @@ ini@~1.3.0:
version "1.3.5"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
interpret@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
invert-kv@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
is-binary-path@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
@ -562,6 +672,24 @@ kind-of@^4.0.0:
dependencies:
is-buffer "^1.1.5"
lazy-cache@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e"
lcid@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835"
dependencies:
invert-kv "^1.0.0"
long@~3:
version "3.2.0"
resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b"
longest@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
micromatch@^2.1.5:
version "2.3.11"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565"
@ -590,7 +718,7 @@ mime-types@^2.1.12, mime-types@~2.1.7:
dependencies:
mime-db "~1.30.0"
minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4:
"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
@ -681,10 +809,20 @@ once@^1.3.0, once@^1.3.3:
dependencies:
wrappy "1"
optjs@~3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/optjs/-/optjs-3.2.2.tgz#69a6ce89c442a44403141ad2f9b370bd5bb6f4ee"
os-homedir@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
os-locale@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9"
dependencies:
lcid "^1.0.0"
os-tmpdir@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
@ -709,6 +847,10 @@ path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
path-parse@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
performance-now@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
@ -721,6 +863,15 @@ process-nextick-args@~1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
protobufjs@5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-5.0.0.tgz#4223063233ea96ac063ca2b554035204db524fa1"
dependencies:
ascli "~1"
bytebuffer "~5"
glob "^5.0.10"
yargs "^3.10.0"
punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
@ -766,6 +917,12 @@ readdirp@^2.0.0:
readable-stream "^2.0.2"
set-immediate-shim "^1.0.1"
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
dependencies:
resolve "^1.1.6"
reflect-metadata@^0.1.2:
version "0.1.10"
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.10.tgz#b4f83704416acad89988c9b15635d47e03b9344a"
@ -815,12 +972,28 @@ request@2.81.0:
tunnel-agent "^0.6.0"
uuid "^3.0.0"
resolve@^1.1.6:
version "1.5.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
dependencies:
path-parse "^1.0.5"
right-align@^0.1.1:
version "0.1.3"
resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef"
dependencies:
align-text "^0.1.1"
rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
dependencies:
glob "^7.0.5"
rollup@0.47.4:
version "0.47.4"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.47.4.tgz#e3a55de83a78221d232ce29619a8d68189ae845e"
"rxjs@file:../../node_modules/rxjs":
version "5.5.5"
dependencies:
@ -842,6 +1015,14 @@ set-immediate-shim@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
shelljs@0.7.8:
version "0.7.8"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3"
dependencies:
glob "^7.0.0"
interpret "^1.0.0"
rechoir "^0.6.2"
signal-exit@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
@ -852,13 +1033,17 @@ sntp@1.x.x:
dependencies:
hoek "2.x.x"
source-map-support@^0.4.2:
version "0.4.18"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f"
source-map-support@^0.5.0:
version "0.5.3"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.3.tgz#2b3d5fff298cfa4d1afd7d4352d569e9a0158e76"
dependencies:
source-map "^0.5.6"
source-map "^0.6.0"
source-map@^0.5.6:
source-map@^0.6.0:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
source-map@~0.5.1:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
@ -935,14 +1120,14 @@ tough-cookie@~2.3.0:
dependencies:
punycode "^1.4.1"
tsickle@^0.26.0:
version "0.26.0"
resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.26.0.tgz#40b30a2dd6abcb33b182e37596674bd1cfe4039c"
tsickle@^0.27.2:
version "0.27.2"
resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.27.2.tgz#f33d46d046f73dd5c155a37922e422816e878736"
dependencies:
minimist "^1.2.0"
mkdirp "^0.5.1"
source-map "^0.5.6"
source-map-support "^0.4.2"
source-map "^0.6.0"
source-map-support "^0.5.0"
tslib@^1.7.1:
version "1.8.1"
@ -961,6 +1146,19 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
"typescript@file:../../node_modules/typescript":
version "2.6.2"
uglify-js@2.8.29:
version "2.8.29"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd"
dependencies:
source-map "~0.5.1"
yargs "~3.10.0"
optionalDependencies:
uglify-to-browserify "~1.0.0"
uglify-to-browserify@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7"
uid-number@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
@ -987,9 +1185,53 @@ wide-align@^1.1.0:
dependencies:
string-width "^1.0.2"
window-size@0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"
window-size@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876"
wordwrap@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
wrap-ansi@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
dependencies:
string-width "^1.0.1"
strip-ansi "^3.0.1"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
y18n@^3.2.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
yargs@^3.10.0:
version "3.32.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995"
dependencies:
camelcase "^2.0.1"
cliui "^3.0.3"
decamelize "^1.1.1"
os-locale "^1.4.0"
string-width "^1.0.1"
window-size "^0.1.4"
y18n "^3.2.0"
yargs@~3.10.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"
dependencies:
camelcase "^1.0.2"
cliui "^2.1.0"
decamelize "^1.0.0"
window-size "0.1.0"
"zone.js@file:../../node_modules/zone.js":
version "0.8.17"

View File

@ -45,6 +45,7 @@
"@types/jasmine": "2.2.22-alpha",
"@types/node": "6.0.88",
"@types/selenium-webdriver": "3.0.7",
"@types/shelljs": "^0.7.8",
"@types/source-map": "^0.5.1",
"@types/systemjs": "0.19.32",
"angular": "1.5.0",

View File

@ -8,5 +8,7 @@ Users should not load files under "/src"
"""
load("//packages/bazel/src:ng_module.bzl", _ng_module = "ng_module")
load("//packages/bazel/src/ng_package:ng_package.bzl", _ng_package = "ng_package")
ng_module = _ng_module
ng_package = _ng_package

View File

@ -4,13 +4,16 @@
"description": "Angular - bazel build rules",
"author": "angular",
"license": "MIT",
"dependencies": {
"@types/node": "6.0.84",
"@types/shelljs": "0.7.7",
"shelljs": "0.7.8",
"protobufjs": "5.0.0"
},
"peerDependencies": {
"@angular/compiler-cli": "0.0.0-PLACEHOLDER",
"typescript": ">=2.4.2 <2.7"
},
"dependencies": {
"@types/node": "6.0.84"
},
"repository": {
"type": "git",
"url": "https://github.com/angular/angular.git"

View File

@ -35,8 +35,10 @@ def _expected_outs(ctx):
factory_basename_set = depset([_basename_of(ctx, src) for src in ctx.files.factories])
for src in ctx.files.srcs + ctx.files.assets:
package_prefix = ctx.label.package + "/" if ctx.label.package else ""
if src.short_path.endswith(".ts") and not src.short_path.endswith(".d.ts"):
basename = src.short_path[len(ctx.label.package) + 1:-len(".ts")]
basename = src.short_path[len(package_prefix):-len(".ts")]
if len(factory_basename_set) == 0 or basename in factory_basename_set:
devmode_js = [
".ngfactory.js",
@ -48,7 +50,7 @@ def _expected_outs(ctx):
devmode_js = [".js"]
summaries = []
elif src.short_path.endswith(".css"):
basename = src.short_path[len(ctx.label.package) + 1:-len(".css")]
basename = src.short_path[len(package_prefix):-len(".css")]
devmode_js = [
".css.shim.ngstyle.js",
".css.ngstyle.js",
@ -252,14 +254,18 @@ def _write_bundle_index(ctx):
if ctx.attr.module_name:
tsconfig["angularCompilerOptions"]["flatModuleId"] = ctx.attr.module_name
entry_point = ctx.attr.entry_point if ctx.attr.entry_point else "index.ts"
# createBundleIndexHost in bundle_index_host.ts will throw if the "files" has more than one entry.
# We don't want to fail() here, however, because not all ng_module's will have the bundle index written.
# So we make the assumption that the index.ts file in the highest parent directory is the entry point.
index_file = None
for f in tsconfig["files"]:
if f.endswith("/index.ts"):
if f.endswith("/" + entry_point):
if not index_file or len(f) < len(index_file):
index_file = f
if index_file:
tsconfig["files"] = [index_file]
ctx.actions.write(tsconfig_file, json_marshal(tsconfig))
@ -361,6 +367,9 @@ ng_module = rule(
"node_modules": attr.label(
default = Label("@//:node_modules")
),
"entry_point": attr.string(),
"_index_bundler": attr.label(
executable = True,
cfg = "host",

View File

@ -0,0 +1,18 @@
package(default_visibility = ["//visibility:public"])
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library")
exports_files(["rollup.config.js"])
ts_library(
name = "lib",
srcs = glob(["*.ts"]),
tsconfig = ":tsconfig.json",
)
nodejs_binary(
name = "packager",
data = ["lib"],
entry_point = "angular/packages/bazel/src/ng_package/packager.js",
)

View File

@ -0,0 +1,229 @@
# 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
"""Implementation of the ng_package rule.
"""
load("@build_bazel_rules_nodejs//:internal/collect_es6_sources.bzl", "collect_es6_sources")
load("@build_bazel_rules_nodejs//:internal/rollup/rollup_bundle.bzl",
"write_rollup_config",
"rollup_module_mappings_aspect",
"run_uglify",
"ROLLUP_ATTRS")
load("//packages/bazel/src:esm5.bzl", "esm5_outputs_aspect", "ESM5Info")
# TODO(alexeagle): this list is incomplete, add more as material ramps up
WELL_KNOWN_GLOBALS = {
"@angular/core": "ng.core",
"@angular/common": "ng.common",
"@angular/platform-browser": "ng.platformBrowser",
"rxjs/Observable": "Rx",
"rxjs/Observer": "Rx",
"rxjs/Subject": "Rx",
"rxjs/Subscription": "Rx",
"rxjs/observable/merge": "Rx.Observable",
"rxjs/observable/of": "Rx.Observable.prototype",
"rxjs/operator/concatMap": "Rx.Observable.prototype",
"rxjs/operator/filter": "Rx.Observable.prototype",
"rxjs/operator/map": "Rx.Observable.prototype",
"rxjs/operator/share": "Rx.Observable.prototype",
}
def _rollup(ctx, rollup_config, entry_point, inputs, js_output, format = "es"):
map_output = ctx.actions.declare_file(js_output.basename + ".map", sibling = js_output)
args = ctx.actions.args()
args.add(["--config", rollup_config.path])
args.add(["--input", entry_point])
args.add(["--output.file", js_output.path])
args.add(["--output.format", format])
args.add(["--name", ctx.label.name])
# Note: if the input has external source maps then we need to also install and use
# `rollup-plugin-sourcemaps`, which will require us to use rollup.config.js file instead
# of command line args
args.add("--sourcemap")
globals = dict(WELL_KNOWN_GLOBALS, **ctx.attr.globals)
externals = globals.keys()
args.add("--external")
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)
ctx.actions.run(
progress_message = "Angular Packaging: rolling up %s" % ctx.label.name,
mnemonic = "AngularPackageRollup",
inputs = inputs.to_list() + other_inputs,
outputs = [js_output, map_output],
executable = ctx.executable._rollup,
arguments = [args],
)
return struct(
js = js_output,
map = map_output,
)
# convert from [{js: js_file1, map: map_file1}, ...] to
# [js_filepath1, map_filepath1, ...]
def _flatten_paths(directory):
result = []
for f in directory:
result.extend([f.js.path, 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)
esm_2015_files = collect_es6_sources(ctx)
esm5_sources = depset()
root_dirs = []
for dep in ctx.attr.deps:
if ESM5Info in dep:
# TODO(alexeagle): we could make the module resolution in the rollup plugin
# faster if we kept the files grouped with their root dir. This approach just
# passes in both lists and requires multiple lookups (with expensive exception
# handling) to locate the files again.
transitive_output = dep[ESM5Info].transitive_output
root_dirs.extend(transitive_output.keys())
esm5_sources = depset(transitive=[esm5_sources] + transitive_output.values())
# These accumulators match the directory names where the files live in the
# Angular package format.
esm2015 = []
esm5 = []
bundles = []
for entry_point in [''] + ctx.attr.secondary_entry_points:
es2015_entry_point = "/".join([p for p in [
ctx.bin_dir.path,
ctx.label.package,
ctx.label.name + ".es6",
ctx.label.package,
entry_point,
"index.js",
] if p])
es5_entry_point = "/".join([p for p in [
ctx.label.package,
entry_point,
"index.js",
] if p])
if entry_point:
# TODO jasonaden says there is no particular reason these filenames differ
umd_output_filename = "-".join([ctx.label.package.split("/")[-1]] + entry_point.split("/"))
fesm_output_filename = entry_point.replace("/", "__")
fesm2015_output = ctx.actions.declare_file("fesm2015/%s.js" % fesm_output_filename)
fesm5_output = ctx.actions.declare_file("%s.js" % fesm_output_filename)
umd_output = ctx.actions.declare_file("%s.umd.js" % umd_output_filename)
min_output = ctx.actions.declare_file("%s.umd.min.js" % umd_output_filename)
else:
fesm2015_output = ctx.outputs.fesm2015
fesm5_output = ctx.outputs.fesm5
umd_output = ctx.outputs.umd
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))
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("/", "_"))
bundles.append(struct(js = min_output, map = uglify_sourcemap))
metadata_files = depset(transitive = [getattr(dep, "angular").flat_module_metadata
for dep in ctx.attr.deps
if hasattr(dep, "angular")])
# TODO: the args look long, maybe need to spill to a params file:
# https://docs.bazel.build/versions/master/skylark/lib/Args.html#use_param_file
args = ctx.actions.args()
args.add(npm_package_directory.path)
args.add(ctx.label.package)
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)
if ctx.file.readme_md:
other_inputs.append(ctx.file.readme_md)
if ctx.file.license_banner:
other_inputs.append(ctx.file.license_banner)
ctx.actions.run(
progress_message = "Angular Packaging: building npm package for %s" % ctx.label.name,
mnemonic = "AngularPackage",
inputs = esm5_sources.to_list() +
ctx.files.deps +
ctx.files.srcs +
other_inputs,
outputs = [npm_package_directory],
executable = ctx.executable._packager,
arguments = [args],
)
return struct(
files = depset([npm_package_directory])
)
NG_PACKAGE_ATTRS = dict(ROLLUP_ATTRS, **{
"srcs": attr.label_list(allow_files = True),
"deps": attr.label_list(aspects = [
rollup_module_mappings_aspect,
esm5_outputs_aspect,
]),
"readme_md": attr.label(allow_single_file = FileType([".md"])),
"globals": attr.string_dict(default={}),
"secondary_entry_points": attr.string_list(),
"_packager": attr.label(
default=Label("//packages/bazel/src/ng_package:packager"),
executable=True, cfg="host"),
"_rollup": attr.label(
default=Label("@build_bazel_rules_nodejs//internal/rollup"),
executable=True, cfg="host"),
"_rollup_config_tmpl": attr.label(
default=Label("@build_bazel_rules_nodejs//internal/rollup:rollup.config.js"),
allow_single_file=True),
"_uglify": attr.label(
default=Label("@build_bazel_rules_nodejs//internal/rollup:uglify"),
executable=True, cfg="host"),
})
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 {
"fesm5": "%s.js" % basename,
"fesm2015": "fesm2015/%s.js" % basename,
"umd": "%s.umd.js" % basename,
"umd_min": "%s.umd.min.js" % basename,
}
ng_package = rule(
implementation = _ng_package_impl,
attrs = NG_PACKAGE_ATTRS,
outputs = ng_package_outputs,
)

View File

@ -0,0 +1,141 @@
/**
* @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';
function filter(ext: string): (path: string) => boolean {
return f => f.endsWith(ext) && !f.endsWith(`.ngfactory${ext}`) && !f.endsWith(`.ngsummary${ext}`);
}
function main(args: string[]): number {
shx.set('-e');
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);
const bundles = bundlesArg.split(',').filter(s => !!s);
const srcs = srcsArg.split(',').filter(s => !!s);
shx.mkdir('-p', out);
let primaryEntryPoint: string|null = null;
const secondaryEntryPoints = new Set<string>();
function replaceVersionPlaceholders(filePath: string) {
if (stampData) {
const version = shx.grep('BUILD_SCM_VERSION', stampData).split(' ')[1].trim();
return shx.sed(/0.0.0-PLACEHOLDER/, version, filePath);
}
return shx.cat(filePath);
}
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);
shx.cp(file, dir);
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');
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;
}
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')));
const bundlesDir = path.join(out, 'bundles');
shx.mkdir('-p', bundlesDir);
bundles.forEach(bundle => { shx.cp(bundle, bundlesDir); });
const allsrcs = shx.find('-R', binDir);
allsrcs.filter(filter('.d.ts')).forEach((f: string) => {
const content = fs.readFileSync(f, {encoding: 'utf-8'})
// Strip the named AMD module for compatibility with non-bazel users
.replace(/^\/\/\/ <amd-module name=.*\/>\n/, '');
let outputPath: string;
if (f.endsWith('.bundle_index.d.ts')) {
outputPath = moveBundleIndex(f);
} else {
outputPath = path.join(out, path.relative(binDir, f));
}
shx.mkdir('-p', path.dirname(outputPath));
fs.writeFileSync(outputPath, content);
});
for (const src of srcs) {
replaceVersionPlaceholders(src).to(path.join(out, path.relative(srcDir, src)));
}
allsrcs.filter(filter('.bundle_index.metadata.json')).forEach((f: string) => {
replaceVersionPlaceholders(f).to(moveBundleIndex(f));
});
const licenseBanner = licenseFile ? fs.readFileSync(licenseFile, {encoding: 'utf-8'}) : '';
for (const secondaryEntryPoint of secondaryEntryPoints.values()) {
const baseName = secondaryEntryPoint.split('/').pop();
const dirName = path.join(...secondaryEntryPoint.split('/').slice(0, -1));
fs.writeFileSync(path.join(out, dirName, `${baseName}.metadata.json`), JSON.stringify({
'__symbolic': 'module',
'version': 3,
'metadata': {},
'exports': [{'from': `./${baseName}/${baseName}`}],
'flatModuleIndexRedirect': true
}) + '\n');
fs.writeFileSync(
path.join(out, dirName, `${baseName}.d.ts`),
// Format carefully to match existing build.sh output
licenseBanner + ' ' +
`
export * from './${baseName}/${baseName}'
`);
}
return 0;
}
if (require.main === module) {
process.exitCode = main(process.argv.slice(2));
}

View File

@ -0,0 +1,5 @@
{
"compilerOptions": {
"lib": ["es2015"]
}
}

View File

@ -0,0 +1,36 @@
load("//tools:defaults.bzl", "ts_library")
load("@build_bazel_rules_nodejs//:defs.bzl", "jasmine_node_test")
exports_files(["package.json"])
# The tests in this package must run in separate targets, since they change
# working directory and therefore have mutable global state that causes test
# isolation failures.
ts_library(
name = "core_spec_lib",
testonly = True,
srcs = ["core_package.spec.ts"],
deps = ["//packages:types"],
)
jasmine_node_test(
name = "core_package",
srcs = [":core_spec_lib"],
data = [
"//packages/core:npm_package",
],
)
ts_library(
name = "common_spec_lib",
testonly = True,
srcs = ["common_package.spec.ts"],
deps = ["//packages:types"],
)
jasmine_node_test(
name = "common_package",
srcs = [":common_spec_lib"],
data = ["//packages/common:npm_package"],
)

View File

@ -0,0 +1,50 @@
/**
* @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 path from 'path';
import * as shx from 'shelljs';
shx.cd(path.join(process.env['TEST_SRCDIR'], 'angular', 'packages', 'common', 'npm_package'));
describe('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',
'common-http-testing.umd.js.map',
'common-http-testing.umd.min.js',
'common-http-testing.umd.min.js.map',
'common-http.umd.js',
'common-http.umd.js.map',
'common-http.umd.min.js',
'common-http.umd.min.js.map',
'common-testing.umd.js',
'common-testing.umd.js.map',
'common-testing.umd.min.js',
'common-testing.umd.min.js.map',
'common.umd.js',
'common.umd.js.map',
'common.umd.min.js',
'common.umd.min.js.map',
]);
});
it('should have right fesm files', () => {
const expected = [
'common.js',
'common.js.map',
'http',
'http.js',
'http.js.map',
'http/testing.js',
'http/testing.js.map',
'testing.js',
'testing.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);
});
});

View File

@ -0,0 +1,227 @@
/**
* @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 path from 'path';
import * as shx from 'shelljs';
const corePackagePath =
path.join(process.env['TEST_SRCDIR'], 'angular', 'packages', 'core', 'npm_package');
shx.cd(corePackagePath);
/**
* Utility functions that allows me to create fs paths
* p`${foo}/some/${{bar}}/path` rather than path.join(foo, 'some',
*/
function p(templateStringArray: TemplateStringsArray) {
const segments = [];
for (const entry of templateStringArray) {
segments.push(...entry.split('/').filter(s => s !== ''));
}
return path.join(...segments);
}
describe('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`);
});
});
});
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)/);
});
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`);
});
});
describe('typescript support', () => {
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'); });
});
describe('closure', () => {
it('should contain externs', () => {
expect(shx.cat('src/testability/testability.externs.js')).toContain('/** @externs */');
});
});
describe('angular metadata', () => {
it('should have metadata.json files',
() => { expect(shx.cat('core.metadata.json')).toContain(`"__symbolic":"module"`); });
});
describe('fesm15', () => {
it('should have a fesm15 file in the /esm2015 directory',
() => { expect(shx.cat('esm2015/core.js')).toContain(`export {`); });
it('should have a source map', () => {
expect(shx.cat('esm2015/core.js.map'))
.toContain(`{"version":3,"file":"core.js","sources":`);
});
it('should have the version info in the header', () => {
expect(shx.cat('esm2015/core.js'))
.toMatch(/@license Angular v\d+\.\d+\.\d+(?!-PLACEHOLDER)/);
});
});
describe('fesm5', () => {
it('should have a fesm5 file in the /esm5 directory',
() => { expect(shx.cat('esm5/core.js')).toContain(`export {`); });
it('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');
});
});
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'); });
it('should have a source map next to the umd file',
() => { expect(shx.ls('bundles/core.umd.js.map').length).toBe(1, 'File not found'); });
it('should have a minified umd file in the /bundles directory',
() => { expect(shx.ls('bundles/core.umd.min.js').length).toBe(1, 'File not found'); });
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'); });
});
});
describe('secondary entry-point', () => {
describe('package.json', () => {
const packageJson = p `testing/package.json`;
it('should have a package.json file',
() => { expect(shx.grep('"name":', packageJson)).toContain(`@angular/core/testing`); });
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('"typings":', packageJson)).toContain(`./testing.d.ts`);
});
});
describe('typings', () => {
const typingsFile = p `testing/testing.d.ts`;
it('should have a typings file',
() => { expect(shx.cat(typingsFile)).toContain('export * from \'./public_api\';'); });
});
describe('typescript support', () => {
// TODO(i): why in the parent dir?
it('should have an \'redirect\' d.ts file in the parent dir',
() => { 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';`);
});
});
describe('angular metadata file', () => {
it('should have a \'redirect\' metadata.json file next to the d.ts file', () => {
expect(shx.cat('testing.metadata.json'))
.toContain(`"exports":[{"from":"./testing/testing"}],"flatModuleIndexRedirect":true`);
});
it('should have an \'actual\' metadata.json file', () => {
expect(shx.cat('testing/testing.metadata.json'))
.toContain(`"metadata":{"async":{"__symbolic":"function"},`);
});
});
describe('fesm15', () => {
it('should have a fesm15 file in the /esm2015 directory',
() => { expect(shx.cat('esm2015/testing.js')).toContain(`export {`); });
it('should have a source map', () => {
expect(shx.cat('esm2015/testing.js.map'))
.toContain(`{"version":3,"file":"testing.js","sources":`);
});
it('should have the version info in the header', () => {
expect(shx.cat('esm2015/testing.js'))
.toMatch(/@license Angular v\d+\.\d+\.\d+(?!-PLACEHOLDER)/);
});
});
describe('fesm5', () => {
it('should have a fesm5 file in the /esm5 directory',
() => { expect(shx.cat('esm5/testing.js')).toContain(`export {`); });
it('should have a source map', () => {
expect(shx.cat('esm5/testing.js.map'))
.toContain(`{"version":3,"file":"testing.js","sources":`);
});
});
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'); });
it('should have a source map next to the umd file', () => {
expect(shx.ls('bundles/core-testing.umd.js.map').length).toBe(1, 'File not found');
});
it('should have a minified umd file in the /bundles directory', () => {
expect(shx.ls('bundles/core-testing.umd.min.js').length).toBe(1, 'File not found');
});
it('should have a source map next to the minified umd file', () => {
expect(shx.ls('bundles/core-testing.umd.min.js.map').length).toBe(1, 'File not found');
});
});
});
});

View File

@ -1,6 +1,6 @@
package(default_visibility = ["//visibility:public"])
load("//tools:defaults.bzl", "ng_module")
load("//tools:defaults.bzl", "ng_module", "ng_package")
ng_module(
name = "common",
@ -16,3 +16,19 @@ ng_module(
"@rxjs",
],
)
ng_package(
name = "npm_package",
entry_point = "packages/common/index.js",
secondary_entry_points = [
"testing",
"http",
"http/testing",
],
deps = [
"//packages/common",
"//packages/common/http",
"//packages/common/http/testing",
"//packages/common/testing",
],
)

View File

@ -3,6 +3,7 @@ load("//packages/bazel:index.bzl", "ng_module")
ng_module(
name = "test_module",
srcs = glob(["*.ts"]),
entry_point = "index.ts",
module_name = "some_npm_module",
deps = ["//packages/core"],
)

View File

@ -1,6 +1,6 @@
package(default_visibility = ["//visibility:public"])
load("//tools:defaults.bzl", "ng_module")
load("//tools:defaults.bzl", "ng_module", "ng_package")
ng_module(
name = "core",
@ -16,3 +16,14 @@ ng_module(
"@rxjs",
],
)
ng_package(
name = "npm_package",
srcs = glob(["**/*.externs.js"] + ["**/package.json"]) + ["//packages/core/testing:npm_package_assets"],
entry_point = "packages/core/index.js",
secondary_entry_points = ["testing"],
deps = [
":core",
"//packages/core/testing",
],
)

View File

@ -4,10 +4,17 @@ load("//tools:defaults.bzl", "ng_module")
ng_module(
name = "testing",
srcs = glob(["**/*.ts"]),
srcs = glob(
["**/*.ts"],
),
module_name = "@angular/core/testing",
deps = [
"//packages:types",
"//packages/core",
],
)
filegroup(
name = "npm_package_assets",
srcs = ["package.json"],
)

View File

@ -1,6 +1,6 @@
"""Re-export of some bazel rules with repository-wide defaults."""
load("@build_bazel_rules_typescript//:defs.bzl", _ts_library = "ts_library")
load("//packages/bazel:index.bzl", _ng_module = "ng_module")
load("//packages/bazel:index.bzl", _ng_module = "ng_module", _ng_package = "ng_package")
DEFAULT_TSCONFIG = "//packages:tsconfig-build.json"
@ -9,7 +9,24 @@ def ts_library(tsconfig = None, **kwargs):
tsconfig = DEFAULT_TSCONFIG
_ts_library(tsconfig = tsconfig, **kwargs)
def ng_module(name, tsconfig = None, **kwargs):
def ng_module(name, tsconfig = None, entry_point = None, **kwargs):
if not tsconfig:
tsconfig = DEFAULT_TSCONFIG
_ng_module(name = name, tsconfig = tsconfig, **kwargs)
if not entry_point:
entry_point = "public_api.ts"
_ng_module(name = name, tsconfig = tsconfig, entry_point = entry_point, **kwargs)
def ng_package(name, readme_md = None, license_banner = None, stamp_data = None, **kwargs):
if not readme_md:
readme_md = "//packages:README.md"
if not license_banner:
license_banner = "//packages:license-banner.txt"
if not stamp_data:
stamp_data = "//tools:stamp_data"
_ng_package(
name = name,
readme_md = readme_md,
license_banner = license_banner,
stamp_data = stamp_data,
**kwargs)

View File

@ -91,12 +91,24 @@
dependencies:
"@types/node" "*"
"@types/events@*":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@types/events/-/events-1.1.0.tgz#93b1be91f63c184450385272c47b6496fd028e02"
"@types/fs-extra@4.0.2":
version "4.0.2"
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-4.0.2.tgz#7b9b1bbf85962cbe029b5a83c9b530d7c75af3ba"
dependencies:
"@types/node" "*"
"@types/glob@*":
version "5.0.35"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.35.tgz#1ae151c802cece940443b5ac246925c85189f32a"
dependencies:
"@types/events" "*"
"@types/minimatch" "*"
"@types/node" "*"
"@types/hammerjs@2.0.35":
version "2.0.35"
resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.35.tgz#7b7c950c7d54593e23bffc8d2b4feba9866a7277"
@ -105,6 +117,10 @@
version "2.2.22-alpha"
resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-2.2.22-alpha.tgz#eecaee43fe42ef6b5cfefad1bcc370c433f485bf"
"@types/minimatch@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
"@types/node@*":
version "8.0.28"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.28.tgz#86206716f8d9251cf41692e384264cbd7058ad60"
@ -125,6 +141,13 @@
version "2.53.42"
resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-2.53.42.tgz#74cb77fb6052edaff2a8984ddafd88d419f25cac"
"@types/shelljs@^0.7.8":
version "0.7.8"
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.7.8.tgz#4b4d6ee7926e58d7bca448a50ba442fd9f6715bd"
dependencies:
"@types/glob" "*"
"@types/node" "*"
"@types/source-map@^0.5.1":
version "0.5.1"
resolved "https://registry.yarnpkg.com/@types/source-map/-/source-map-0.5.1.tgz#7e74db5d06ab373a712356eebfaea2fad0ea2367"