refactor(bazel): use web_package rule for index.html (#27995)

index.html needs to have the zone.js and the project bundle injected
using script tags. This used to be done explicitly by specifying a
new index.html but with `web_package` rule introduced in rules_nodejs,
it is now possible to perform the injection dynamically.

PR Close #27995
This commit is contained in:
Keen Yee Liau 2018-12-06 10:41:03 -08:00 committed by Andrew Kushnir
parent 2c9f0139a3
commit e8495b460f
5 changed files with 50 additions and 49 deletions

View File

@ -3,6 +3,7 @@ package(default_visibility = ["//visibility:public"])
load("@angular//:index.bzl", "ng_module")
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library", "ts_web_test_suite")
load("@build_bazel_rules_nodejs//:defs.bzl", "rollup_bundle", "history_server")
load("@build_bazel_rules_nodejs//internal/web_package:web_package.bzl", "web_package")
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
ng_module(
@ -33,22 +34,23 @@ rollup_bundle(
deps = ["//src"],
)
# Needed because the prodserver only loads static files that appear under this
# package.
genrule(
name = "zonejs",
srcs = ["@npm//node_modules/zone.js:dist/zone.min.js"],
outs = ["zone.min.js"],
cmd = "cp $< $@",
web_package(
name = "prodapp",
assets = [
# do not sort
"@npm//node_modules/zone.js:dist/zone.min.js",
":bundle.min.js",
],
data = [
":bundle",
],
index_html = "index.html",
)
history_server(
name = "prodserver",
data = [
"index.html",
":bundle",
":zonejs",
],
data = [":prodapp"],
templated_args = ["src/prodapp"],
)
ts_devserver(
@ -63,8 +65,8 @@ ts_devserver(
static_files = [
"@npm//node_modules/zone.js:dist/zone.min.js",
"@npm//node_modules/tslib:tslib.js",
"index.html",
],
index_html = "index.html",
deps = [":src"],
)

View File

@ -81,7 +81,7 @@ export default function(options: BazelWorkspaceOptions): Rule {
const workspaceVersions = {
'RULES_NODEJS_VERSION': '0.16.5',
'RULES_TYPESCRIPT_VERSION': '0.22.0',
'RULES_TYPESCRIPT_VERSION': '0.22.1',
'ANGULAR_VERSION': existingVersions.Angular || clean(latestVersions.Angular),
'RXJS_VERSION': existingVersions.RxJs || clean(latestVersions.RxJs),
// TODO(kyliau): Consider moving this to latest-versions.ts

View File

@ -1,16 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title><%= utils.classify(name) %></title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
<script src="/zone.min.js"></script>
<script src="/bundle.min.js"></script>
</body>
</html>

View File

@ -15,6 +15,11 @@ import {validateProjectName} from '@schematics/angular/utility/validation';
import {getWorkspace} from '@schematics/angular/utility/config';
import {Schema} from './schema';
/**
* Packages that build under Bazel require additional dev dependencies. This
* function adds those dependencies to "devDependencies" section in
* package.json.
*/
function addDevDependenciesToPackageJson(options: Schema) {
return (host: Tree) => {
const packageJson = `${options.name}/package.json`;
@ -38,8 +43,8 @@ function addDevDependenciesToPackageJson(options: Schema) {
// TODO(kyliau): Consider moving this to latest-versions.ts
'@bazel/bazel': '^0.21.0',
'@bazel/ibazel': '^0.9.0',
'@bazel/karma': '^0.22.0',
'@bazel/typescript': '^0.22.0',
'@bazel/karma': '^0.22.1',
'@bazel/typescript': '^0.22.1',
};
const recorder = host.beginUpdate(packageJson);
@ -53,7 +58,13 @@ function addDevDependenciesToPackageJson(options: Schema) {
};
}
function overwriteMainAndIndex(options: Schema) {
/**
* Append main.dev.ts and main.prod.ts to src directory. These files are needed
* by Bazel for devserver and prodserver, respectively. They are different from
* main.ts generated by CLI because they use platformBrowser (AOT) instead of
* platformBrowserDynamic (JIT).
*/
function addDevAndProdMainForAot(options: Schema) {
return (host: Tree) => {
let newProjectRoot = '';
try {
@ -63,18 +74,14 @@ function overwriteMainAndIndex(options: Schema) {
}
const srcDir = `${newProjectRoot}/${options.name}/src`;
return mergeWith(
apply(
url('./files'),
[
applyTemplates({
utils: strings,
...options,
'dot': '.',
}),
move(srcDir),
]),
MergeStrategy.Overwrite);
return mergeWith(apply(url('./files'), [
applyTemplates({
utils: strings,
...options,
'dot': '.',
}),
move(srcDir),
]));
};
}
@ -199,8 +206,8 @@ export default function(options: Schema): Rule {
skipInstall: true,
}),
addDevDependenciesToPackageJson(options),
addDevAndProdMainForAot(options),
schematic('bazel-workspace', options),
overwriteMainAndIndex(options),
overwriteGitignore(options),
updateWorkspaceFileToUseBazelBuilder(options),
]);

View File

@ -70,14 +70,22 @@ describe('Ng-new Schematic', () => {
expect(files).toContain('/demo/src/main.ts');
});
it('should overwrite index.html with script tags', () => {
it('should not overwrite index.html with script tags', () => {
const options = {...defaultOptions};
const host = schematicRunner.runSchematic('ng-new', options);
const {files} = host;
expect(files).toContain('/demo/src/index.html');
const content = host.readContent('/demo/src/index.html');
expect(content).toMatch('<script src="/zone.min.js"></script>');
expect(content).toMatch('<script src="/bundle.min.js"></script>');
expect(content).not.toMatch('<script src="/zone.min.js"></script>');
expect(content).not.toMatch('<script src="/bundle.min.js"></script>');
});
it('should generate main.dev.ts and main.prod.ts', () => {
const options = {...defaultOptions};
const host = schematicRunner.runSchematic('ng-new', options);
const {files} = host;
expect(files).toContain('/demo/src/main.dev.ts');
expect(files).toContain('/demo/src/main.prod.ts');
});
it('should overwrite .gitignore for bazel-out directory', () => {