feat(bazel): ng-new schematics with Bazel (#27277)
This commit creates a schematics for ng new command that builds the project with Bazel. PR Close #27277
This commit is contained in:
parent
7ec05b4d8c
commit
06d4a0c46e
|
@ -7,6 +7,7 @@ npm_package(
|
|||
"package.json",
|
||||
"protractor-utils.js",
|
||||
"//packages/bazel/src:package_assets",
|
||||
"//packages/bazel/src/builders:package_assets",
|
||||
"//packages/bazel/src/schematics:package_assets",
|
||||
],
|
||||
packages = [
|
||||
|
@ -19,5 +20,6 @@ npm_package(
|
|||
"//packages/bazel/src/ngc-wrapped:ngc_lib",
|
||||
"//packages/bazel/src/protractor/utils",
|
||||
"//packages/bazel/src/schematics/bazel-workspace",
|
||||
"//packages/bazel/src/schematics/ng-new",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"builders": {
|
||||
"build": {
|
||||
"class": "./index#Builder",
|
||||
"class": "./index",
|
||||
"schema": "./schema.json",
|
||||
"description": "Executes Bazel on a target."
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
* 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
|
||||
*
|
||||
* @fileoverview Bazel bundle builder
|
||||
* @fileoverview Bazel builder
|
||||
*/
|
||||
|
||||
import {BuildEvent, Builder as BuilderInterface, BuilderConfiguration, BuilderContext} from '@angular-devkit/architect';
|
||||
import {BuildEvent, Builder, BuilderConfiguration, BuilderContext} from '@angular-devkit/architect';
|
||||
import {getSystemPath, resolve} from '@angular-devkit/core';
|
||||
import {Observable, of } from 'rxjs';
|
||||
import {catchError, map, tap} from 'rxjs/operators';
|
||||
|
@ -16,7 +16,7 @@ import {catchError, map, tap} from 'rxjs/operators';
|
|||
import {checkInstallation, runBazel} from './bazel';
|
||||
import {Schema} from './schema';
|
||||
|
||||
export class Builder implements BuilderInterface<Schema> {
|
||||
class BazelBuilder implements Builder<Schema> {
|
||||
constructor(private context: BuilderContext) {}
|
||||
|
||||
run(builderConfig: BuilderConfiguration<Partial<Schema>>): Observable<BuildEvent> {
|
||||
|
@ -38,3 +38,5 @@ export class Builder implements BuilderInterface<Schema> {
|
|||
.pipe(map(() => ({success: true})), catchError(() => of ({success: false})), );
|
||||
}
|
||||
}
|
||||
|
||||
export default BazelBuilder;
|
||||
|
|
|
@ -15,6 +15,7 @@ jasmine_node_test(
|
|||
bootstrap = ["angular/tools/testing/init_node_spec.js"],
|
||||
deps = [
|
||||
"//packages/bazel/src/schematics/bazel-workspace:test",
|
||||
"//packages/bazel/src/schematics/ng-new:test",
|
||||
"//tools/testing:node",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -7,7 +7,15 @@ load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
|
|||
|
||||
ng_module(
|
||||
name = "src",
|
||||
srcs = glob(["**/*.ts"], exclude = ["**/*.spec.ts", "test.ts"]),
|
||||
srcs = glob(
|
||||
include = ["**/*.ts"],
|
||||
exclude = [
|
||||
"**/*.spec.ts",
|
||||
"main.ts",
|
||||
"test.ts",
|
||||
"initialize_testbed.ts",
|
||||
],
|
||||
),
|
||||
assets = glob([
|
||||
"**/*.css",
|
||||
"**/*.html",
|
||||
|
@ -21,7 +29,7 @@ ng_module(
|
|||
|
||||
rollup_bundle(
|
||||
name = "bundle",
|
||||
entry_point = "src/main",
|
||||
entry_point = "src/main.prod",
|
||||
deps = ["//src"],
|
||||
)
|
||||
|
||||
|
@ -50,7 +58,7 @@ ts_devserver(
|
|||
"npm/node_modules/zone.js/dist",
|
||||
"npm/node_modules/tslib",
|
||||
],
|
||||
entry_module = "<%= name %>/src/main",
|
||||
entry_module = "<%= name %>/src/main.dev",
|
||||
serving_path = "/bundle.min.js",
|
||||
static_files = [
|
||||
"@npm//node_modules/zone.js:dist/zone.min.js",
|
||||
|
@ -67,14 +75,28 @@ ts_library(
|
|||
deps = [
|
||||
":src",
|
||||
"@angular//packages/core/testing",
|
||||
"@angular//packages/platform-browser-dynamic/testing",
|
||||
"@npm//@types",
|
||||
],
|
||||
)
|
||||
|
||||
ts_library(
|
||||
name = "initialize_testbed",
|
||||
testonly = 1,
|
||||
srcs = [
|
||||
"initialize_testbed.ts",
|
||||
],
|
||||
deps = [
|
||||
"@angular//packages/core/testing",
|
||||
"@angular//packages/platform-browser-dynamic/testing",
|
||||
],
|
||||
)
|
||||
|
||||
ts_web_test_suite(
|
||||
name = "test",
|
||||
srcs = ["@npm//node_modules/tslib:tslib.js"],
|
||||
runtime_deps = [
|
||||
":initialize_testbed",
|
||||
],
|
||||
# do not sort
|
||||
bootstrap = [
|
||||
"@npm//node_modules/zone.js:dist/zone-testing-bundle.js",
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
/**
|
||||
* @fileoverview Provides a script to initialize TestBed before tests are run.
|
||||
* This file should be included in the "runtime_deps" of a "ts_web_test_suite"
|
||||
* rule.
|
||||
*/
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
|
|
@ -30,7 +30,7 @@ export default function(options: BazelWorkspaceOptions): Rule {
|
|||
const appDir = `${newProjectRoot}/${options.name}`;
|
||||
|
||||
const workspaceVersions = {
|
||||
'ANGULAR_VERSION': '7.0.2',
|
||||
'ANGULAR_VERSION': '7.1.0',
|
||||
'RULES_SASS_VERSION': '1.14.1',
|
||||
'RXJS_VERSION': '6.3.3',
|
||||
};
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
"name": "@angular/bazel",
|
||||
"version": "0.1",
|
||||
"schematics": {
|
||||
"ng-new": {
|
||||
"factory": "./ng-new",
|
||||
"schema": "./ng-new/schema.json",
|
||||
"description": "Create an Angular project that builds with Bazel."
|
||||
},
|
||||
"bazel-workspace": {
|
||||
"factory": "./bazel-workspace",
|
||||
"schema": "./bazel-workspace/schema.json",
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("//tools:defaults.bzl", "ts_library")
|
||||
|
||||
ts_library(
|
||||
name = "ng-new",
|
||||
srcs = [
|
||||
"index.ts",
|
||||
"schema.d.ts",
|
||||
],
|
||||
data = glob(["files/**/*"]) + [
|
||||
"schema.json",
|
||||
],
|
||||
deps = [
|
||||
"//packages/bazel/src/schematics/bazel-workspace",
|
||||
"@ngdeps//@angular-devkit/core",
|
||||
"@ngdeps//@angular-devkit/schematics",
|
||||
"@ngdeps//@schematics/angular",
|
||||
"@ngdeps//typescript",
|
||||
],
|
||||
)
|
||||
|
||||
ts_library(
|
||||
name = "test",
|
||||
testonly = True,
|
||||
srcs = [
|
||||
"index_spec.ts",
|
||||
],
|
||||
data = [
|
||||
"//packages/bazel/src/schematics:package_assets",
|
||||
],
|
||||
deps = [
|
||||
":ng-new",
|
||||
"@ngdeps//@angular-devkit/schematics",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,16 @@
|
|||
<!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>
|
|
@ -0,0 +1,4 @@
|
|||
import {platformBrowser} from '@angular/platform-browser';
|
||||
import {AppModuleNgFactory} from './app/app.module.ngfactory';
|
||||
|
||||
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);
|
|
@ -0,0 +1,6 @@
|
|||
import {enableProdMode} from '@angular/core';
|
||||
import {platformBrowser} from '@angular/platform-browser';
|
||||
import {AppModuleNgFactory} from './app/app.module.ngfactory';
|
||||
|
||||
enableProdMode();
|
||||
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);
|
|
@ -0,0 +1,180 @@
|
|||
/**
|
||||
* @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
|
||||
*
|
||||
* @fileoverview Schematics for ng-new project that builds with Bazel.
|
||||
*/
|
||||
|
||||
import {apply, applyTemplates, chain, externalSchematic, MergeStrategy, mergeWith, move, Rule, schematic, Tree, url, SchematicsException, UpdateRecorder,} from '@angular-devkit/schematics';
|
||||
import {parseJsonAst, JsonAstObject, strings, JsonValue} from '@angular-devkit/core';
|
||||
import {findPropertyInAstObject, insertPropertyInAstObjectInOrder} from '@schematics/angular/utility/json-utils';
|
||||
import {validateProjectName} from '@schematics/angular/utility/validation';
|
||||
import {getWorkspace} from '@schematics/angular/utility/config';
|
||||
import {Schema} from './schema';
|
||||
|
||||
function addDevDependenciesToPackageJson(options: Schema) {
|
||||
return (host: Tree) => {
|
||||
const packageJson = `${options.name}/package.json`;
|
||||
|
||||
if (!host.exists(packageJson)) {
|
||||
throw new Error(`Could not find ${packageJson}`);
|
||||
}
|
||||
const packageJsonContent = host.read(packageJson);
|
||||
if (!packageJsonContent) {
|
||||
throw new Error('Failed to read package.json content');
|
||||
}
|
||||
const jsonAst = parseJsonAst(packageJsonContent.toString()) as JsonAstObject;
|
||||
const deps = findPropertyInAstObject(jsonAst, 'dependencies') as JsonAstObject;
|
||||
const devDeps = findPropertyInAstObject(jsonAst, 'devDependencies') as JsonAstObject;
|
||||
|
||||
const angularCoreNode = findPropertyInAstObject(deps, '@angular/core');
|
||||
const angularCoreVersion = angularCoreNode !.value as string;
|
||||
|
||||
const devDependencies: {[k: string]: string} = {
|
||||
'@angular/bazel': angularCoreVersion,
|
||||
'@bazel/karma': '0.21.0',
|
||||
'@bazel/typescript': '0.21.0',
|
||||
};
|
||||
|
||||
const recorder = host.beginUpdate(packageJson);
|
||||
for (const packageName of Object.keys(devDependencies)) {
|
||||
const version = devDependencies[packageName];
|
||||
const indent = 4;
|
||||
insertPropertyInAstObjectInOrder(recorder, devDeps, packageName, version, indent);
|
||||
}
|
||||
host.commitUpdate(recorder);
|
||||
return host;
|
||||
};
|
||||
}
|
||||
|
||||
function overwriteMainAndIndex(options: Schema) {
|
||||
return (host: Tree) => {
|
||||
let newProjectRoot = '';
|
||||
try {
|
||||
const workspace = getWorkspace(host);
|
||||
newProjectRoot = workspace.newProjectRoot || '';
|
||||
} catch {
|
||||
}
|
||||
const srcDir = `${newProjectRoot}/${options.name}/src`;
|
||||
|
||||
return mergeWith(
|
||||
apply(
|
||||
url('./files'),
|
||||
[
|
||||
applyTemplates({
|
||||
utils: strings,
|
||||
...options,
|
||||
'dot': '.',
|
||||
}),
|
||||
move(srcDir),
|
||||
]),
|
||||
MergeStrategy.Overwrite);
|
||||
};
|
||||
}
|
||||
|
||||
function replacePropertyInAstObject(
|
||||
recorder: UpdateRecorder, node: JsonAstObject, propertyName: string, value: JsonValue,
|
||||
indent: number) {
|
||||
const property = findPropertyInAstObject(node, propertyName);
|
||||
if (property === null) {
|
||||
throw new Error(`Property ${propertyName} does not exist in JSON object`);
|
||||
}
|
||||
const {start, text} = property;
|
||||
recorder.remove(start.offset, text.length);
|
||||
const indentStr = '\n' +
|
||||
' '.repeat(indent);
|
||||
const content = JSON.stringify(value, null, ' ').replace(/\n/g, indentStr);
|
||||
recorder.insertLeft(start.offset, content);
|
||||
}
|
||||
|
||||
function updateWorkspaceFileToUseBazelBuilder(options: Schema): Rule {
|
||||
return (host: Tree, context: SchematicContext) => {
|
||||
const {name} = options;
|
||||
const workspacePath = `${name}/angular.json`;
|
||||
if (!host.exists(workspacePath)) {
|
||||
throw new SchematicsException(`Workspace file ${workspacePath} not found.`);
|
||||
}
|
||||
const workspaceBuffer = host.read(workspacePath) !;
|
||||
const workspaceJsonAst = parseJsonAst(workspaceBuffer.toString()) as JsonAstObject;
|
||||
const projects = findPropertyInAstObject(workspaceJsonAst, 'projects');
|
||||
if (!projects) {
|
||||
throw new SchematicsException('Expect projects in angular.json to be an Object');
|
||||
}
|
||||
const project = findPropertyInAstObject(projects as JsonAstObject, name);
|
||||
if (!project) {
|
||||
throw new SchematicsException(`Expected projects to contain ${name}`);
|
||||
}
|
||||
const recorder = host.beginUpdate(workspacePath);
|
||||
const indent = 6;
|
||||
replacePropertyInAstObject(
|
||||
recorder, project as JsonAstObject, 'architect', {
|
||||
'build': {
|
||||
'builder': '@angular/bazel:build',
|
||||
'options': {'targetLabel': '//src:bundle.js', 'bazelCommand': 'build'},
|
||||
'configurations': {'production': {'targetLabel': '//src:bundle'}}
|
||||
},
|
||||
'serve': {
|
||||
'builder': '@angular/bazel:build',
|
||||
'options': {'targetLabel': '//src:devserver', 'bazelCommand': 'run'},
|
||||
'configurations': {'production': {'targetLabel': '//src:prodserver'}}
|
||||
},
|
||||
'extract-i18n': {
|
||||
'builder': '@angular-devkit/build-angular:extract-i18n',
|
||||
'options': {'browserTarget': `${name}:build`}
|
||||
},
|
||||
'test': {
|
||||
'builder': '@angular/bazel:build',
|
||||
'options': {'bazelCommand': 'test', 'targetLabel': '//src/...'}
|
||||
},
|
||||
'lint': {
|
||||
'builder': '@angular-devkit/build-angular:tslint',
|
||||
'options': {
|
||||
'tsConfig': ['src/tsconfig.app.json', 'src/tsconfig.spec.json'],
|
||||
'exclude': ['**/node_modules/**']
|
||||
}
|
||||
}
|
||||
},
|
||||
indent);
|
||||
|
||||
const e2e = `${options.name}-e2e`;
|
||||
const e2eNode = findPropertyInAstObject(projects as JsonAstObject, e2e);
|
||||
if (e2eNode) {
|
||||
replacePropertyInAstObject(
|
||||
recorder, e2eNode as JsonAstObject, 'architect', {
|
||||
'e2e': {
|
||||
'builder': '@angular/bazel:build',
|
||||
'options': {'bazelCommand': 'test', 'targetLabel': '//e2e:devserver_test'},
|
||||
'configurations': {'production': {'targetLabel': '//e2e:prodserver_test'}}
|
||||
},
|
||||
'lint': {
|
||||
'builder': '@angular-devkit/build-angular:tslint',
|
||||
'options': {'tsConfig': 'e2e/tsconfig.e2e.json', 'exclude': ['**/node_modules/**']}
|
||||
}
|
||||
},
|
||||
indent);
|
||||
}
|
||||
|
||||
host.commitUpdate(recorder);
|
||||
return host;
|
||||
};
|
||||
}
|
||||
|
||||
export default function(options: Schema): Rule {
|
||||
return (host: Tree) => {
|
||||
validateProjectName(options.name);
|
||||
|
||||
return chain([
|
||||
externalSchematic('@schematics/angular', 'ng-new', {
|
||||
...options,
|
||||
skipInstall: true,
|
||||
}),
|
||||
addDevDependenciesToPackageJson(options),
|
||||
schematic('bazel-workspace', options),
|
||||
overwriteMainAndIndex(options),
|
||||
updateWorkspaceFileToUseBazelBuilder(options),
|
||||
]);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* @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 {SchematicTestRunner} from '@angular-devkit/schematics/testing';
|
||||
|
||||
describe('Ng-new Schematic', () => {
|
||||
const schematicRunner =
|
||||
new SchematicTestRunner('@angular/bazel', require.resolve('../collection.json'), );
|
||||
const defaultOptions = {
|
||||
name: 'demo',
|
||||
version: '7.0.0',
|
||||
};
|
||||
|
||||
it('should call external @schematics/angular', () => {
|
||||
const options = {...defaultOptions};
|
||||
const host = schematicRunner.runSchematic('ng-new', options);
|
||||
const {files} = host;
|
||||
// External schematic should produce workspace file angular.json
|
||||
expect(files).toContain('/demo/angular.json');
|
||||
});
|
||||
|
||||
it('should add @angular/bazel to package.json dependencies', () => {
|
||||
const options = {...defaultOptions};
|
||||
const host = schematicRunner.runSchematic('ng-new', options);
|
||||
const {files} = host;
|
||||
expect(files).toContain('/demo/package.json');
|
||||
const content = host.readContent('/demo/package.json');
|
||||
expect(() => JSON.parse(content)).not.toThrow();
|
||||
const json = JSON.parse(content);
|
||||
const core = '@angular/core';
|
||||
const bazel = '@angular/bazel';
|
||||
expect(Object.keys(json)).toContain('dependencies');
|
||||
expect(Object.keys(json)).toContain('devDependencies');
|
||||
expect(Object.keys(json.dependencies)).toContain(core);
|
||||
expect(Object.keys(json.devDependencies)).toContain(bazel);
|
||||
expect(json.dependencies[core]).toBe(json.devDependencies[bazel]);
|
||||
});
|
||||
|
||||
it('should create Bazel workspace file', () => {
|
||||
const options = {...defaultOptions};
|
||||
const host = schematicRunner.runSchematic('ng-new', options);
|
||||
const {files} = host;
|
||||
expect(files).toContain('/demo/WORKSPACE');
|
||||
expect(files).toContain('/demo/BUILD.bazel');
|
||||
});
|
||||
|
||||
it('should produce main.prod.ts for AOT', () => {
|
||||
const options = {...defaultOptions};
|
||||
const host = schematicRunner.runSchematic('ng-new', options);
|
||||
const {files} = host;
|
||||
// main.prod.ts is used by Bazel for AOT
|
||||
expect(files).toContain('/demo/src/main.prod.ts');
|
||||
// main.ts is produced by original ng-new schematics
|
||||
// This file should be present for backwards compatibility.
|
||||
expect(files).toContain('/demo/src/main.ts');
|
||||
});
|
||||
|
||||
it('should 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>');
|
||||
});
|
||||
|
||||
it('should update angular.json to use Bazel builder', () => {
|
||||
const options = {...defaultOptions};
|
||||
const host = schematicRunner.runSchematic('ng-new', options);
|
||||
const {files} = host;
|
||||
expect(files).toContain('/demo/angular.json');
|
||||
const content = host.readContent('/demo/angular.json');
|
||||
expect(() => JSON.parse(content)).not.toThrow();
|
||||
const json = JSON.parse(content);
|
||||
let {architect} = json.projects.demo;
|
||||
expect(architect.build.builder).toBe('@angular/bazel:build');
|
||||
expect(architect.serve.builder).toBe('@angular/bazel:build');
|
||||
expect(architect.test.builder).toBe('@angular/bazel:build');
|
||||
architect = json.projects['demo-e2e'].architect;
|
||||
expect(architect.e2e.builder).toBe('@angular/bazel:build');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,103 @@
|
|||
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE
|
||||
// CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...).
|
||||
|
||||
// tslint:disable:no-global-tslint-disable
|
||||
// tslint:disable
|
||||
|
||||
export interface Schema {
|
||||
/**
|
||||
* Initial repository commit information.
|
||||
*/
|
||||
commit?: CommitUnion;
|
||||
/**
|
||||
* Flag to toggle creation of an application in the new workspace.
|
||||
*/
|
||||
createApplication?: boolean;
|
||||
/**
|
||||
* The directory name to create the workspace in.
|
||||
*/
|
||||
directory?: string;
|
||||
/**
|
||||
* EXPERIMENTAL: Specifies whether to create a new application which uses the Ivy rendering
|
||||
* engine.
|
||||
*/
|
||||
experimentalIvy?: boolean;
|
||||
/**
|
||||
* Specifies if the style will be in the ts file.
|
||||
*/
|
||||
inlineStyle?: boolean;
|
||||
/**
|
||||
* Specifies if the template will be in the ts file.
|
||||
*/
|
||||
inlineTemplate?: boolean;
|
||||
/**
|
||||
* Link CLI to global version (internal development only).
|
||||
*/
|
||||
linkCli?: boolean;
|
||||
/**
|
||||
* Create a barebones project without any testing frameworks
|
||||
*/
|
||||
minimal?: boolean;
|
||||
/**
|
||||
* The name of the workspace.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* The path where new projects will be created.
|
||||
*/
|
||||
newProjectRoot?: string;
|
||||
/**
|
||||
* The prefix to apply to generated selectors.
|
||||
*/
|
||||
prefix?: string;
|
||||
/**
|
||||
* Generates a routing module.
|
||||
*/
|
||||
routing?: boolean;
|
||||
/**
|
||||
* Skip initializing a git repository.
|
||||
*/
|
||||
skipGit?: boolean;
|
||||
/**
|
||||
* Skip installing dependency packages.
|
||||
*/
|
||||
skipInstall?: boolean;
|
||||
/**
|
||||
* Skip creating spec files.
|
||||
*/
|
||||
skipTests?: boolean;
|
||||
/**
|
||||
* The file extension to be used for style files.
|
||||
*/
|
||||
style?: string;
|
||||
/**
|
||||
* The version of the Angular CLI to use.
|
||||
*/
|
||||
version: string;
|
||||
/**
|
||||
* Specifies the view encapsulation strategy.
|
||||
*/
|
||||
viewEncapsulation?: ViewEncapsulation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initial repository commit information.
|
||||
*/
|
||||
export type CommitUnion = boolean | CommitObject;
|
||||
|
||||
export interface CommitObject {
|
||||
email: string;
|
||||
message?: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the view encapsulation strategy.
|
||||
*/
|
||||
export enum ViewEncapsulation {
|
||||
Emulated = 'Emulated',
|
||||
Native = 'Native',
|
||||
None = 'None',
|
||||
ShadowDOM = 'ShadowDom',
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/schema",
|
||||
"id": "SchematicsAngularNgNew",
|
||||
"title": "Angular Ng New Options Schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"directory": {
|
||||
"type": "string",
|
||||
"description": "The directory name to create the workspace in."
|
||||
},
|
||||
"name": {
|
||||
"description": "The name of the workspace.",
|
||||
"type": "string",
|
||||
"format": "html-selector",
|
||||
"$default": {
|
||||
"$source": "argv",
|
||||
"index": 0
|
||||
},
|
||||
"x-prompt": "What name would you like to use for the project?"
|
||||
},
|
||||
"experimentalIvy": {
|
||||
"description": "EXPERIMENTAL: Specifies whether to create a new application which uses the Ivy rendering engine.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"skipInstall": {
|
||||
"description": "Skip installing dependency packages.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"linkCli": {
|
||||
"description": "Link CLI to global version (internal development only).",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"visible": false
|
||||
},
|
||||
"skipGit": {
|
||||
"description": "Skip initializing a git repository.",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"alias": "g"
|
||||
},
|
||||
"commit": {
|
||||
"description": "Initial repository commit information.",
|
||||
"oneOf": [
|
||||
{ "type": "boolean" },
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string",
|
||||
"format": "email"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"email"
|
||||
]
|
||||
}
|
||||
],
|
||||
"default": true
|
||||
},
|
||||
"newProjectRoot": {
|
||||
"description": "The path where new projects will be created.",
|
||||
"type": "string",
|
||||
"default": "projects"
|
||||
},
|
||||
"inlineStyle": {
|
||||
"description": "Specifies if the style will be in the ts file.",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"alias": "s"
|
||||
},
|
||||
"inlineTemplate": {
|
||||
"description": "Specifies if the template will be in the ts file.",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"alias": "t"
|
||||
},
|
||||
"viewEncapsulation": {
|
||||
"description": "Specifies the view encapsulation strategy.",
|
||||
"enum": ["Emulated", "Native", "None", "ShadowDom"],
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the Angular CLI to use.",
|
||||
"visible": false,
|
||||
"$default": {
|
||||
"$source": "ng-cli-version"
|
||||
}
|
||||
},
|
||||
"routing": {
|
||||
"type": "boolean",
|
||||
"description": "Generates a routing module.",
|
||||
"default": false,
|
||||
"x-prompt": "Would you like to add Angular routing?"
|
||||
},
|
||||
"prefix": {
|
||||
"type": "string",
|
||||
"format": "html-selector",
|
||||
"description": "The prefix to apply to generated selectors.",
|
||||
"minLength": 1,
|
||||
"default": "app",
|
||||
"alias": "p"
|
||||
},
|
||||
"style": {
|
||||
"description": "The file extension to be used for style files.",
|
||||
"type": "string",
|
||||
"default": "css",
|
||||
"x-prompt": {
|
||||
"message": "Which stylesheet format would you like to use?",
|
||||
"type": "list",
|
||||
"items": [
|
||||
{ "value": "css", "label": "CSS" },
|
||||
{ "value": "scss", "label": "SCSS [ http://sass-lang.com ]" },
|
||||
{ "value": "sass", "label": "SASS [ http://sass-lang.com ]" },
|
||||
{ "value": "less", "label": "LESS [ http://lesscss.org ]" },
|
||||
{ "value": "styl", "label": "Stylus [ http://stylus-lang.com ]" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"skipTests": {
|
||||
"description": "Skip creating spec files.",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"alias": "S"
|
||||
},
|
||||
"createApplication": {
|
||||
"description": "Flag to toggle creation of an application in the new workspace.",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"minimal": {
|
||||
"description": "Create a barebones project without any testing frameworks",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"version"
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue