Skip to content

Commit a263063

Browse files
authored
build: avoid duplication of mdc dependencies by generating package.json (#24697)
As part of the Yarn PNP changes we moved from `peerDependencies` in the experimental package to actual `dependencies` on all individual MDC packages we rely on. This is necessary for Yarn PnP and conceptually also makes the package more correct/safe. This resulted in duplication of the MDC dependencies, making MDC updates more complicated. We can avoid duplication by auto-inserting the dependencies. That way we keep two places for the MDC deps: * The project `package.json` * `packages.bzl` for the Bazel analysis phase/Starlark.
1 parent 9d1c47e commit a263063

File tree

5 files changed

+142
-95
lines changed

5 files changed

+142
-95
lines changed

src/material-experimental/BUILD.bazel

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,23 @@ sass_library(
3434
deps = [":theming_scss_lib"],
3535
)
3636

37+
# Generate the material-experimental `package.json` by adding all MDC dependencies
38+
# from the project root to the `package-base.json` file. This is done to avoid
39+
# duplication and make the update process of MDC dependencies more obvious.
40+
# Note that we need to explicitly reference all individual `@material/` dependencies as
41+
# our code imports from the individual dependencies (and not from the kitchen-sink package)
42+
genrule(
43+
name = "package_json",
44+
srcs = ["package-base.json"],
45+
outs = ["package.json"],
46+
cmd = "$(execpath //tools/mdc-deps:add-to-package-json) $< > $@",
47+
exec_tools = ["//tools/mdc-deps:add-to-package-json"],
48+
)
49+
3750
ng_package(
3851
name = "npm_package",
3952
srcs = [
40-
"package.json",
53+
":package_json",
4154
":sass_lib",
4255
":theming_scss_lib",
4356
],
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"name": "@angular/material-experimental",
3+
"version": "0.0.0-PLACEHOLDER",
4+
"description": "Experimental components for Angular Material",
5+
"repository": {
6+
"type": "git",
7+
"url": "https://github.com/angular/components.git"
8+
},
9+
"license": "MIT",
10+
"bugs": {
11+
"url": "https://github.com/angular/components/issues"
12+
},
13+
"homepage": "https://github.com/angular/components#readme",
14+
"exports": {
15+
".": {
16+
"sass": "./_index.scss"
17+
},
18+
"./mdc-theming/prebuilt/indigo-pink.css": {
19+
"style": "./mdc-theming/prebuilt/indigo-pink.css"
20+
},
21+
"./mdc-theming/prebuilt/deeppurple-amber.css": {
22+
"style": "./mdc-theming/prebuilt/deeppurple-amber.css"
23+
},
24+
"./mdc-theming/prebuilt/pink-bluegrey.css": {
25+
"style": "./mdc-theming/prebuilt/pink-bluegrey.css"
26+
},
27+
"./mdc-theming/prebuilt/purple-green.css": {
28+
"style": "./mdc-theming/prebuilt/purple-green.css"
29+
},
30+
"./mdc-theming/prebuilt/*": {
31+
"style": "./mdc-theming/prebuilt/*.css"
32+
}
33+
},
34+
"peerDependencies": {
35+
"@angular/animations": "0.0.0-NG",
36+
"@angular/cdk": "0.0.0-PLACEHOLDER",
37+
"@angular/core": "0.0.0-NG",
38+
"@angular/common": "0.0.0-NG",
39+
"@angular/forms": "0.0.0-NG",
40+
"@angular/platform-browser": "0.0.0-NG",
41+
"@angular/material": "0.0.0-PLACEHOLDER"
42+
},
43+
"dependencies": {
44+
"tslib": "0.0.0-TSLIB"
45+
},
46+
"sideEffects": false
47+
}

src/material-experimental/package.json

Lines changed: 0 additions & 94 deletions
This file was deleted.

tools/mdc-deps/BUILD.bazel

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")
2+
load("//tools:defaults.bzl", "ts_library")
3+
4+
package(default_visibility = ["//visibility:public"])
5+
6+
ts_library(
7+
name = "lib",
8+
srcs = glob(["**/*.ts"]),
9+
# TODO(ESM): remove this once the Bazel NodeJS rules can handle ESM with `nodejs_binary`.
10+
devmode_module = "commonjs",
11+
deps = [
12+
"@npm//@bazel/runfiles",
13+
"@npm//@types/node",
14+
],
15+
)
16+
17+
nodejs_binary(
18+
name = "add-to-package-json",
19+
data = [
20+
":lib",
21+
"//:package.json",
22+
],
23+
entry_point = ":add-to-package-json.ts",
24+
templated_args = ["--nobazel_run_linker"],
25+
)

tools/mdc-deps/add-to-package-json.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import * as fs from 'fs';
2+
3+
import {runfiles} from '@bazel/runfiles';
4+
5+
interface PackageJson {
6+
name: string;
7+
dependencies?: Record<string, string>;
8+
devDependencies?: Record<string, string>;
9+
}
10+
11+
/**
12+
* Inserts all MDC packages from the project `package.json` to the `dependencies`
13+
* of the specified base package json file. The output JSON is written to stdout.
14+
*
15+
* Note that the MDC version placeholder (from the `/packages.bzl` substitutions)
16+
* will be used as value for the MDC dependency entries.
17+
*
18+
* @param basePackageJsonPath Absolute disk path to the base `package.json` file.
19+
*/
20+
async function main(basePackageJsonPath: string) {
21+
const projectPkgJsonPath = runfiles.resolveWorkspaceRelative('package.json');
22+
const projectPkgJson = JSON.parse(
23+
await fs.promises.readFile(projectPkgJsonPath, 'utf8'),
24+
) as PackageJson;
25+
26+
const mdcDeps = Object.keys(projectPkgJson.devDependencies ?? []).filter(pkgName =>
27+
pkgName.startsWith('@material/'),
28+
);
29+
30+
if (mdcDeps.length === 0) {
31+
throw new Error('Could not find `@material/` MDC dependencies in project `package.json`.');
32+
}
33+
34+
const basePackageJson = JSON.parse(
35+
await fs.promises.readFile(basePackageJsonPath, 'utf8'),
36+
) as PackageJson;
37+
38+
if (basePackageJson.dependencies === undefined) {
39+
basePackageJson.dependencies = {};
40+
}
41+
42+
// Add all MDC dependencies as explicit `dependencies`.
43+
for (const pkgName of mdcDeps) {
44+
basePackageJson.dependencies[pkgName] = '0.0.0-MDC';
45+
}
46+
47+
process.stdout.write(JSON.stringify(basePackageJson, null, 2));
48+
}
49+
50+
if (require.main === module) {
51+
const [basePackageJsonPath] = process.argv.slice(2);
52+
main(basePackageJsonPath).catch(e => {
53+
console.error(e);
54+
process.exitCode = 1;
55+
});
56+
}

0 commit comments

Comments
 (0)