301 lines
12 KiB
JavaScript
301 lines
12 KiB
JavaScript
|
"use strict";
|
||
|
/**
|
||
|
* @license
|
||
|
* Copyright Google LLC 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
|
||
|
*/
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
const core_1 = require("@angular-devkit/core");
|
||
|
const schematics_1 = require("@angular-devkit/schematics");
|
||
|
const tasks_1 = require("@angular-devkit/schematics/tasks");
|
||
|
const dependencies_1 = require("../utility/dependencies");
|
||
|
const latest_versions_1 = require("../utility/latest-versions");
|
||
|
const paths_1 = require("../utility/paths");
|
||
|
const workspace_1 = require("../utility/workspace");
|
||
|
const workspace_models_1 = require("../utility/workspace-models");
|
||
|
const schema_1 = require("./schema");
|
||
|
function default_1(options) {
|
||
|
return async (host, context) => {
|
||
|
const { appDir, appRootSelector, componentOptions, folderName, sourceDir } = await getAppOptions(host, options);
|
||
|
return (0, schematics_1.chain)([
|
||
|
addAppToWorkspaceFile(options, appDir, folderName),
|
||
|
options.standalone
|
||
|
? (0, schematics_1.noop)()
|
||
|
: (0, schematics_1.schematic)('module', {
|
||
|
name: 'app',
|
||
|
commonModule: false,
|
||
|
flat: true,
|
||
|
routing: options.routing,
|
||
|
routingScope: 'Root',
|
||
|
path: sourceDir,
|
||
|
project: options.name,
|
||
|
}),
|
||
|
(0, schematics_1.schematic)('component', {
|
||
|
name: 'app',
|
||
|
selector: appRootSelector,
|
||
|
flat: true,
|
||
|
path: sourceDir,
|
||
|
skipImport: true,
|
||
|
project: options.name,
|
||
|
...componentOptions,
|
||
|
}),
|
||
|
(0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)(options.standalone ? './files/standalone-files' : './files/module-files'), [
|
||
|
options.routing ? (0, schematics_1.noop)() : (0, schematics_1.filter)((path) => !path.endsWith('app.routes.ts.template')),
|
||
|
componentOptions.skipTests
|
||
|
? (0, schematics_1.filter)((path) => !path.endsWith('.spec.ts.template'))
|
||
|
: (0, schematics_1.noop)(),
|
||
|
(0, schematics_1.applyTemplates)({
|
||
|
utils: schematics_1.strings,
|
||
|
...options,
|
||
|
...componentOptions,
|
||
|
selector: appRootSelector,
|
||
|
relativePathToWorkspaceRoot: (0, paths_1.relativePathToWorkspaceRoot)(appDir),
|
||
|
appName: options.name,
|
||
|
folderName,
|
||
|
}),
|
||
|
(0, schematics_1.move)(appDir),
|
||
|
]), schematics_1.MergeStrategy.Overwrite),
|
||
|
(0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)('./files/common-files'), [
|
||
|
options.minimal
|
||
|
? (0, schematics_1.filter)((path) => !path.endsWith('tsconfig.spec.json.template'))
|
||
|
: (0, schematics_1.noop)(),
|
||
|
componentOptions.inlineTemplate
|
||
|
? (0, schematics_1.filter)((path) => !path.endsWith('component.html.template'))
|
||
|
: (0, schematics_1.noop)(),
|
||
|
(0, schematics_1.applyTemplates)({
|
||
|
utils: schematics_1.strings,
|
||
|
...options,
|
||
|
selector: appRootSelector,
|
||
|
relativePathToWorkspaceRoot: (0, paths_1.relativePathToWorkspaceRoot)(appDir),
|
||
|
appName: options.name,
|
||
|
folderName,
|
||
|
}),
|
||
|
(0, schematics_1.move)(appDir),
|
||
|
]), schematics_1.MergeStrategy.Overwrite),
|
||
|
options.ssr
|
||
|
? (0, schematics_1.schematic)('ssr', {
|
||
|
project: options.name,
|
||
|
skipInstall: true,
|
||
|
})
|
||
|
: (0, schematics_1.noop)(),
|
||
|
options.skipPackageJson ? (0, schematics_1.noop)() : addDependenciesToPackageJson(options),
|
||
|
]);
|
||
|
};
|
||
|
}
|
||
|
exports.default = default_1;
|
||
|
function addDependenciesToPackageJson(options) {
|
||
|
return (host, context) => {
|
||
|
[
|
||
|
{
|
||
|
type: dependencies_1.NodeDependencyType.Dev,
|
||
|
name: '@angular/compiler-cli',
|
||
|
version: latest_versions_1.latestVersions.Angular,
|
||
|
},
|
||
|
{
|
||
|
type: dependencies_1.NodeDependencyType.Dev,
|
||
|
name: '@angular-devkit/build-angular',
|
||
|
version: latest_versions_1.latestVersions.DevkitBuildAngular,
|
||
|
},
|
||
|
{
|
||
|
type: dependencies_1.NodeDependencyType.Dev,
|
||
|
name: 'typescript',
|
||
|
version: latest_versions_1.latestVersions['typescript'],
|
||
|
},
|
||
|
].forEach((dependency) => (0, dependencies_1.addPackageJsonDependency)(host, dependency));
|
||
|
if (!options.skipInstall) {
|
||
|
context.addTask(new tasks_1.NodePackageInstallTask());
|
||
|
}
|
||
|
return host;
|
||
|
};
|
||
|
}
|
||
|
function addAppToWorkspaceFile(options, appDir, folderName) {
|
||
|
let projectRoot = appDir;
|
||
|
if (projectRoot) {
|
||
|
projectRoot += '/';
|
||
|
}
|
||
|
const schematics = {};
|
||
|
if (options.inlineTemplate ||
|
||
|
options.inlineStyle ||
|
||
|
options.minimal ||
|
||
|
options.style !== schema_1.Style.Css) {
|
||
|
const componentSchematicsOptions = {};
|
||
|
if (options.inlineTemplate ?? options.minimal) {
|
||
|
componentSchematicsOptions.inlineTemplate = true;
|
||
|
}
|
||
|
if (options.inlineStyle ?? options.minimal) {
|
||
|
componentSchematicsOptions.inlineStyle = true;
|
||
|
}
|
||
|
if (options.style && options.style !== schema_1.Style.Css) {
|
||
|
componentSchematicsOptions.style = options.style;
|
||
|
}
|
||
|
schematics['@schematics/angular:component'] = componentSchematicsOptions;
|
||
|
}
|
||
|
if (options.skipTests || options.minimal) {
|
||
|
const schematicsWithTests = [
|
||
|
'class',
|
||
|
'component',
|
||
|
'directive',
|
||
|
'guard',
|
||
|
'interceptor',
|
||
|
'pipe',
|
||
|
'resolver',
|
||
|
'service',
|
||
|
];
|
||
|
schematicsWithTests.forEach((type) => {
|
||
|
(schematics[`@schematics/angular:${type}`] ??= {}).skipTests = true;
|
||
|
});
|
||
|
}
|
||
|
if (!options.standalone) {
|
||
|
const schematicsWithStandalone = ['component', 'directive', 'pipe'];
|
||
|
schematicsWithStandalone.forEach((type) => {
|
||
|
(schematics[`@schematics/angular:${type}`] ??= {}).standalone = false;
|
||
|
});
|
||
|
}
|
||
|
const sourceRoot = (0, core_1.join)((0, core_1.normalize)(projectRoot), 'src');
|
||
|
let budgets = [];
|
||
|
if (options.strict) {
|
||
|
budgets = [
|
||
|
{
|
||
|
type: 'initial',
|
||
|
maximumWarning: '500kb',
|
||
|
maximumError: '1mb',
|
||
|
},
|
||
|
{
|
||
|
type: 'anyComponentStyle',
|
||
|
maximumWarning: '2kb',
|
||
|
maximumError: '4kb',
|
||
|
},
|
||
|
];
|
||
|
}
|
||
|
else {
|
||
|
budgets = [
|
||
|
{
|
||
|
type: 'initial',
|
||
|
maximumWarning: '2mb',
|
||
|
maximumError: '5mb',
|
||
|
},
|
||
|
{
|
||
|
type: 'anyComponentStyle',
|
||
|
maximumWarning: '6kb',
|
||
|
maximumError: '10kb',
|
||
|
},
|
||
|
];
|
||
|
}
|
||
|
const inlineStyleLanguage = options?.style !== schema_1.Style.Css ? options.style : undefined;
|
||
|
const project = {
|
||
|
root: (0, core_1.normalize)(projectRoot),
|
||
|
sourceRoot,
|
||
|
projectType: workspace_models_1.ProjectType.Application,
|
||
|
prefix: options.prefix || 'app',
|
||
|
schematics,
|
||
|
targets: {
|
||
|
build: {
|
||
|
builder: workspace_models_1.Builders.Application,
|
||
|
defaultConfiguration: 'production',
|
||
|
options: {
|
||
|
outputPath: `dist/${folderName}`,
|
||
|
index: `${sourceRoot}/index.html`,
|
||
|
browser: `${sourceRoot}/main.ts`,
|
||
|
polyfills: ['zone.js'],
|
||
|
tsConfig: `${projectRoot}tsconfig.app.json`,
|
||
|
inlineStyleLanguage,
|
||
|
assets: [`${sourceRoot}/favicon.ico`, `${sourceRoot}/assets`],
|
||
|
styles: [`${sourceRoot}/styles.${options.style}`],
|
||
|
scripts: [],
|
||
|
},
|
||
|
configurations: {
|
||
|
production: {
|
||
|
budgets,
|
||
|
outputHashing: 'all',
|
||
|
},
|
||
|
development: {
|
||
|
optimization: false,
|
||
|
extractLicenses: false,
|
||
|
sourceMap: true,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
serve: {
|
||
|
builder: workspace_models_1.Builders.DevServer,
|
||
|
defaultConfiguration: 'development',
|
||
|
options: {},
|
||
|
configurations: {
|
||
|
production: {
|
||
|
buildTarget: `${options.name}:build:production`,
|
||
|
},
|
||
|
development: {
|
||
|
buildTarget: `${options.name}:build:development`,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
'extract-i18n': {
|
||
|
builder: workspace_models_1.Builders.ExtractI18n,
|
||
|
options: {
|
||
|
buildTarget: `${options.name}:build`,
|
||
|
},
|
||
|
},
|
||
|
test: options.minimal
|
||
|
? undefined
|
||
|
: {
|
||
|
builder: workspace_models_1.Builders.Karma,
|
||
|
options: {
|
||
|
polyfills: ['zone.js', 'zone.js/testing'],
|
||
|
tsConfig: `${projectRoot}tsconfig.spec.json`,
|
||
|
inlineStyleLanguage,
|
||
|
assets: [`${sourceRoot}/favicon.ico`, `${sourceRoot}/assets`],
|
||
|
styles: [`${sourceRoot}/styles.${options.style}`],
|
||
|
scripts: [],
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
};
|
||
|
return (0, workspace_1.updateWorkspace)((workspace) => {
|
||
|
workspace.projects.add({
|
||
|
name: options.name,
|
||
|
...project,
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
async function getAppOptions(host, options) {
|
||
|
const appRootSelector = `${options.prefix}-root`;
|
||
|
const componentOptions = getComponentOptions(options);
|
||
|
const workspace = await (0, workspace_1.getWorkspace)(host);
|
||
|
const newProjectRoot = workspace.extensions.newProjectRoot || '';
|
||
|
// If scoped project (i.e. "@foo/bar"), convert dir to "foo/bar".
|
||
|
let folderName = options.name.startsWith('@') ? options.name.slice(1) : options.name;
|
||
|
if (/[A-Z]/.test(folderName)) {
|
||
|
folderName = schematics_1.strings.dasherize(folderName);
|
||
|
}
|
||
|
const appDir = options.projectRoot === undefined
|
||
|
? (0, core_1.join)((0, core_1.normalize)(newProjectRoot), folderName)
|
||
|
: (0, core_1.normalize)(options.projectRoot);
|
||
|
const sourceDir = `${appDir}/src/app`;
|
||
|
return {
|
||
|
appDir,
|
||
|
appRootSelector,
|
||
|
componentOptions,
|
||
|
folderName,
|
||
|
sourceDir,
|
||
|
};
|
||
|
}
|
||
|
function getComponentOptions(options) {
|
||
|
const componentOptions = !options.minimal
|
||
|
? {
|
||
|
inlineStyle: options.inlineStyle,
|
||
|
inlineTemplate: options.inlineTemplate,
|
||
|
skipTests: options.skipTests,
|
||
|
style: options.style,
|
||
|
viewEncapsulation: options.viewEncapsulation,
|
||
|
}
|
||
|
: {
|
||
|
inlineStyle: options.inlineStyle ?? true,
|
||
|
inlineTemplate: options.inlineTemplate ?? true,
|
||
|
skipTests: true,
|
||
|
style: options.style,
|
||
|
viewEncapsulation: options.viewEncapsulation,
|
||
|
};
|
||
|
return componentOptions;
|
||
|
}
|