import { cypressInitGenerator } from '@nrwl/cypress'; import { GeneratorCallback, logger, Tree } from '@nrwl/devkit'; import { addDependenciesToPackageJson, formatFiles, readWorkspaceConfiguration, updateJson, updateWorkspaceConfiguration, } from '@nrwl/devkit'; import { jestInitGenerator } from '@nrwl/jest'; import { Linter } from '@nrwl/linter'; import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial'; import { E2eTestRunner, UnitTestRunner } from '../../utils/test-runners'; import { angularVersion, angularDevkitVersion, jestPresetAngularVersion, rxjsVersion, tsNodeVersion, tsLibVersion, zoneJsVersion, protractorVersion, jasmineCoreVersion, jasmineSpecReporterVersion, typesJasmineVersion, typesJasminewd2Version, } from '../../utils/versions'; import { karmaGenerator } from '../karma/karma'; import { Schema } from './schema'; export async function angularInitGenerator( host: Tree, rawOptions: Schema ): Promise { const options = normalizeOptions(rawOptions); setDefaults(host, options); if (!options.skipPostInstall) { addPostInstall(host); } const depsTask = !options.skipPackageJson ? updateDependencies(host) : () => {}; const unitTestTask = addUnitTestRunner(host, options); const e2eTask = addE2ETestRunner(host, options); addGitIgnoreEntry(host, '.angular'); if (!options.skipFormat) { await formatFiles(host); } return runTasksInSerial(depsTask, unitTestTask, e2eTask); } function normalizeOptions(options: Schema): Required { return { e2eTestRunner: options.e2eTestRunner ?? E2eTestRunner.Cypress, linter: options.linter ?? Linter.EsLint, skipFormat: options.skipFormat ?? false, skipInstall: options.skipInstall ?? false, skipPostInstall: options.skipPostInstall ?? false, skipPackageJson: options.skipPackageJson ?? false, style: options.style ?? 'css', unitTestRunner: options.unitTestRunner ?? UnitTestRunner.Jest, }; } function setDefaults(host: Tree, options: Schema) { const workspace = readWorkspaceConfiguration(host); workspace.generators = workspace.generators || {}; workspace.generators['@nrwl/angular:application'] = { style: options.style, linter: options.linter, unitTestRunner: options.unitTestRunner, e2eTestRunner: options.e2eTestRunner, ...(workspace.generators['@nrwl/angular:application'] || {}), }; workspace.generators['@nrwl/angular:library'] = { linter: options.linter, unitTestRunner: options.unitTestRunner, ...(workspace.generators['@nrwl/angular:library'] || {}), }; workspace.generators['@nrwl/angular:component'] = { style: options.style, ...(workspace.generators['@nrwl/angular:component'] || {}), }; updateWorkspaceConfiguration(host, workspace); } function addPostInstall(host: Tree) { updateJson(host, 'package.json', (pkgJson) => { pkgJson.scripts = pkgJson.scripts ?? {}; const command = 'ngcc --properties es2020 browser module main'; if (!pkgJson.scripts.postinstall) { pkgJson.scripts.postinstall = command; } else if (!pkgJson.scripts.postinstall.includes('ngcc')) { pkgJson.scripts.postinstall = `${pkgJson.scripts.postinstall} && ${command}`; } return pkgJson; }); } function updateDependencies(host: Tree): GeneratorCallback { return addDependenciesToPackageJson( host, { '@angular/animations': angularVersion, '@angular/common': angularVersion, '@angular/compiler': angularVersion, '@angular/core': angularVersion, '@angular/forms': angularVersion, '@angular/platform-browser': angularVersion, '@angular/platform-browser-dynamic': angularVersion, '@angular/router': angularVersion, rxjs: rxjsVersion, tslib: tsLibVersion, 'zone.js': zoneJsVersion, }, { '@angular/cli': angularDevkitVersion, '@angular/compiler-cli': angularVersion, '@angular/language-service': angularVersion, '@angular-devkit/build-angular': angularDevkitVersion, } ); } function addUnitTestRunner(host: Tree, options: Schema): GeneratorCallback { switch (options.unitTestRunner) { case UnitTestRunner.Karma: return karmaGenerator(host, { skipPackageJson: options.skipPackageJson }); case UnitTestRunner.Jest: if (!options.skipPackageJson) { addDependenciesToPackageJson( host, {}, { 'jest-preset-angular': jestPresetAngularVersion, } ); } return jestInitGenerator(host, { skipPackageJson: options.skipPackageJson, }); default: return () => {}; } } function addE2ETestRunner(host: Tree, options: Schema): GeneratorCallback { switch (options.e2eTestRunner) { case E2eTestRunner.Protractor: return !options.skipPackageJson ? addDependenciesToPackageJson( host, {}, { protractor: protractorVersion, 'jasmine-core': jasmineCoreVersion, 'jasmine-spec-reporter': jasmineSpecReporterVersion, 'ts-node': tsNodeVersion, '@types/jasmine': typesJasmineVersion, '@types/jasminewd2': typesJasminewd2Version, } ) : () => {}; case E2eTestRunner.Cypress: return cypressInitGenerator(host, { skipPackageJson: options.skipPackageJson, }); default: return () => {}; } } function addGitIgnoreEntry(host: Tree, entry: string) { if (host.exists('.gitignore')) { let content = host.read('.gitignore', 'utf-8'); if (/^\.angular$/gm.test(content)) { return; } content = `${content}\n${entry}\n`; host.write('.gitignore', content); } else { logger.warn(`Couldn't find .gitignore file to update`); } } export default angularInitGenerator;