mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-15 18:13:38 +08:00
feat(@schematics/angular): production builds by default
With this change we do several changes to the `angular.json` configuration for `build` , `server` and `app-shell` targets so that these are `production` by default. - build, server and app-shell targets are configured to run production by default. - We add a new configuration named `development` to run the mentioned builder targets in development. Ex: `ng build --configuration development`. - When adding `universal` or `app-shell`, we generate the full set of configurations as per the `buiid` target. Previously, we only generated the `production` configuration. - We added a helper script in `package.json` to run build in watch mode. `npm run watch` which is a shortcut for `ng build --watch --configuration development`
This commit is contained in:
parent
a5877bf917
commit
1de6d71edd
@ -52,7 +52,7 @@ describe('PWA Schematic', () => {
|
||||
schematicRunner.runSchematicAsync('ng-add', defaultOptions, appTree).toPromise().then(tree => {
|
||||
const configText = tree.readContent('/angular.json');
|
||||
const config = JSON.parse(configText);
|
||||
const swFlag = config.projects.bar.architect.build.configurations.production.serviceWorker;
|
||||
const swFlag = config.projects.bar.architect.build.options.serviceWorker;
|
||||
expect(swFlag).toEqual(true);
|
||||
done();
|
||||
}, done.fail);
|
||||
|
@ -155,7 +155,7 @@ function addUniversalTarget(options: AppShellOptions): Rule {
|
||||
}
|
||||
|
||||
function addAppShellConfigToWorkspace(options: AppShellOptions): Rule {
|
||||
return () => {
|
||||
return (host, context) => {
|
||||
if (!options.route) {
|
||||
throw new SchematicsException(`Route is not defined`);
|
||||
}
|
||||
@ -166,20 +166,44 @@ function addAppShellConfigToWorkspace(options: AppShellOptions): Rule {
|
||||
return;
|
||||
}
|
||||
|
||||
// Validation of targets is handled already in the main function.
|
||||
// Duplicate keys means that we have configurations in both server and build builders.
|
||||
const serverConfigKeys = project.targets.get('server')?.configurations ?? {};
|
||||
const buildConfigKeys = project.targets.get('build')?.configurations ?? {};
|
||||
|
||||
const configurationNames = Object.keys({
|
||||
...serverConfigKeys,
|
||||
...buildConfigKeys,
|
||||
});
|
||||
|
||||
const configurations: Record<string, {}> = {};
|
||||
for (const key of configurationNames) {
|
||||
if (!serverConfigKeys[key]) {
|
||||
context.logger.warn(`Skipped adding "${key}" configuration to "app-shell" target as it's missing from "server" target.`);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!buildConfigKeys[key]) {
|
||||
context.logger.warn(`Skipped adding "${key}" configuration to "app-shell" target as it's missing from "build" target.`);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
configurations[key] = {
|
||||
browserTarget: `${options.clientProject}:build:${key}`,
|
||||
serverTarget: `${options.clientProject}:server:${key}`,
|
||||
};
|
||||
}
|
||||
|
||||
project.targets.add({
|
||||
name: 'app-shell',
|
||||
builder: Builders.AppShell,
|
||||
defaultConfiguration: configurations['production'] ? 'production' : undefined,
|
||||
options: {
|
||||
browserTarget: `${options.clientProject}:build`,
|
||||
serverTarget: `${options.clientProject}:server`,
|
||||
route: options.route,
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
browserTarget: `${options.clientProject}:build:production`,
|
||||
serverTarget: `${options.clientProject}:server:production`,
|
||||
},
|
||||
},
|
||||
configurations,
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -242,9 +266,9 @@ function addServerRoutes(options: AppShellOptions): Rule {
|
||||
if (!isImported(moduleSource, 'Routes', '@angular/router')) {
|
||||
const recorder = host.beginUpdate(modulePath);
|
||||
const routesChange = insertImport(moduleSource,
|
||||
modulePath,
|
||||
'Routes',
|
||||
'@angular/router');
|
||||
modulePath,
|
||||
'Routes',
|
||||
'@angular/router');
|
||||
if (routesChange) {
|
||||
applyToUpdateRecorder(recorder, [routesChange]);
|
||||
}
|
||||
@ -263,16 +287,16 @@ function addServerRoutes(options: AppShellOptions): Rule {
|
||||
if (!isImported(moduleSource, 'RouterModule', '@angular/router')) {
|
||||
const recorder = host.beginUpdate(modulePath);
|
||||
const routerModuleChange = insertImport(moduleSource,
|
||||
modulePath,
|
||||
'RouterModule',
|
||||
'@angular/router');
|
||||
modulePath,
|
||||
'RouterModule',
|
||||
'@angular/router');
|
||||
|
||||
if (routerModuleChange) {
|
||||
applyToUpdateRecorder(recorder, [routerModuleChange]);
|
||||
}
|
||||
|
||||
const metadataChange = addSymbolToNgModuleMetadata(
|
||||
moduleSource, modulePath, 'imports', 'RouterModule.forRoot(routes)');
|
||||
moduleSource, modulePath, 'imports', 'RouterModule.forRoot(routes)');
|
||||
if (metadataChange) {
|
||||
applyToUpdateRecorder(recorder, metadataChange);
|
||||
}
|
||||
|
@ -68,9 +68,9 @@ describe('App Shell Schematic', () => {
|
||||
const content = tree.readContent(filePath);
|
||||
const workspace = JSON.parse(content);
|
||||
const target = workspace.projects.bar.architect['app-shell'];
|
||||
expect(target.options.browserTarget).toEqual('bar:build');
|
||||
expect(target.options.serverTarget).toEqual('bar:server');
|
||||
expect(target.options.route).toEqual('shell');
|
||||
expect(target.configurations.development.browserTarget).toEqual('bar:build:development');
|
||||
expect(target.configurations.development.serverTarget).toEqual('bar:server:development');
|
||||
expect(target.configurations.production.browserTarget).toEqual('bar:build:production');
|
||||
expect(target.configurations.production.serverTarget).toEqual('bar:server:production');
|
||||
});
|
||||
|
@ -172,6 +172,7 @@ function addAppToWorkspaceFile(options: ApplicationOptions, appDir: string): Rul
|
||||
targets: {
|
||||
build: {
|
||||
builder: Builders.Browser,
|
||||
defaultConfiguration: 'production',
|
||||
options: {
|
||||
outputPath: `dist/${options.name}`,
|
||||
index: `${sourceRoot}/index.html`,
|
||||
@ -190,30 +191,35 @@ function addAppToWorkspaceFile(options: ApplicationOptions, appDir: string): Rul
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
budgets,
|
||||
fileReplacements: [{
|
||||
replace: `${sourceRoot}/environments/environment.ts`,
|
||||
with: `${sourceRoot}/environments/environment.prod.ts`,
|
||||
}],
|
||||
buildOptimizer: true,
|
||||
optimization: true,
|
||||
outputHashing: 'all',
|
||||
sourceMap: false,
|
||||
namedChunks: false,
|
||||
extractLicenses: true,
|
||||
vendorChunk: false,
|
||||
buildOptimizer: true,
|
||||
budgets,
|
||||
},
|
||||
development: {
|
||||
vendorChunk: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
serve: {
|
||||
builder: Builders.DevServer,
|
||||
options: {
|
||||
browserTarget: `${options.name}:build`,
|
||||
},
|
||||
defaultConfiguration: 'development',
|
||||
options: {},
|
||||
configurations: {
|
||||
production: {
|
||||
browserTarget: `${options.name}:build:production`,
|
||||
},
|
||||
development: {
|
||||
browserTarget: `${options.name}:build:development`,
|
||||
},
|
||||
},
|
||||
},
|
||||
'extract-i18n': {
|
||||
|
@ -48,14 +48,17 @@ export default function (options: E2eOptions): Rule {
|
||||
project.targets.add({
|
||||
name: 'e2e',
|
||||
builder: Builders.Protractor,
|
||||
defaultConfiguration: 'development',
|
||||
options: {
|
||||
protractorConfig: `${root}/protractor.conf.js`,
|
||||
devServerTarget: `${options.relatedAppName}:serve`,
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
devServerTarget: `${options.relatedAppName}:serve:production`,
|
||||
},
|
||||
development: {
|
||||
devServerTarget: `${options.relatedAppName}:serve:development`,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -94,9 +94,9 @@ describe('Application Schematic', () => {
|
||||
const tree = await schematicRunner.runSchematicAsync('e2e', defaultOptions, applicationTree)
|
||||
.toPromise();
|
||||
const workspace = JSON.parse(tree.readContent('/angular.json'));
|
||||
const e2eOptions = workspace.projects.foo.architect.e2e.options;
|
||||
expect(e2eOptions.protractorConfig).toEqual('projects/foo/e2e/protractor.conf.js');
|
||||
expect(e2eOptions.devServerTarget).toEqual('foo:serve');
|
||||
const { options, configurations } = workspace.projects.foo.architect.e2e;
|
||||
expect(options.protractorConfig).toEqual('projects/foo/e2e/protractor.conf.js');
|
||||
expect(configurations.development.devServerTarget).toEqual('foo:serve:development');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -95,14 +95,17 @@ function addLibToWorkspaceFile(
|
||||
targets: {
|
||||
build: {
|
||||
builder: Builders.NgPackagr,
|
||||
defaultConfiguration: 'production',
|
||||
options: {
|
||||
tsConfig: `${projectRoot}/tsconfig.lib.json`,
|
||||
project: `${projectRoot}/ng-package.json`,
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
tsConfig: `${projectRoot}/tsconfig.lib.prod.json`,
|
||||
},
|
||||
development: {
|
||||
tsConfig: `${projectRoot}/tsconfig.lib.json`,
|
||||
},
|
||||
},
|
||||
},
|
||||
test: {
|
||||
|
@ -309,22 +309,22 @@ describe('Library Schematic', () => {
|
||||
const config = getJsonFileContent(tree, '/angular.json');
|
||||
const project = config.projects.foo;
|
||||
expect(project.root).toEqual('foo');
|
||||
const buildOpt = project.architect.build.options;
|
||||
expect(buildOpt.project).toEqual('foo/ng-package.json');
|
||||
expect(buildOpt.tsConfig).toEqual('foo/tsconfig.lib.json');
|
||||
const { options, configurations } = project.architect.build;
|
||||
expect(options.project).toEqual('foo/ng-package.json');
|
||||
expect(configurations.production.tsConfig).toEqual('foo/tsconfig.lib.prod.json');
|
||||
|
||||
const appTsConfig = getJsonFileContent(tree, '/foo/tsconfig.lib.json');
|
||||
expect(appTsConfig.extends).toEqual('../tsconfig.json');
|
||||
const libTsConfig = getJsonFileContent(tree, '/foo/tsconfig.lib.json');
|
||||
expect(libTsConfig.extends).toEqual('../tsconfig.json');
|
||||
const specTsConfig = getJsonFileContent(tree, '/foo/tsconfig.spec.json');
|
||||
expect(specTsConfig.extends).toEqual('../tsconfig.json');
|
||||
});
|
||||
|
||||
it(`should add 'production' configuration`, async () => {
|
||||
it(`should add 'development' configuration`, async () => {
|
||||
const tree = await schematicRunner.runSchematicAsync('library', defaultOptions, workspaceTree)
|
||||
.toPromise();
|
||||
|
||||
const workspace = JSON.parse(tree.readContent('/angular.json'));
|
||||
expect(workspace.projects.foo.architect.build.configurations.production).toBeDefined();
|
||||
expect(workspace.projects.foo.architect.build.configurations.development).toBeDefined();
|
||||
});
|
||||
|
||||
it(`should add 'ng-packagr' builder`, async () => {
|
||||
|
@ -49,6 +49,8 @@ describe('Migration to version 9', () => {
|
||||
tree,
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
tree.overwrite('angular.json', tree.readContent('angular.json').replace(/development/g, 'production'));
|
||||
});
|
||||
|
||||
describe('i18n configuration', () => {
|
||||
|
@ -93,6 +93,8 @@ describe('Migration to version 9', () => {
|
||||
);
|
||||
|
||||
tree.overwrite('tsconfig.app.json', tsConfig);
|
||||
|
||||
tree.overwrite('angular.json', tree.readContent('angular.json').replace(/development/g, 'production'));
|
||||
});
|
||||
|
||||
describe('scripts and style options', () => {
|
||||
@ -277,6 +279,8 @@ describe('Migration to version 9', () => {
|
||||
tree,
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
tree.overwrite('angular.json', tree.readContent('angular.json').replace(/development/g, 'production'));
|
||||
});
|
||||
|
||||
it('should add optimization option when not defined', async () => {
|
||||
|
@ -130,21 +130,12 @@ export default function (options: ServiceWorkerOptions): Rule {
|
||||
if (!buildTarget) {
|
||||
throw targetBuildNotFoundError();
|
||||
}
|
||||
const buildOptions =
|
||||
(buildTarget.options || {}) as unknown as BrowserBuilderOptions;
|
||||
let buildConfiguration;
|
||||
if (options.configuration && buildTarget.configurations) {
|
||||
buildConfiguration =
|
||||
buildTarget.configurations[options.configuration] as unknown as BrowserBuilderOptions | undefined;
|
||||
}
|
||||
|
||||
const config = buildConfiguration || buildOptions;
|
||||
const buildOptions = (buildTarget.options || {}) as unknown as BrowserBuilderOptions;
|
||||
const root = project.root;
|
||||
buildOptions.serviceWorker = true;
|
||||
buildOptions.ngswConfigPath = join(normalize(root), 'ngsw-config.json');
|
||||
|
||||
config.serviceWorker = true;
|
||||
config.ngswConfigPath = join(normalize(root), 'ngsw-config.json');
|
||||
|
||||
let { resourcesOutputPath = '' } = config;
|
||||
let { resourcesOutputPath = '' } = buildOptions;
|
||||
if (resourcesOutputPath) {
|
||||
resourcesOutputPath = normalize(`/${resourcesOutputPath}`);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ describe('Service Worker Schematic', () => {
|
||||
const defaultOptions: ServiceWorkerOptions = {
|
||||
project: 'bar',
|
||||
target: 'build',
|
||||
configuration: 'production',
|
||||
configuration: '',
|
||||
};
|
||||
|
||||
let appTree: UnitTestTree;
|
||||
@ -45,25 +45,13 @@ describe('Service Worker Schematic', () => {
|
||||
.toPromise();
|
||||
});
|
||||
|
||||
it('should update the production configuration', async () => {
|
||||
it('should add `serviceWorker` option to build target', async () => {
|
||||
const tree = await schematicRunner.runSchematicAsync('service-worker', defaultOptions, appTree)
|
||||
.toPromise();
|
||||
const configText = tree.readContent('/angular.json');
|
||||
const config = JSON.parse(configText);
|
||||
const swFlag = config.projects.bar.architect
|
||||
.build.configurations.production.serviceWorker;
|
||||
expect(swFlag).toEqual(true);
|
||||
});
|
||||
const buildConfig = JSON.parse(configText).projects.bar.architect.build;
|
||||
|
||||
it('should update the target options if no configuration is set', async () => {
|
||||
const options = { ...defaultOptions, configuration: '' };
|
||||
const tree = await schematicRunner.runSchematicAsync('service-worker', options, appTree)
|
||||
.toPromise();
|
||||
const configText = tree.readContent('/angular.json');
|
||||
const config = JSON.parse(configText);
|
||||
const swFlag = config.projects.bar.architect
|
||||
.build.options.serviceWorker;
|
||||
expect(swFlag).toEqual(true);
|
||||
expect(buildConfig.options.serviceWorker).toBeTrue();
|
||||
});
|
||||
|
||||
it('should add the necessary dependency', async () => {
|
||||
@ -162,8 +150,7 @@ describe('Service Worker Schematic', () => {
|
||||
expect(tree.exists(path)).toEqual(true);
|
||||
|
||||
const { projects } = JSON.parse(tree.readContent('/angular.json'));
|
||||
expect(projects.bar.architect.build.configurations.production.ngswConfigPath)
|
||||
.toBe('projects/bar/ngsw-config.json');
|
||||
expect(projects.bar.architect.build.options.ngswConfigPath).toBe('projects/bar/ngsw-config.json');
|
||||
});
|
||||
|
||||
it('should add $schema in ngsw-config.json with correct relative path', async () => {
|
||||
@ -214,7 +201,7 @@ describe('Service Worker Schematic', () => {
|
||||
|
||||
it('should add resourcesOutputPath to root assets when specified', async () => {
|
||||
const config = JSON.parse(appTree.readContent('/angular.json'));
|
||||
config.projects.bar.architect.build.configurations.production.resourcesOutputPath = 'outDir';
|
||||
config.projects.bar.architect.build.options.resourcesOutputPath = 'outDir';
|
||||
appTree.overwrite('/angular.json', JSON.stringify(config));
|
||||
const tree = await schematicRunner.runSchematicAsync('service-worker', defaultOptions, appTree)
|
||||
.toPromise();
|
||||
@ -243,7 +230,6 @@ describe('Service Worker Schematic', () => {
|
||||
expect(tree.exists('/ngsw-config.json')).toBe(true);
|
||||
|
||||
const { projects } = JSON.parse(tree.readContent('/angular.json'));
|
||||
expect(projects.foo.architect.build.configurations.production.ngswConfigPath)
|
||||
.toBe('ngsw-config.json');
|
||||
expect(projects.foo.architect.build.options.ngswConfigPath).toBe('ngsw-config.json');
|
||||
});
|
||||
});
|
||||
|
@ -20,7 +20,7 @@
|
||||
"configuration": {
|
||||
"type": "string",
|
||||
"description": "The configuration to apply service worker to.",
|
||||
"default": "production"
|
||||
"x-deprecated": "No longer has an effect."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -6,6 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {
|
||||
JsonValue,
|
||||
Path,
|
||||
basename,
|
||||
join,
|
||||
@ -35,62 +36,65 @@ import { findBootstrapModuleCall, findBootstrapModulePath } from '../utility/ng-
|
||||
import { relativePathToWorkspaceRoot } from '../utility/paths';
|
||||
import { targetBuildNotFoundError } from '../utility/project-targets';
|
||||
import { getWorkspace, updateWorkspace } from '../utility/workspace';
|
||||
import { BrowserBuilderOptions, Builders, OutputHashing } from '../utility/workspace-models';
|
||||
import { BrowserBuilderOptions, Builders } from '../utility/workspace-models';
|
||||
import { Schema as UniversalOptions } from './schema';
|
||||
|
||||
function updateConfigFile(options: UniversalOptions, tsConfigDirectory: Path): Rule {
|
||||
return updateWorkspace(workspace => {
|
||||
const clientProject = workspace.projects.get(options.clientProject);
|
||||
|
||||
if (clientProject) {
|
||||
const buildTarget = clientProject.targets.get('build');
|
||||
let fileReplacements;
|
||||
if (buildTarget && buildTarget.configurations && buildTarget.configurations.production) {
|
||||
fileReplacements = buildTarget.configurations.production.fileReplacements;
|
||||
}
|
||||
|
||||
if (buildTarget && buildTarget.options) {
|
||||
buildTarget.options.outputPath = `dist/${options.clientProject}/browser`;
|
||||
}
|
||||
|
||||
// In case the browser builder hashes the assets
|
||||
// we need to add this setting to the server builder
|
||||
// as otherwise when assets it will be requested twice.
|
||||
// One for the server which will be unhashed, and other on the client which will be hashed.
|
||||
let outputHashing: OutputHashing | undefined;
|
||||
if (buildTarget && buildTarget.configurations && buildTarget.configurations.production) {
|
||||
switch (buildTarget.configurations.production.outputHashing as OutputHashing) {
|
||||
case 'all':
|
||||
case 'media':
|
||||
outputHashing = 'media';
|
||||
break;
|
||||
const getServerOptions = (options: Record<string, JsonValue | undefined> = {}): {} => {
|
||||
return {
|
||||
outputHashing: options?.outputHashing === 'all' ? 'media' : options?.outputHashing,
|
||||
fileReplacements: options?.fileReplacements,
|
||||
optimization: options?.optimization === undefined ? undefined : !!options?.optimization,
|
||||
sourceMap: options?.sourceMap,
|
||||
localization: options?.localization,
|
||||
stylePreprocessorOptions: options?.stylePreprocessorOptions,
|
||||
resourcesOutputPath: options?.resourcesOutputPath,
|
||||
deployUrl: options?.deployUrl,
|
||||
i18nMissingTranslation: options?.i18nMissingTranslation,
|
||||
preserveSymlinks: options?.preserveSymlinks,
|
||||
extractLicenses: options?.extractLicenses,
|
||||
};
|
||||
};
|
||||
|
||||
const buildTarget = clientProject.targets.get('build');
|
||||
if (buildTarget?.options) {
|
||||
buildTarget.options.outputPath = `dist/${options.clientProject}/browser`;
|
||||
}
|
||||
|
||||
const buildConfigurations = buildTarget?.configurations;
|
||||
const configurations: Record<string, {}> = {};
|
||||
if (buildConfigurations) {
|
||||
for (const [key, options] of Object.entries(buildConfigurations)) {
|
||||
configurations[key] = getServerOptions(options);
|
||||
}
|
||||
}
|
||||
|
||||
const mainPath = options.main as string;
|
||||
const serverTsConfig = join(tsConfigDirectory, 'tsconfig.server.json');
|
||||
|
||||
clientProject.targets.add({
|
||||
name: 'server',
|
||||
builder: Builders.Server,
|
||||
defaultConfiguration: 'production',
|
||||
options: {
|
||||
outputPath: `dist/${options.clientProject}/server`,
|
||||
main: join(normalize(clientProject.root), 'src', mainPath.endsWith('.ts') ? mainPath : mainPath + '.ts'),
|
||||
tsConfig: serverTsConfig,
|
||||
...(buildTarget?.options ? getServerOptions(buildTarget?.options) : {}),
|
||||
},
|
||||
configurations: {
|
||||
production: {
|
||||
outputHashing,
|
||||
fileReplacements,
|
||||
sourceMap: false,
|
||||
optimization: true,
|
||||
},
|
||||
},
|
||||
configurations,
|
||||
});
|
||||
|
||||
const lintTarget = clientProject.targets.get('lint');
|
||||
if (lintTarget && lintTarget.options && Array.isArray(lintTarget.options.tsConfig)) {
|
||||
lintTarget.options.tsConfig =
|
||||
lintTarget.options.tsConfig.concat(serverTsConfig);
|
||||
lintTarget.options.tsConfig = lintTarget.options.tsConfig.concat(serverTsConfig);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -156,13 +156,9 @@ describe('Universal Schematic', () => {
|
||||
expect(opts.main).toEqual('projects/bar/src/main.server.ts');
|
||||
expect(opts.tsConfig).toEqual('projects/bar/tsconfig.server.json');
|
||||
const configurations = targets.server.configurations;
|
||||
expect(configurations.production).toBeDefined();
|
||||
expect(configurations.production.fileReplacements).toBeDefined();
|
||||
expect(configurations.production.outputHashing).toBe('media');
|
||||
const fileReplacements = targets.server.configurations.production.fileReplacements;
|
||||
expect(fileReplacements.length).toEqual(1);
|
||||
expect(fileReplacements[0].replace).toEqual('projects/bar/src/environments/environment.ts');
|
||||
expect(fileReplacements[0].with).toEqual('projects/bar/src/environments/environment.prod.ts');
|
||||
expect(configurations.production.fileReplacements.length).toEqual(1);
|
||||
expect(configurations.production.fileReplacements[0].replace).toEqual('projects/bar/src/environments/environment.ts');
|
||||
expect(configurations.production.fileReplacements[0].with).toEqual('projects/bar/src/environments/environment.prod.ts');
|
||||
});
|
||||
|
||||
it('should update workspace with a build target outputPath', async () => {
|
||||
|
@ -4,7 +4,8 @@
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build"<% if (!minimal) { %>,
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development"<% if (!minimal) { %>,
|
||||
"test": "ng test",
|
||||
"lint": "ng lint"<% } %>
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user