UNPKG

11.9 kBJavaScriptView Raw
1"use strict";
2/**
3 * @license
4 * Copyright Google LLC All Rights Reserved.
5 *
6 * Use of this source code is governed by an MIT-style license that can be
7 * found in the LICENSE file at https://angular.io/license
8 */
9Object.defineProperty(exports, "__esModule", { value: true });
10const core_1 = require("@angular-devkit/core");
11const schematics_1 = require("@angular-devkit/schematics");
12const tasks_1 = require("@angular-devkit/schematics/tasks");
13const dependencies_1 = require("../utility/dependencies");
14const latest_versions_1 = require("../utility/latest-versions");
15const paths_1 = require("../utility/paths");
16const workspace_1 = require("../utility/workspace");
17const workspace_models_1 = require("../utility/workspace-models");
18const schema_1 = require("./schema");
19function default_1(options) {
20 return async (host, context) => {
21 const { appDir, appRootSelector, componentOptions, folderName, sourceDir } = await getAppOptions(host, options);
22 return (0, schematics_1.chain)([
23 addAppToWorkspaceFile(options, appDir, folderName),
24 options.standalone
25 ? (0, schematics_1.noop)()
26 : (0, schematics_1.schematic)('module', {
27 name: 'app',
28 commonModule: false,
29 flat: true,
30 routing: options.routing,
31 routingScope: 'Root',
32 path: sourceDir,
33 project: options.name,
34 }),
35 (0, schematics_1.schematic)('component', {
36 name: 'app',
37 selector: appRootSelector,
38 flat: true,
39 path: sourceDir,
40 skipImport: true,
41 project: options.name,
42 ...componentOptions,
43 }),
44 (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)(options.standalone ? './files/standalone-files' : './files/module-files'), [
45 options.routing ? (0, schematics_1.noop)() : (0, schematics_1.filter)((path) => !path.endsWith('app.routes.ts.template')),
46 componentOptions.skipTests
47 ? (0, schematics_1.filter)((path) => !path.endsWith('.spec.ts.template'))
48 : (0, schematics_1.noop)(),
49 (0, schematics_1.applyTemplates)({
50 utils: schematics_1.strings,
51 ...options,
52 ...componentOptions,
53 selector: appRootSelector,
54 relativePathToWorkspaceRoot: (0, paths_1.relativePathToWorkspaceRoot)(appDir),
55 appName: options.name,
56 folderName,
57 }),
58 (0, schematics_1.move)(appDir),
59 ]), schematics_1.MergeStrategy.Overwrite),
60 (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)('./files/common-files'), [
61 options.minimal
62 ? (0, schematics_1.filter)((path) => !path.endsWith('tsconfig.spec.json.template'))
63 : (0, schematics_1.noop)(),
64 componentOptions.inlineTemplate
65 ? (0, schematics_1.filter)((path) => !path.endsWith('component.html.template'))
66 : (0, schematics_1.noop)(),
67 (0, schematics_1.applyTemplates)({
68 utils: schematics_1.strings,
69 ...options,
70 selector: appRootSelector,
71 relativePathToWorkspaceRoot: (0, paths_1.relativePathToWorkspaceRoot)(appDir),
72 appName: options.name,
73 folderName,
74 }),
75 (0, schematics_1.move)(appDir),
76 ]), schematics_1.MergeStrategy.Overwrite),
77 options.ssr
78 ? (0, schematics_1.schematic)('ssr', {
79 project: options.name,
80 skipInstall: true,
81 })
82 : (0, schematics_1.noop)(),
83 options.skipPackageJson ? (0, schematics_1.noop)() : addDependenciesToPackageJson(options),
84 ]);
85 };
86}
87exports.default = default_1;
88function addDependenciesToPackageJson(options) {
89 return (host, context) => {
90 [
91 {
92 type: dependencies_1.NodeDependencyType.Dev,
93 name: '@angular/compiler-cli',
94 version: latest_versions_1.latestVersions.Angular,
95 },
96 {
97 type: dependencies_1.NodeDependencyType.Dev,
98 name: '@angular-devkit/build-angular',
99 version: latest_versions_1.latestVersions.DevkitBuildAngular,
100 },
101 {
102 type: dependencies_1.NodeDependencyType.Dev,
103 name: 'typescript',
104 version: latest_versions_1.latestVersions['typescript'],
105 },
106 ].forEach((dependency) => (0, dependencies_1.addPackageJsonDependency)(host, dependency));
107 if (!options.skipInstall) {
108 context.addTask(new tasks_1.NodePackageInstallTask());
109 }
110 return host;
111 };
112}
113function addAppToWorkspaceFile(options, appDir, folderName) {
114 let projectRoot = appDir;
115 if (projectRoot) {
116 projectRoot += '/';
117 }
118 const schematics = {};
119 if (options.inlineTemplate ||
120 options.inlineStyle ||
121 options.minimal ||
122 options.style !== schema_1.Style.Css) {
123 const componentSchematicsOptions = {};
124 if (options.inlineTemplate ?? options.minimal) {
125 componentSchematicsOptions.inlineTemplate = true;
126 }
127 if (options.inlineStyle ?? options.minimal) {
128 componentSchematicsOptions.inlineStyle = true;
129 }
130 if (options.style && options.style !== schema_1.Style.Css) {
131 componentSchematicsOptions.style = options.style;
132 }
133 schematics['@schematics/angular:component'] = componentSchematicsOptions;
134 }
135 if (options.skipTests || options.minimal) {
136 const schematicsWithTests = [
137 'class',
138 'component',
139 'directive',
140 'guard',
141 'interceptor',
142 'pipe',
143 'resolver',
144 'service',
145 ];
146 schematicsWithTests.forEach((type) => {
147 (schematics[`@schematics/angular:${type}`] ??= {}).skipTests = true;
148 });
149 }
150 if (!options.standalone) {
151 const schematicsWithStandalone = ['component', 'directive', 'pipe'];
152 schematicsWithStandalone.forEach((type) => {
153 (schematics[`@schematics/angular:${type}`] ??= {}).standalone = false;
154 });
155 }
156 const sourceRoot = (0, core_1.join)((0, core_1.normalize)(projectRoot), 'src');
157 let budgets = [];
158 if (options.strict) {
159 budgets = [
160 {
161 type: 'initial',
162 maximumWarning: '500kb',
163 maximumError: '1mb',
164 },
165 {
166 type: 'anyComponentStyle',
167 maximumWarning: '2kb',
168 maximumError: '4kb',
169 },
170 ];
171 }
172 else {
173 budgets = [
174 {
175 type: 'initial',
176 maximumWarning: '2mb',
177 maximumError: '5mb',
178 },
179 {
180 type: 'anyComponentStyle',
181 maximumWarning: '6kb',
182 maximumError: '10kb',
183 },
184 ];
185 }
186 const inlineStyleLanguage = options?.style !== schema_1.Style.Css ? options.style : undefined;
187 const project = {
188 root: (0, core_1.normalize)(projectRoot),
189 sourceRoot,
190 projectType: workspace_models_1.ProjectType.Application,
191 prefix: options.prefix || 'app',
192 schematics,
193 targets: {
194 build: {
195 builder: workspace_models_1.Builders.Application,
196 defaultConfiguration: 'production',
197 options: {
198 outputPath: `dist/${folderName}`,
199 index: `${sourceRoot}/index.html`,
200 browser: `${sourceRoot}/main.ts`,
201 polyfills: ['zone.js'],
202 tsConfig: `${projectRoot}tsconfig.app.json`,
203 inlineStyleLanguage,
204 assets: [`${sourceRoot}/favicon.ico`, `${sourceRoot}/assets`],
205 styles: [`${sourceRoot}/styles.${options.style}`],
206 scripts: [],
207 },
208 configurations: {
209 production: {
210 budgets,
211 outputHashing: 'all',
212 },
213 development: {
214 optimization: false,
215 extractLicenses: false,
216 sourceMap: true,
217 },
218 },
219 },
220 serve: {
221 builder: workspace_models_1.Builders.DevServer,
222 defaultConfiguration: 'development',
223 options: {},
224 configurations: {
225 production: {
226 buildTarget: `${options.name}:build:production`,
227 },
228 development: {
229 buildTarget: `${options.name}:build:development`,
230 },
231 },
232 },
233 'extract-i18n': {
234 builder: workspace_models_1.Builders.ExtractI18n,
235 options: {
236 buildTarget: `${options.name}:build`,
237 },
238 },
239 test: options.minimal
240 ? undefined
241 : {
242 builder: workspace_models_1.Builders.Karma,
243 options: {
244 polyfills: ['zone.js', 'zone.js/testing'],
245 tsConfig: `${projectRoot}tsconfig.spec.json`,
246 inlineStyleLanguage,
247 assets: [`${sourceRoot}/favicon.ico`, `${sourceRoot}/assets`],
248 styles: [`${sourceRoot}/styles.${options.style}`],
249 scripts: [],
250 },
251 },
252 },
253 };
254 return (0, workspace_1.updateWorkspace)((workspace) => {
255 workspace.projects.add({
256 name: options.name,
257 ...project,
258 });
259 });
260}
261async function getAppOptions(host, options) {
262 const appRootSelector = `${options.prefix}-root`;
263 const componentOptions = getComponentOptions(options);
264 const workspace = await (0, workspace_1.getWorkspace)(host);
265 const newProjectRoot = workspace.extensions.newProjectRoot || '';
266 // If scoped project (i.e. "@foo/bar"), convert dir to "foo/bar".
267 let folderName = options.name.startsWith('@') ? options.name.slice(1) : options.name;
268 if (/[A-Z]/.test(folderName)) {
269 folderName = schematics_1.strings.dasherize(folderName);
270 }
271 const appDir = options.projectRoot === undefined
272 ? (0, core_1.join)((0, core_1.normalize)(newProjectRoot), folderName)
273 : (0, core_1.normalize)(options.projectRoot);
274 const sourceDir = `${appDir}/src/app`;
275 return {
276 appDir,
277 appRootSelector,
278 componentOptions,
279 folderName,
280 sourceDir,
281 };
282}
283function getComponentOptions(options) {
284 const componentOptions = !options.minimal
285 ? {
286 inlineStyle: options.inlineStyle,
287 inlineTemplate: options.inlineTemplate,
288 skipTests: options.skipTests,
289 style: options.style,
290 viewEncapsulation: options.viewEncapsulation,
291 }
292 : {
293 inlineStyle: options.inlineStyle ?? true,
294 inlineTemplate: options.inlineTemplate ?? true,
295 skipTests: true,
296 style: options.style,
297 viewEncapsulation: options.viewEncapsulation,
298 };
299 return componentOptions;
300}