feat(core): move tsconfig.base.json to @nrwl/js:init (#14467)

This commit is contained in:
Emily Xiong 2023-02-16 11:17:30 -05:00 committed by GitHub
parent f913b905a1
commit a97212b601
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
182 changed files with 1565 additions and 785 deletions

View File

@ -1190,14 +1190,14 @@ Detect workspace scope from the package.json name
### ensurePackage
**ensurePackage**(`tree`, `pkg`, `requiredVersion`, `options?`): `Promise`<`void`\>
**ensurePackage**(`tree`, `pkg`, `requiredVersion`, `options?`): `void`
Ensure that dependencies and devDependencies from package.json are installed at the required versions.
For example:
```typescript
ensurePackage(tree, {}, { '@nrwl/jest': nxVersion });
ensurePackage(tree, '@nrwl/jest', nxVersion);
```
This will check that @nrwl/jest@<nxVersion> exists in devDependencies.
@ -1217,7 +1217,7 @@ When running with --dryRun, the function will throw when dependencies are missin
#### Returns
`Promise`<`void`\>
`void`
---

View File

@ -1088,7 +1088,7 @@
"type": "generator"
},
"/packages/js/generators/init": {
"description": "Init placeholder.",
"description": "Initialize a TS/JS workspace.",
"file": "generated/packages/js/generators/init.json",
"hidden": true,
"name": "init",

View File

@ -1070,7 +1070,7 @@
"type": "generator"
},
{
"description": "Init placeholder.",
"description": "Initialize a TS/JS workspace.",
"file": "generated/packages/js/generators/init.json",
"hidden": true,
"name": "init",

View File

@ -1190,14 +1190,14 @@ Detect workspace scope from the package.json name
### ensurePackage
**ensurePackage**(`tree`, `pkg`, `requiredVersion`, `options?`): `Promise`<`void`\>
**ensurePackage**(`tree`, `pkg`, `requiredVersion`, `options?`): `void`
Ensure that dependencies and devDependencies from package.json are installed at the required versions.
For example:
```typescript
ensurePackage(tree, {}, { '@nrwl/jest': nxVersion });
ensurePackage(tree, '@nrwl/jest', nxVersion);
```
This will check that @nrwl/jest@<nxVersion> exists in devDependencies.
@ -1217,7 +1217,7 @@ When running with --dryRun, the function will throw when dependencies are missin
#### Returns
`Promise`<`void`\>
`void`
---

View File

@ -1190,14 +1190,14 @@ Detect workspace scope from the package.json name
### ensurePackage
**ensurePackage**(`tree`, `pkg`, `requiredVersion`, `options?`): `Promise`<`void`\>
**ensurePackage**(`tree`, `pkg`, `requiredVersion`, `options?`): `void`
Ensure that dependencies and devDependencies from package.json are installed at the required versions.
For example:
```typescript
ensurePackage(tree, {}, { '@nrwl/jest': nxVersion });
ensurePackage(tree, '@nrwl/jest', nxVersion);
```
This will check that @nrwl/jest@<nxVersion> exists in devDependencies.
@ -1217,7 +1217,7 @@ When running with --dryRun, the function will throw when dependencies are missin
#### Returns
`Promise`<`void`\>
`void`
---

View File

@ -28,8 +28,13 @@
},
"skipPackageJson": {
"type": "boolean",
"description": "Do not add dependencies to `package.json`.",
"default": false
"default": false,
"description": "Do not add dependencies to `package.json`."
},
"js": {
"type": "boolean",
"default": false,
"description": "Use JavaScript instead of TypeScript"
}
},
"required": [],

View File

@ -7,11 +7,25 @@
"cli": "nx",
"title": "Init nrwl/js",
"description": "Init generator placeholder for nrwl/js.",
"properties": {
"js": {
"type": "boolean",
"default": false,
"description": "Use JavaScript instead of TypeScript"
},
"skipFormat": {
"type": "boolean",
"aliases": ["skip-format"],
"description": "Skip formatting files.",
"default": true,
"x-priority": "internal"
}
},
"presets": []
},
"aliases": ["lib"],
"x-type": "init",
"description": "Init placeholder.",
"description": "Initialize a TS/JS workspace.",
"hidden": true,
"implementation": "/packages/js/src/generators/init/init#initGenerator.ts",
"path": "/packages/js/src/generators/init/schema.json",

View File

@ -76,12 +76,6 @@
"default": false,
"x-priority": "internal"
},
"skipWorkspaceJson": {
"description": "Skip updating `workspace.json` with default options based on values provided to this app (e.g. `babel`, `style`).",
"type": "boolean",
"default": false,
"x-priority": "internal"
},
"unitTestRunner": {
"type": "string",
"enum": ["jest", "none"],

View File

@ -52,6 +52,11 @@
"type": "boolean",
"default": false,
"hidden": true
},
"js": {
"type": "boolean",
"description": "Generate JavaScript story files rather than TypeScript story files.",
"default": false
}
},
"presets": []

View File

@ -35,7 +35,8 @@
"skipPackageJson": {
"description": "Do not add dependencies to `package.json`.",
"type": "boolean",
"default": false
"default": false,
"x-priority": "internal"
},
"skipBabelConfig": {
"description": "Do not generate a root babel.config.json (if babel is not needed).",

View File

@ -0,0 +1,228 @@
import {
checkFilesExist,
cleanupProject,
packageInstall,
readJson,
runCLI,
runCreateWorkspace,
uniq,
} from '@nrwl/e2e/utils';
describe('create-nx-workspace --preset=npm', () => {
let wsName;
beforeEach(() => {
wsName = uniq('npm');
runCreateWorkspace(wsName, {
preset: 'npm',
});
});
afterEach(() => cleanupProject());
it('should add angular application', () => {
packageInstall('@nrwl/angular', wsName);
const appName = uniq('my-app');
expect(() => {
runCLI(`generate @nrwl/angular:app ${appName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
}, 1_000_000);
it('should add angular library', () => {
packageInstall('@nrwl/angular', wsName);
const libName = uniq('lib');
expect(() => {
runCLI(`generate @nrwl/angular:lib ${libName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
const tsconfig = readJson(`tsconfig.base.json`);
expect(tsconfig.compilerOptions.paths).toEqual({
[libName]: [`packages/${libName}/src/index.ts`],
});
}, 1_000_000);
it('should add workspace library', () => {
packageInstall('@nrwl/workspace', wsName);
const libName = uniq('lib');
expect(() =>
runCLI(`generate @nrwl/workspace:library ${libName} --no-interactive`)
).not.toThrowError();
checkFilesExist('tsconfig.base.json');
const tsconfig = readJson(`tsconfig.base.json`);
expect(tsconfig.compilerOptions.paths).toEqual({
[libName]: [`packages/${libName}/src/index.ts`],
});
});
it('should add js library', () => {
packageInstall('@nrwl/js', wsName);
const libName = uniq('lib');
expect(() =>
runCLI(`generate @nrwl/js:library ${libName} --no-interactive`)
).not.toThrowError();
checkFilesExist('tsconfig.base.json');
const tsconfig = readJson(`tsconfig.base.json`);
expect(tsconfig.compilerOptions.paths).toEqual({
[libName]: [`packages/${libName}/src/index.ts`],
});
});
it('should add web application', () => {
packageInstall('@nrwl/web', wsName);
const appName = uniq('my-app');
expect(() =>
runCLI(`generate @nrwl/web:app ${appName} --no-interactive`)
).not.toThrowError();
checkFilesExist('tsconfig.base.json');
});
it('should add react application', () => {
packageInstall('@nrwl/react', wsName);
const appName = uniq('my-app');
expect(() => {
runCLI(`generate @nrwl/react:app ${appName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
});
it('should add react library', () => {
packageInstall('@nrwl/react', wsName);
const libName = uniq('lib');
expect(() => {
runCLI(`generate @nrwl/react:lib ${libName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
const tsconfig = readJson(`tsconfig.base.json`);
expect(tsconfig.compilerOptions.paths).toEqual({
[libName]: [`packages/${libName}/src/index.ts`],
});
});
it('should add next application', () => {
packageInstall('@nrwl/next', wsName);
const appName = uniq('my-app');
expect(() => {
runCLI(`generate @nrwl/next:app ${appName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
});
it('should add next library', () => {
packageInstall('@nrwl/next', wsName);
const libName = uniq('lib');
expect(() => {
runCLI(`generate @nrwl/next:lib ${libName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
const tsconfig = readJson(`tsconfig.base.json`);
expect(tsconfig.compilerOptions.paths).toEqual({
[libName]: [`packages/${libName}/src/index.ts`],
});
});
it('should add react-native application', () => {
packageInstall('@nrwl/react-native', wsName);
const appName = uniq('my-app');
expect(() => {
runCLI(`generate @nrwl/react-native:app ${appName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
});
it('should add react-native library', () => {
packageInstall('@nrwl/react-native', wsName);
const libName = uniq('lib');
expect(() => {
runCLI(`generate @nrwl/react-native:lib ${libName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
const tsconfig = readJson(`tsconfig.base.json`);
expect(tsconfig.compilerOptions.paths).toEqual({
[libName]: [`packages/${libName}/src/index.ts`],
});
});
it('should add node application', () => {
packageInstall('@nrwl/node', wsName);
const appName = uniq('my-app');
expect(() => {
runCLI(`generate @nrwl/node:app ${appName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
});
it('should add node library', () => {
packageInstall('@nrwl/node', wsName);
const libName = uniq('lib');
expect(() => {
runCLI(`generate @nrwl/node:lib ${libName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
const tsconfig = readJson(`tsconfig.base.json`);
expect(tsconfig.compilerOptions.paths).toEqual({
[libName]: [`packages/${libName}/src/index.ts`],
});
});
it('should add nest application', () => {
packageInstall('@nrwl/nest', wsName);
const appName = uniq('my-app');
expect(() => {
runCLI(`generate @nrwl/nest:app ${appName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
});
it('should add nest library', () => {
packageInstall('@nrwl/nest', wsName);
const libName = uniq('lib');
expect(() => {
runCLI(`generate @nrwl/nest:lib ${libName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
const tsconfig = readJson(`tsconfig.base.json`);
expect(tsconfig.compilerOptions.paths).toEqual({
[libName]: [`packages/${libName}/src/index.ts`],
});
});
it('should add express application', () => {
packageInstall('@nrwl/express', wsName);
const appName = uniq('my-app');
expect(() => {
runCLI(`generate @nrwl/express:app ${appName} --no-interactive`);
}).not.toThrowError();
checkFilesExist('tsconfig.base.json');
});
});

View File

@ -129,6 +129,7 @@ describe('create-nx-workspace', () => {
});
expectNoAngularDevkit();
checkFilesDoNotExist('tsconfig.base.json');
});
it('should be able to create an empty workspace with ts/js capabilities', () => {

View File

@ -39,6 +39,7 @@
"@nrwl/cypress": "file:../cypress",
"@nrwl/devkit": "file:../devkit",
"@nrwl/jest": "file:../jest",
"@nrwl/js": "file:../js",
"@nrwl/linter": "file:../linter",
"@nrwl/webpack": "file:../webpack",
"@nrwl/workspace": "file:../workspace",

View File

@ -1,7 +1,6 @@
import type { Tree } from '@nrwl/devkit';
import { joinPathFragments } from '@nrwl/devkit';
import type { NormalizedSchema } from './normalized-schema';
import { tsquery } from '@phenomnomnominal/tsquery';
export function convertToStandaloneApp(tree: Tree, options: NormalizedSchema) {
const pathToAppModule = joinPathFragments(
@ -24,6 +23,7 @@ function updateMainEntrypoint(
) {
let routerModuleSetup: string;
if (options.routing) {
const { tsquery } = require('@phenomnomnominal/tsquery');
const appModuleContents = tree.read(pathToAppModule, 'utf-8');
const ast = tsquery.ast(appModuleContents);
@ -73,6 +73,7 @@ function updateAppComponent(tree: Tree, options: NormalizedSchema) {
);
const appComponentContents = tree.read(pathToAppComponent, 'utf-8');
const { tsquery } = require('@phenomnomnominal/tsquery');
const ast = tsquery.ast(appComponentContents);
const COMPONENT_DECORATOR_SELECTOR =
'Decorator > CallExpression:has(Identifier[name=Component]) ObjectLiteralExpression';

View File

@ -1,6 +1,5 @@
import type { Tree } from '@nrwl/devkit';
import { generateFiles, joinPathFragments } from '@nrwl/devkit';
import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript';
import type { NormalizedSchema } from './normalized-schema';
export function createFiles(tree: Tree, options: NormalizedSchema) {

View File

@ -1,22 +1,26 @@
import type { Tree } from '@nrwl/devkit';
import type { NormalizedSchema } from './normalized-schema';
import * as ts from 'typescript';
import { insertImport } from '@nrwl/workspace/src/utilities/ast-utils';
import {
addImportToTestBed,
replaceIntoToTestBed,
} from '../../../../utils/nx-devkit/ast-utils';
let tsModule: typeof import('typescript');
export function updateComponentSpec(host: Tree, options: NormalizedSchema) {
if (!tsModule) {
tsModule = require('typescript');
}
if (options.skipTests !== true) {
const componentSpecPath = `${options.appProjectRoot}/src/app/app.component.spec.ts`;
const componentSpecSource = host.read(componentSpecPath, 'utf-8');
let componentSpecSourceFile = ts.createSourceFile(
let componentSpecSourceFile = tsModule.createSourceFile(
componentSpecPath,
componentSpecSource,
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);

View File

@ -9,13 +9,13 @@ import {
updateJson,
} from '@nrwl/devkit';
import { replaceAppNameWithPath } from '@nrwl/workspace/src/utils/cli-config-utils';
import { getRelativePathToRootTsConfig } from '@nrwl/js';
import { E2eTestRunner, UnitTestRunner } from '../../../../utils/test-runners';
import type { NormalizedSchema } from './normalized-schema';
import {
createTsConfig,
extractTsConfigBase,
} from '../../../utils/create-ts-config';
import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript';
export function updateConfigFiles(host: Tree, options: NormalizedSchema) {
if (!options.rootProject) {

View File

@ -6,7 +6,7 @@ import {
updateJson,
updateProjectConfiguration,
} from '@nrwl/devkit';
import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript';
import { getRelativePathToRootTsConfig } from '@nrwl/js';
import type { NormalizedSchema } from './normalized-schema';
export function updateE2eProject(tree: Tree, options: NormalizedSchema) {

View File

@ -1,5 +1,6 @@
import {
formatFiles,
GeneratorCallback,
installPackagesTask,
moveFilesToNewDirectory,
readNxJson,
@ -38,7 +39,7 @@ import { lt } from 'semver';
export async function applicationGenerator(
tree: Tree,
schema: Partial<Schema>
) {
): Promise<GeneratorCallback> {
const installedAngularVersionInfo = getInstalledAngularVersionInfo(tree);
if (lt(installedAngularVersionInfo.version, '14.1.0') && schema.standalone) {

View File

@ -1,7 +1,6 @@
import type { Tree } from '@nrwl/devkit';
import { joinPathFragments } from '@nrwl/devkit';
import type { NormalizedSchema } from './normalized-schema';
import { tsquery } from '@phenomnomnominal/tsquery';
export function convertToStandaloneApp(tree: Tree, options: NormalizedSchema) {
const pathToAppModule = joinPathFragments(
@ -22,6 +21,7 @@ function updateMainEntrypoint(
tree: Tree,
pathToAppModule: string
) {
const { tsquery } = require('@phenomnomnominal/tsquery');
let routerModuleSetup: string;
if (options.routing) {
const appModuleContents = tree.read(pathToAppModule, 'utf-8');
@ -63,6 +63,7 @@ bootstrapApplication(AppComponent${
}).catch((err) => console.error(err));`;
function updateAppComponent(tree: Tree, options: NormalizedSchema) {
const { tsquery } = require('@phenomnomnominal/tsquery');
const pathToAppComponent = joinPathFragments(
options.appProjectRoot,
'src/app/app.component.ts'

View File

@ -1,6 +1,6 @@
import type { Tree } from '@nrwl/devkit';
import { generateFiles, joinPathFragments } from '@nrwl/devkit';
import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript';
import { getRelativePathToRootTsConfig } from '@nrwl/js';
import type { NormalizedSchema } from './normalized-schema';
export function createFiles(tree: Tree, options: NormalizedSchema) {

View File

@ -2,9 +2,10 @@ import type { Tree } from '@nrwl/devkit';
import type { NormalizedSchema } from './normalized-schema';
import { insertImport } from '@nrwl/workspace/src/utilities/ast-utils';
import * as ts from 'typescript';
import { addImportToModule } from '../../../utils/nx-devkit/ast-utils';
let tsModule: typeof import('typescript');
export function addRouterRootConfiguration(
host: Tree,
options: NormalizedSchema
@ -12,10 +13,13 @@ export function addRouterRootConfiguration(
const modulePath = `${options.appProjectRoot}/src/app/app.module.ts`;
const moduleSource = host.read(modulePath, 'utf-8');
let sourceFile = ts.createSourceFile(
if (!tsModule) {
tsModule = require('typescript');
}
let sourceFile = tsModule.createSourceFile(
modulePath,
moduleSource,
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);

View File

@ -1,16 +1,21 @@
import type { Tree } from '@nrwl/devkit';
import type { NormalizedSchema } from './normalized-schema';
import * as ts from 'typescript';
import { replaceNodeValue } from '@nrwl/workspace/src/utilities/ast-utils';
import { getDecoratorPropertyValueNode } from '../../../utils/nx-devkit/ast-utils';
import { nrwlHomeTemplate } from './nrwl-home-tpl';
export function updateAppComponentTemplate(
let tsModule: typeof import('typescript');
export async function updateAppComponentTemplate(
host: Tree,
options: NormalizedSchema
) {
if (!tsModule) {
tsModule = require('typescript');
}
const content = options.routing
? `${nrwlHomeTemplate.getSelector(
options.prefix
@ -35,10 +40,10 @@ export function updateAppComponentTemplate(
replaceNodeValue(
host,
ts.createSourceFile(
tsModule.createSourceFile(
componentPath,
host.read(componentPath, 'utf-8'),
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
),
componentPath,

View File

@ -1,22 +1,26 @@
import type { Tree } from '@nrwl/devkit';
import type { NormalizedSchema } from './normalized-schema';
import * as ts from 'typescript';
import { insertImport } from '@nrwl/workspace/src/utilities/ast-utils';
import {
addImportToTestBed,
replaceIntoToTestBed,
} from '../../../utils/nx-devkit/ast-utils';
import type { NormalizedSchema } from './normalized-schema';
let tsModule: typeof import('typescript');
export function updateComponentSpec(host: Tree, options: NormalizedSchema) {
if (!tsModule) {
tsModule = require('typescript');
}
if (options.skipTests !== true) {
const componentSpecPath = `${options.appProjectRoot}/src/app/app.component.spec.ts`;
const componentSpecSource = host.read(componentSpecPath, 'utf-8');
let componentSpecSourceFile = ts.createSourceFile(
let componentSpecSourceFile = tsModule.createSourceFile(
componentSpecPath,
componentSpecSource,
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);

View File

@ -9,10 +9,10 @@ import {
updateJson,
} from '@nrwl/devkit';
import { replaceAppNameWithPath } from '@nrwl/workspace/src/utils/cli-config-utils';
import { getRelativePathToRootTsConfig } from '@nrwl/js';
import { E2eTestRunner, UnitTestRunner } from '../../../utils/test-runners';
import type { NormalizedSchema } from './normalized-schema';
import { createTsConfig } from '../../utils/create-ts-config';
import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript';
export function updateConfigFiles(host: Tree, options: NormalizedSchema) {
updateTsConfigOptions(host, options);

View File

@ -6,7 +6,7 @@ import {
updateJson,
updateProjectConfiguration,
} from '@nrwl/devkit';
import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript';
import { getRelativePathToRootTsConfig } from '@nrwl/js';
import type { NormalizedSchema } from './normalized-schema';
export function updateE2eProject(tree: Tree, options: NormalizedSchema) {

View File

@ -1,7 +1,6 @@
import type { Tree } from '@nrwl/devkit';
import type { NormalizedSchema } from './normalized-schema';
import * as ts from 'typescript';
import {
addGlobal,
replaceNodeValue,
@ -9,10 +8,16 @@ import {
import { getDecoratorPropertyValueNode } from '../../../utils/nx-devkit/ast-utils';
import { nrwlHomeTemplate } from './nrwl-home-tpl';
let tsModule: typeof import('typescript');
export function updateNxComponentTemplate(
host: Tree,
options: NormalizedSchema
) {
if (!tsModule) {
tsModule = require('typescript');
}
const componentPath = `${options.appProjectRoot}/src/app/nx-welcome.component.ts`;
const templateNodeValue = getDecoratorPropertyValueNode(
host,
@ -24,10 +29,10 @@ export function updateNxComponentTemplate(
replaceNodeValue(
host,
ts.createSourceFile(
tsModule.createSourceFile(
componentPath,
host.read(componentPath, 'utf-8'),
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
),
componentPath,
@ -36,10 +41,10 @@ export function updateNxComponentTemplate(
);
// Fixing extra comma issue `,,`
let sourceFile = ts.createSourceFile(
let sourceFile = tsModule.createSourceFile(
componentPath,
host.read(componentPath, 'utf-8'),
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);
const componentFile = host
@ -56,10 +61,10 @@ export function updateNxComponentTemplate(
});
// Add ESLint ignore to pass the lint step
sourceFile = ts.createSourceFile(
sourceFile = tsModule.createSourceFile(
componentPath,
host.read(componentPath, 'utf-8'),
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);
addGlobal(host, sourceFile, componentPath, '/* eslint-disable */');

View File

@ -8,7 +8,7 @@ export async function angularChangeStorybookTargestGenerator(
tree: Tree,
schema: Schema
) {
await ensurePackage(tree, '@nrwl/storybook', nxVersion);
ensurePackage(tree, '@nrwl/storybook', nxVersion);
const { changeStorybookTargetsGenerator } = await import('@nrwl/storybook');
await changeStorybookTargetsGenerator(tree);

View File

@ -1,5 +1,4 @@
import type { Tree } from '@nrwl/devkit';
import { tsquery } from '@phenomnomnominal/tsquery';
import type { StringLiteral } from 'typescript';
import { getRelativeImportToFile } from '../../utils/path';
@ -12,6 +11,7 @@ export function shouldExportInEntryPoint(
return false;
}
const { tsquery } = require('@phenomnomnominal/tsquery');
const moduleImportPath = getRelativeImportToFile(entryPoint, modulePath);
const entryPointContent = tree.read(entryPoint, 'utf-8');
const entryPointAst = tsquery.ast(entryPointContent);

View File

@ -1,10 +1,10 @@
import type { SourceFile } from 'typescript';
import { tsquery } from '@phenomnomnominal/tsquery';
export function checkOutputNameMatchesProjectName(
ast: SourceFile,
projectName: string
) {
const { tsquery } = require('@phenomnomnominal/tsquery');
const OUTPUT_SELECTOR =
'PropertyAssignment:has(Identifier[name=output]) > ObjectLiteralExpression:has(PropertyAssignment:has(Identifier[name=uniqueName]))';
const UNIQUENAME_SELECTOR =

View File

@ -1,7 +1,7 @@
import type { SourceFile, Node } from 'typescript';
import { tsquery } from '@phenomnomnominal/tsquery';
export function checkSharedNpmPackagesMatchExpected(ast: SourceFile) {
const { tsquery } = require('@phenomnomnominal/tsquery');
const SHARE_HELPER_SELECTOR =
'PropertyAssignment:has(Identifier[name=shared]) > CallExpression:has(Identifier[name=share])';
const SHARED_PACKAGE_CONFIG_SELECTOR =

View File

@ -1,5 +1,4 @@
import type { SourceFile } from 'typescript';
import { tsquery } from '@phenomnomnominal/tsquery';
export type IsHostRemoteConfigResult = 'host' | 'remote' | 'both' | false;
@ -12,6 +11,7 @@ const PROPERTY_SELECTOR = 'ObjectLiteralExpression > PropertyAssignment';
export function isHostRemoteConfig(ast: SourceFile): IsHostRemoteConfigResult {
let isHost = false;
let isRemote = false;
const { tsquery } = require('@phenomnomnominal/tsquery');
const remotesNodes = tsquery(ast, REMOTES_EXPRESSION_SELECTOR, {
visitAllChildren: true,
@ -33,6 +33,7 @@ export function isHostRemoteConfig(ast: SourceFile): IsHostRemoteConfigResult {
}
export function getRemotesFromHost(ast: SourceFile) {
const { tsquery } = require('@phenomnomnominal/tsquery');
const remotesObjectNodes = tsquery(ast, REMOTES_EXPRESSION_SELECTOR, {
visitAllChildren: true,
});
@ -62,6 +63,7 @@ export function getRemotesFromHost(ast: SourceFile) {
}
export function getExposedModulesFromRemote(ast: SourceFile) {
const { tsquery } = require('@phenomnomnominal/tsquery');
const exposesObjectNodes = tsquery(ast, EXPOSES_EXPRESSION_SELECTOR, {
visitAllChildren: true,
});

View File

@ -1,5 +1,4 @@
import type { Tree } from '@nrwl/devkit';
import { tsquery } from '@phenomnomnominal/tsquery';
export function parseASTOfWebpackConfig(
tree: Tree,
@ -10,6 +9,7 @@ export function parseASTOfWebpackConfig(
`Cannot migrate webpack config at \`${pathToWebpackConfig}\` as it does not exist. Please ensure this file exists and that the path to the file is correct.`
);
}
const { tsquery } = require('@phenomnomnominal/tsquery');
const source = tree.read(pathToWebpackConfig, 'utf-8');
return tsquery.ast(source);

View File

@ -10,6 +10,7 @@ import {
} from '@nrwl/devkit';
import { jestInitGenerator } from '@nrwl/jest';
import { Linter } from '@nrwl/linter';
import { initGenerator as jsInitGenerator } from '@nrwl/js';
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
import { backwardCompatibleVersions } from '../../../utils/backward-compatible-versions';
import { E2eTestRunner, UnitTestRunner } from '../../../utils/test-runners';
@ -26,6 +27,12 @@ export async function angularInitGenerator(
): Promise<GeneratorCallback> {
const options = normalizeOptions(rawOptions);
setDefaults(host, options);
await jsInitGenerator(host, {
js: false,
skipFormat: true,
});
const tasks: GeneratorCallback[] = [];
const peerDepsToInstall = [
'@angular-devkit/core',
@ -44,18 +51,22 @@ export async function angularInitGenerator(
}
});
const depsTask = !options.skipPackageJson
? updateDependencies(host)
: () => {};
if (!options.skipPackageJson) {
tasks.push(updateDependencies(host));
}
const unitTestTask = await addUnitTestRunner(host, options);
tasks.push(unitTestTask);
const e2eTask = addE2ETestRunner(host, options);
tasks.push(e2eTask);
addGitIgnoreEntry(host, '.angular');
if (!options.skipFormat) {
await formatFiles(host);
}
return runTasksInSerial(depsTask, unitTestTask, e2eTask);
return runTasksInSerial(...tasks);
}
function normalizeOptions(options: Schema): Required<Schema> {

View File

@ -10,6 +10,7 @@ import {
} from '@nrwl/devkit';
import { jestInitGenerator } from '@nrwl/jest';
import { Linter } from '@nrwl/linter';
import { initGenerator as jsInitGenerator } from '@nrwl/js';
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
import { join } from 'path';
import { E2eTestRunner, UnitTestRunner } from '../../utils/test-runners';
@ -68,19 +69,28 @@ export async function angularInitGenerator(
const options = normalizeOptions(rawOptions);
setDefaults(tree, options);
await jsInitGenerator(tree, {
js: false,
skipFormat: true,
});
const depsTask = !options.skipPackageJson
? updateDependencies(tree)
: () => {};
const tasks: GeneratorCallback[] = [];
if (!options.skipPackageJson) {
tasks.push(updateDependencies(tree));
}
const unitTestTask = await addUnitTestRunner(tree, options);
tasks.push(unitTestTask);
const e2eTask = addE2ETestRunner(tree, options);
tasks.push(e2eTask);
addGitIgnoreEntry(tree, '.angular');
if (!options.skipFormat) {
await formatFiles(tree);
}
return runTasksInSerial(depsTask, unitTestTask, e2eTask);
return runTasksInSerial(...tasks);
}
function normalizeOptions(options: Schema): Required<Schema> {

View File

@ -6,7 +6,6 @@ import {
offsetFromRoot,
readProjectConfiguration,
} from '@nrwl/devkit';
import { tsquery } from '@phenomnomnominal/tsquery';
import { getInstalledAngularVersionInfo } from '../../utils/version-utils';
import { v14TestFile } from './v14-test-file';
@ -76,6 +75,7 @@ function isUsingConfigSetInBaseKarmaConfig(tree: Tree) {
if (!tree.exists('karma.conf.js')) {
return false;
}
const { tsquery } = require('@phenomnomnominal/tsquery');
const CONFIG_SET_SELECTOR =
'PropertyAccessExpression:has(Identifier[name=config], Identifier[name=set])';

View File

@ -1,5 +1,5 @@
import { Tree, updateJson } from '@nrwl/devkit';
import { getRootTsConfigPathInTree } from '@nrwl/workspace/src/utilities/typescript';
import { getRootTsConfigPathInTree } from '@nrwl/js';
import { NormalizedGeneratorOptions } from '../schema';
export function addPathMapping(

View File

@ -1,10 +1,11 @@
import { names, Tree } from '@nrwl/devkit';
import { insertImport } from '@nrwl/workspace/src/utilities/ast-utils';
import * as ts from 'typescript';
import { addImportToModule } from '../../../utils/nx-devkit/ast-utils';
import { NormalizedSchema } from './normalized-schema';
import { addRoute } from '../../../utils/nx-devkit/route-utils';
let tsModule: typeof import('typescript');
export function addChildren(
tree: Tree,
options: NormalizedSchema['libraryOptions']
@ -12,16 +13,19 @@ export function addChildren(
if (!tree.exists(options.parent)) {
throw new Error(`Cannot find '${options.parent}'`);
}
if (!tsModule) {
tsModule = require('typescript');
}
const routeFileSource = tree.read(options.parent, 'utf-8');
const constName = options.standalone
? `${names(options.name).propertyName}Routes`
: `${names(options.fileName).propertyName}Routes`;
const importPath = options.importPath;
let sourceFile = ts.createSourceFile(
let sourceFile = tsModule.createSourceFile(
options.parent,
routeFileSource,
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);

View File

@ -1,14 +1,18 @@
import { joinPathFragments, names, Tree } from '@nrwl/devkit';
import { insertImport } from '@nrwl/workspace/src/utilities/ast-utils';
import * as ts from 'typescript';
import { addImportToModule } from '../../../utils/nx-devkit/ast-utils';
import { NormalizedSchema } from './normalized-schema';
import { dirname } from 'path';
let tsModule: typeof import('typescript');
export function addLazyLoadedRouterConfiguration(
tree: Tree,
options: NormalizedSchema['libraryOptions']
) {
if (!tsModule) {
tsModule = require('typescript');
}
const constName = `${names(options.fileName).propertyName}Routes`;
tree.write(
joinPathFragments(dirname(options.modulePath), 'lib.routes.ts'),
@ -18,10 +22,10 @@ export const ${constName}: Route[] = [/* {path: '', pathMatch: 'full', component
);
const routeFileSource = tree.read(options.modulePath, 'utf-8');
let sourceFile = ts.createSourceFile(
let sourceFile = tsModule.createSourceFile(
options.modulePath,
routeFileSource,
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);
sourceFile = addImportToModule(

View File

@ -1,8 +1,9 @@
import { names, Tree } from '@nrwl/devkit';
import * as ts from 'typescript';
import { NormalizedSchema } from './normalized-schema';
import { addRoute } from '../../../utils/nx-devkit/route-utils';
let tsModule: typeof import('typescript');
export function addLoadChildren(
tree: Tree,
options: NormalizedSchema['libraryOptions']
@ -10,12 +11,15 @@ export function addLoadChildren(
if (!tree.exists(options.parent)) {
throw new Error(`Cannot find '${options.parent}'`);
}
if (!tsModule) {
tsModule = require('typescript');
}
const moduleSource = tree.read(options.parent, 'utf-8');
const sourceFile = ts.createSourceFile(
const sourceFile = tsModule.createSourceFile(
options.parent,
moduleSource,
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);

View File

@ -1,21 +1,25 @@
import type { Tree } from '@nrwl/devkit';
import { joinPathFragments, names } from '@nrwl/devkit';
import { insertImport } from '@nrwl/workspace/src/utilities/ast-utils';
import * as ts from 'typescript';
import { addImportToModule } from '../../../utils/nx-devkit/ast-utils';
import { NormalizedSchema } from './normalized-schema';
import { dirname } from 'path';
let tsModule: typeof import('typescript');
export function addRouterConfiguration(
tree: Tree,
options: NormalizedSchema['libraryOptions']
) {
if (!tsModule) {
tsModule = require('typescript');
}
const constName = `${names(options.fileName).propertyName}Routes`;
const moduleSource = tree.read(options.modulePath, 'utf-8');
let moduleSourceFile = ts.createSourceFile(
let moduleSourceFile = tsModule.createSourceFile(
options.modulePath,
moduleSource,
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);

View File

@ -8,7 +8,7 @@ import {
Tree,
updateJson,
} from '@nrwl/devkit';
import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript';
import { getRelativePathToRootTsConfig } from '@nrwl/js';
import { replaceAppNameWithPath } from '@nrwl/workspace/src/utils/cli-config-utils';
import { NormalizedSchema } from './normalized-schema';
import { updateNgPackage } from './update-ng-package';

View File

@ -1,38 +1,12 @@
import type { Tree } from '@nrwl/devkit';
import { joinPathFragments, updateJson } from '@nrwl/devkit';
import {
getRelativePathToRootTsConfig,
getRootTsConfigPathInTree,
} from '@nrwl/workspace/src/utilities/typescript';
import { updateJson } from '@nrwl/devkit';
import { getRelativePathToRootTsConfig } from '@nrwl/js';
import { NormalizedSchema } from './normalized-schema';
import {
createTsConfig,
extractTsConfigBase,
} from '../../utils/create-ts-config';
function updateRootConfig(
host: Tree,
options: NormalizedSchema['libraryOptions']
) {
updateJson(host, getRootTsConfigPathInTree(host), (json) => {
const c = json.compilerOptions;
c.paths = c.paths || {};
delete c.paths[options.name];
if (c.paths[options.importPath]) {
throw new Error(
`You already have a library using the import path "${options.importPath}". Make sure to specify a unique one.`
);
}
c.paths[options.importPath] = [
joinPathFragments(options.projectRoot, '/src/index.ts'),
];
return json;
});
}
function updateProjectConfig(
host: Tree,
options: NormalizedSchema['libraryOptions']
@ -82,7 +56,6 @@ export function updateTsConfig(
options: NormalizedSchema['libraryOptions']
) {
extractTsConfigBase(host);
updateRootConfig(host, options);
updateProjectConfig(host, options);
updateProjectIvyConfig(host, options);
}

View File

@ -1,6 +1,7 @@
import {
addDependenciesToPackageJson,
formatFiles,
GeneratorCallback,
installPackagesTask,
moveFilesToNewDirectory,
removeDependenciesFromPackageJson,
@ -8,6 +9,7 @@ import {
} from '@nrwl/devkit';
import { jestProjectGenerator } from '@nrwl/jest';
import { Linter } from '@nrwl/linter';
import { updateRootTsConfig } from '@nrwl/js';
import { lt } from 'semver';
import init from '../../generators/init/init';
import { E2eTestRunner } from '../../utils/test-runners';
@ -30,7 +32,10 @@ import { updateProject } from './lib/update-project';
import { updateTsConfig } from './lib/update-tsconfig';
import { Schema } from './schema';
export async function libraryGenerator(tree: Tree, schema: Schema) {
export async function libraryGenerator(
tree: Tree,
schema: Schema
): Promise<GeneratorCallback> {
// Do some validation checks
if (!schema.routing && schema.lazy) {
throw new Error(`To use "--lazy" option, "--routing" must also be set.`);
@ -56,7 +61,7 @@ export async function libraryGenerator(tree: Tree, schema: Schema) {
}
const options = normalizeOptions(tree, schema);
const { libraryOptions, componentOptions } = options;
const { libraryOptions } = options;
await init(tree, {
...libraryOptions,
@ -86,6 +91,8 @@ export async function libraryGenerator(tree: Tree, schema: Schema) {
libraryOptions.projectRoot
);
}
const { updateProject } = await import('./lib/update-project');
await updateProject(tree, libraryOptions);
updateTsConfig(tree, libraryOptions);
await addUnitTestRunner(tree, libraryOptions);
@ -122,6 +129,8 @@ export async function libraryGenerator(tree: Tree, schema: Schema) {
addBuildableLibrariesPostCssDependencies(tree);
}
updateRootTsConfig(tree, { ...libraryOptions, js: false });
if (!libraryOptions.skipFormat) {
await formatFiles(tree);
}

View File

@ -8,7 +8,7 @@ import {
offsetFromRoot,
updateProjectConfiguration,
} from '@nrwl/devkit';
import { getRootTsConfigPathInTree } from '@nrwl/workspace/src/utilities/typescript';
import { getRootTsConfigPathInTree } from '@nrwl/js';
import { basename } from 'path';
import type { Logger, ProjectMigrationInfo } from '../../utilities';
import { BuilderMigrator } from './builder.migrator';

View File

@ -9,7 +9,7 @@ import {
updateJson,
updateProjectConfiguration,
} from '@nrwl/devkit';
import { getRootTsConfigPathInTree } from '@nrwl/workspace/src/utilities/typescript';
import { getRootTsConfigPathInTree } from '@nrwl/js';
import { basename } from 'path';
import { addBuildableLibrariesPostCssDependencies } from '../../../utils/dependencies';
import type { Logger, ProjectMigrationInfo } from '../../utilities';

View File

@ -5,7 +5,7 @@ import {
updateJson,
updateProjectConfiguration,
} from '@nrwl/devkit';
import { getRootTsConfigPathInTree } from '@nrwl/workspace/src/utilities/typescript';
import { getRootTsConfigPathInTree } from '@nrwl/js';
import { basename } from 'path';
import type { GeneratorOptions } from '../../schema';
import type {

View File

@ -22,8 +22,7 @@ import {
} from '@nrwl/devkit';
import { Linter, lintProjectGenerator } from '@nrwl/linter';
import { insertImport } from '@nrwl/workspace/src/utilities/ast-utils';
import { getRootTsConfigPathInTree } from '@nrwl/workspace/src/utilities/typescript';
import { tsquery } from '@phenomnomnominal/tsquery';
import { getRootTsConfigPathInTree } from '@nrwl/js';
import { basename, relative } from 'path';
import type {
Node,
@ -578,6 +577,7 @@ export class E2eMigrator extends ProjectMigrator<SupportedTargets> {
}
private updateCypress10ConfigFile(configFilePath: string): void {
const { tsquery } = require('@phenomnomnominal/tsquery');
this.cypressPreset = nxE2EPreset(configFilePath);
const fileContent = this.tree.read(configFilePath, 'utf-8');
@ -657,6 +657,7 @@ export class E2eMigrator extends ProjectMigrator<SupportedTargets> {
recorder: FileChangeRecorder,
{ ...globalConfig }: CypressCommonConfig
): void {
const { tsquery } = require('@phenomnomnominal/tsquery');
const e2eConfig = {};
const presetSpreadAssignment = `...nxE2EPreset(__dirname),`;
if (!e2eNode) {

View File

@ -13,7 +13,7 @@ import { Linter, lintInitGenerator } from '@nrwl/linter';
import { DEFAULT_NRWL_PRETTIER_CONFIG } from '@nrwl/workspace/src/generators/new/generate-workspace-files';
import { deduceDefaultBase } from '@nrwl/workspace/src/utilities/default-base';
import { resolveUserExistingPrettierConfig } from '@nrwl/workspace/src/utilities/prettier';
import { getRootTsConfigPathInTree } from '@nrwl/workspace/src/utilities/typescript';
import { getRootTsConfigPathInTree } from '@nrwl/js';
import { prettierVersion } from '@nrwl/workspace/src/utils/versions';
import { toNewFormat } from 'nx/src/adapter/angular-json';
import { angularDevkitVersion, nxVersion } from '../../../utils/versions';

View File

@ -8,11 +8,13 @@ import {
} from '@nrwl/devkit';
import type { Schema } from '../schema';
import { tsquery } from '@phenomnomnominal/tsquery';
import * as ts from 'typescript';
import type * as ts from 'typescript';
import { ArrayLiteralExpression } from 'typescript';
import { insertImport } from '@nrwl/workspace/src/utilities/ast-utils';
import { addRoute } from '../../../utils/nx-devkit/route-utils';
let tsModule: typeof import('typescript');
export function checkIsCommaNeeded(mfRemoteText: string) {
const remoteText = mfRemoteText.replace(/\s+/g, '');
return !remoteText.endsWith(',]')
@ -118,6 +120,9 @@ function addLazyLoadedRouteToHostAppModule(
options: Schema,
hostFederationType: 'dynamic' | 'static'
) {
if (!tsModule) {
tsModule = require('typescript');
}
const hostAppConfig = readProjectConfiguration(tree, options.host);
const pathToHostRootRouting = `${hostAppConfig.sourceRoot}/app/app.routes.ts`;
@ -128,10 +133,10 @@ function addLazyLoadedRouteToHostAppModule(
const hostRootRoutingFile = tree.read(pathToHostRootRouting, 'utf-8');
let sourceFile = ts.createSourceFile(
let sourceFile = tsModule.createSourceFile(
pathToHostRootRouting,
hostRootRoutingFile,
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);

View File

@ -1,9 +1,9 @@
import type { Tree } from '@nrwl/devkit';
import { joinPathFragments, readProjectConfiguration } from '@nrwl/devkit';
import type { Schema } from '../schema';
import { tsquery } from '@phenomnomnominal/tsquery';
export function updateAppModule(tree: Tree, schema: Schema) {
const { tsquery } = require('@phenomnomnominal/tsquery');
// read the content of app module
const projectConfig = readProjectConfiguration(tree, schema.project);
const pathToAppModule = joinPathFragments(

View File

@ -48,7 +48,7 @@ describe('angularStories generator: libraries', () => {
beforeEach(async () => {
tree = await createStorybookTestWorkspaceForLib(libName);
await ensurePackage(tree, '@nrwl/storybook', nxVersion);
ensurePackage(tree, '@nrwl/storybook', nxVersion);
cypressProjectGenerator = await (
await import('@nrwl/storybook')
).cypressProjectGenerator;

View File

@ -6,7 +6,7 @@ export async function generateStorybookConfiguration(
tree: Tree,
options: StorybookConfigurationOptions
): Promise<GeneratorCallback> {
await ensurePackage(tree, '@nrwl/storybook', nxVersion);
ensurePackage(tree, '@nrwl/storybook', nxVersion);
const { configurationGenerator } = await import('@nrwl/storybook');
return await configurationGenerator(tree, {
name: options.name,

View File

@ -1,9 +1,9 @@
import type { Tree } from '@nrwl/devkit';
import { writeJson } from '@nrwl/devkit';
import { tsConfigBaseOptions } from '@nrwl/workspace/src/utils/create-ts-config';
import { tsConfigBaseOptions } from '@nrwl/js';
import { getInstalledAngularMajorVersion } from './version-utils';
export { extractTsConfigBase } from '@nrwl/workspace/src/utils/create-ts-config';
export { extractTsConfigBase } from '@nrwl/js';
export function createTsConfig(
host: Tree,

View File

@ -6,7 +6,6 @@ import {
visitNotIgnoredFiles,
} from '@nrwl/devkit';
import { findNodes } from 'nx/src/utils/typescript';
import { tsquery } from '@phenomnomnominal/tsquery';
import { extname } from 'path';
import type {
ClassDeclaration,
@ -79,6 +78,7 @@ export function getModuleFilePaths(
}
function hasNgModule(tree: Tree, filePath: string): boolean {
const { tsquery } = require('@phenomnomnominal/tsquery');
const fileContent = tree.read(filePath, 'utf-8');
const ast = tsquery.ast(fileContent);
const ngModule = tsquery(

View File

@ -4,7 +4,7 @@ import {
readProjectConfiguration,
updateJson,
} from '@nrwl/devkit';
import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript';
import { getRelativePathToRootTsConfig } from '@nrwl/js';
export function updateTsConfig(tree: Tree, project: string): void {
const { root } = readProjectConfiguration(tree, project);

View File

@ -1,7 +1,7 @@
import * as ts from 'typescript';
import type * as ts from 'typescript';
import { findNodes } from 'nx/src/utils/typescript';
import { getSourceNodes } from '@nrwl/workspace/src/utilities/typescript/get-source-nodes';
import * as path from 'path';
import { dirname, join } from 'path';
import { names, readProjectConfiguration, Tree } from '@nrwl/devkit';
import {
getImport,
@ -9,7 +9,8 @@ import {
removeChange,
replaceChange,
} from '@nrwl/workspace/src/utilities/ast-utils';
import { tsquery } from '@phenomnomnominal/tsquery';
let tsModule: typeof import('typescript');
type DecoratorName = 'Component' | 'Directive' | 'NgModule' | 'Pipe';
@ -17,10 +18,13 @@ function _angularImportsFromNode(
node: ts.ImportDeclaration,
_sourceFile: ts.SourceFile
): { [name: string]: string } {
if (!tsModule) {
tsModule = require('typescript');
}
const ms = node.moduleSpecifier;
let modulePath: string;
switch (ms.kind) {
case ts.SyntaxKind.StringLiteral:
case tsModule.SyntaxKind.StringLiteral:
modulePath = (ms as ts.StringLiteral).text;
break;
default:
@ -37,7 +41,7 @@ function _angularImportsFromNode(
return {};
} else if (node.importClause.namedBindings) {
const nb = node.importClause.namedBindings;
if (nb.kind == ts.SyntaxKind.NamespaceImport) {
if (nb.kind == tsModule.SyntaxKind.NamespaceImport) {
// This is of the form `import * as name from 'path'`. Return `name.`.
return {
[`${(nb as ts.NamespaceImport).name.text}.`]: modulePath,
@ -84,9 +88,12 @@ export function getDecoratorMetadata(
identifier: string,
module: string
): ts.Node[] {
if (!tsModule) {
tsModule = require('typescript');
}
const angularImports: { [name: string]: string } = findNodes(
source,
ts.SyntaxKind.ImportDeclaration
tsModule.SyntaxKind.ImportDeclaration
)
.map((node: ts.ImportDeclaration) => _angularImportsFromNode(node, source))
.reduce(
@ -106,13 +113,14 @@ export function getDecoratorMetadata(
return getSourceNodes(source)
.filter((node) => {
return (
node.kind == ts.SyntaxKind.Decorator &&
(node as ts.Decorator).expression.kind == ts.SyntaxKind.CallExpression
node.kind == tsModule.SyntaxKind.Decorator &&
(node as ts.Decorator).expression.kind ==
tsModule.SyntaxKind.CallExpression
);
})
.map((node) => (node as ts.Decorator).expression as ts.CallExpression)
.filter((expr) => {
if (expr.expression.kind == ts.SyntaxKind.Identifier) {
if (expr.expression.kind == tsModule.SyntaxKind.Identifier) {
const id = expr.expression as ts.Identifier;
return (
@ -120,12 +128,12 @@ export function getDecoratorMetadata(
angularImports[id.getFullText(source)] === module
);
} else if (
expr.expression.kind == ts.SyntaxKind.PropertyAccessExpression
expr.expression.kind == tsModule.SyntaxKind.PropertyAccessExpression
) {
// This covers foo.NgModule when importing * as foo.
const paExpr = expr.expression as ts.PropertyAccessExpression;
// If the left expression is not an identifier, just give up at that point.
if (paExpr.expression.kind !== ts.SyntaxKind.Identifier) {
if (paExpr.expression.kind !== tsModule.SyntaxKind.Identifier) {
return false;
}
@ -140,7 +148,7 @@ export function getDecoratorMetadata(
.filter(
(expr) =>
expr.arguments[0] &&
expr.arguments[0].kind == ts.SyntaxKind.ObjectLiteralExpression
expr.arguments[0].kind == tsModule.SyntaxKind.ObjectLiteralExpression
)
.map((expr) => expr.arguments[0] as ts.ObjectLiteralExpression);
}
@ -160,19 +168,22 @@ function _addSymbolToDecoratorMetadata(
if (!node) {
return source;
}
if (!tsModule) {
tsModule = require('typescript');
}
// Get all the children property assignment of object literals.
const matchingProperties: ts.ObjectLiteralElement[] = (
node as ts.ObjectLiteralExpression
).properties
.filter((prop) => prop.kind == ts.SyntaxKind.PropertyAssignment)
.filter((prop) => prop.kind == tsModule.SyntaxKind.PropertyAssignment)
// Filter out every fields that's not "metadataField". Also handles string literals
// (but not expressions).
.filter((prop: ts.PropertyAssignment) => {
const name = prop.name;
switch (name.kind) {
case ts.SyntaxKind.Identifier:
case tsModule.SyntaxKind.Identifier:
return (name as ts.Identifier).getText(source) == metadataField;
case ts.SyntaxKind.StringLiteral:
case tsModule.SyntaxKind.StringLiteral:
return (name as ts.StringLiteral).text == metadataField;
}
@ -211,7 +222,9 @@ function _addSymbolToDecoratorMetadata(
const assignment = matchingProperties[0] as ts.PropertyAssignment;
// If it's not an array, nothing we can do really.
if (assignment.initializer.kind !== ts.SyntaxKind.ArrayLiteralExpression) {
if (
assignment.initializer.kind !== tsModule.SyntaxKind.ArrayLiteralExpression
) {
return source;
}
@ -244,7 +257,7 @@ function _addSymbolToDecoratorMetadata(
let toInsert: string;
let position = node.getEnd();
if (!isArray && node.kind == ts.SyntaxKind.ObjectLiteralExpression) {
if (!isArray && node.kind == tsModule.SyntaxKind.ObjectLiteralExpression) {
// We haven't found the field in the metadata declaration. Insert a new
// field.
const expr = node as ts.ObjectLiteralExpression;
@ -264,7 +277,10 @@ function _addSymbolToDecoratorMetadata(
toInsert = `, ${metadataField}: [${expression}]`;
}
}
} else if (!isArray && node.kind == ts.SyntaxKind.ArrayLiteralExpression) {
} else if (
!isArray &&
node.kind == tsModule.SyntaxKind.ArrayLiteralExpression
) {
// We found the field but it's empty. Insert it just before the `]`.
position--;
toInsert = `${expression}`;
@ -398,17 +414,22 @@ export function addImportToTestBed(
specPath: string,
symbolName: string
): ts.SourceFile {
if (!tsModule) {
tsModule = require('typescript');
}
const allCalls: ts.CallExpression[] = <any>(
findNodes(source, ts.SyntaxKind.CallExpression)
findNodes(source, tsModule.SyntaxKind.CallExpression)
);
const configureTestingModuleObjectLiterals = allCalls
.filter((c) => c.expression.kind === ts.SyntaxKind.PropertyAccessExpression)
.filter(
(c) => c.expression.kind === tsModule.SyntaxKind.PropertyAccessExpression
)
.filter(
(c: any) => c.expression.name.getText(source) === 'configureTestingModule'
)
.map((c) =>
c.arguments[0].kind === ts.SyntaxKind.ObjectLiteralExpression
c.arguments[0].kind === tsModule.SyntaxKind.ObjectLiteralExpression
? c.arguments[0]
: null
);
@ -434,17 +455,22 @@ export function addDeclarationsToTestBed(
specPath: string,
symbolName: string[]
): ts.SourceFile {
if (!tsModule) {
tsModule = require('typescript');
}
const allCalls: ts.CallExpression[] = <any>(
findNodes(source, ts.SyntaxKind.CallExpression)
findNodes(source, tsModule.SyntaxKind.CallExpression)
);
const configureTestingModuleObjectLiterals = allCalls
.filter((c) => c.expression.kind === ts.SyntaxKind.PropertyAccessExpression)
.filter(
(c) => c.expression.kind === tsModule.SyntaxKind.PropertyAccessExpression
)
.filter(
(c: any) => c.expression.name.getText(source) === 'configureTestingModule'
)
.map((c) =>
c.arguments[0].kind === ts.SyntaxKind.ObjectLiteralExpression
c.arguments[0].kind === tsModule.SyntaxKind.ObjectLiteralExpression
? c.arguments[0]
: null
);
@ -471,17 +497,22 @@ export function replaceIntoToTestBed(
newSymbol: string,
previousSymbol: string
): ts.SourceFile {
if (!tsModule) {
tsModule = require('typescript');
}
const allCalls: ts.CallExpression[] = <any>(
findNodes(source, ts.SyntaxKind.CallExpression)
findNodes(source, tsModule.SyntaxKind.CallExpression)
);
const configureTestingModuleObjectLiterals = allCalls
.filter((c) => c.expression.kind === ts.SyntaxKind.PropertyAccessExpression)
.filter(
(c) => c.expression.kind === tsModule.SyntaxKind.PropertyAccessExpression
)
.filter(
(c: any) => c.expression.name.getText(source) === 'configureTestingModule'
)
.map((c) =>
c.arguments[0].kind === ts.SyntaxKind.ObjectLiteralExpression
c.arguments[0].kind === tsModule.SyntaxKind.ObjectLiteralExpression
? c.arguments[0]
: null
);
@ -560,6 +591,9 @@ export function addRouteToNgModule(
function getListOfRoutes(
source: ts.SourceFile
): ts.NodeArray<ts.Expression> | null {
if (!tsModule) {
tsModule = require('typescript');
}
const imports: any = getMatchingProperty(
source,
'imports',
@ -567,11 +601,13 @@ function getListOfRoutes(
'@angular/core'
);
if (imports?.initializer.kind === ts.SyntaxKind.ArrayLiteralExpression) {
if (
imports?.initializer.kind === tsModule.SyntaxKind.ArrayLiteralExpression
) {
const a = imports.initializer as ts.ArrayLiteralExpression;
for (const e of a.elements) {
if (e.kind === ts.SyntaxKind.CallExpression) {
if (e.kind === tsModule.SyntaxKind.CallExpression) {
const ee = e as ts.CallExpression;
const text = ee.expression.getText(source);
if (
@ -580,13 +616,13 @@ function getListOfRoutes(
ee.arguments.length > 0
) {
const routes = ee.arguments[0];
if (routes.kind === ts.SyntaxKind.ArrayLiteralExpression) {
if (routes.kind === tsModule.SyntaxKind.ArrayLiteralExpression) {
return (routes as ts.ArrayLiteralExpression).elements;
} else if (routes.kind === ts.SyntaxKind.Identifier) {
} else if (routes.kind === tsModule.SyntaxKind.Identifier) {
// find the array expression
const variableDeclarations = findNodes(
source,
ts.SyntaxKind.VariableDeclaration
tsModule.SyntaxKind.VariableDeclaration
) as ts.VariableDeclaration[];
const routesDeclaration = variableDeclarations.find((x) => {
@ -611,6 +647,7 @@ export function addProviderToBootstrapApplication(
filePath: string,
providerToAdd: string
) {
const { tsquery } = require('@phenomnomnominal/tsquery');
const PROVIDERS_ARRAY_SELECTOR =
'CallExpression:has(Identifier[name=bootstrapApplication]) ObjectLiteralExpression > PropertyAssignment:has(Identifier[name=providers]) > ArrayLiteralExpression';
@ -711,6 +748,9 @@ export function readBootstrapInfo(
bootstrapComponentClassName: string;
bootstrapComponentFileName: string;
} {
if (!tsModule) {
tsModule = require('typescript');
}
const config = readProjectConfiguration(host, app);
let mainPath;
@ -725,10 +765,10 @@ export function readBootstrapInfo(
}
const mainSource = host.read(mainPath)!.toString('utf-8');
const main = ts.createSourceFile(
const main = tsModule.createSourceFile(
mainPath,
mainSource,
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);
const moduleImports = getImport(
@ -743,19 +783,16 @@ export function readBootstrapInfo(
b.endsWith('Module')
)[0];
const modulePath = `${path.join(
path.dirname(mainPath),
moduleImport.moduleSpec
)}.ts`;
const modulePath = `${join(dirname(mainPath), moduleImport.moduleSpec)}.ts`;
if (!host.exists(modulePath)) {
throw new Error(`Cannot find '${modulePath}'`);
}
const moduleSourceText = host.read(modulePath)!.toString('utf-8');
const moduleSource = ts.createSourceFile(
const moduleSource = tsModule.createSourceFile(
modulePath,
moduleSourceText,
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);
@ -763,8 +800,8 @@ export function readBootstrapInfo(
moduleSource,
moduleClassName
);
const bootstrapComponentFileName = `./${path.join(
path.dirname(moduleImport.moduleSpec),
const bootstrapComponentFileName = `./${join(
dirname(moduleImport.moduleSpec),
`${
names(
bootstrapComponentClassName.substring(
@ -793,11 +830,14 @@ export function getDecoratorPropertyValueNode(
property: string,
module: string
) {
if (!tsModule) {
tsModule = require('typescript');
}
const moduleSourceText = host.read(modulePath)!.toString('utf-8');
const moduleSource = ts.createSourceFile(
const moduleSource = tsModule.createSourceFile(
modulePath,
moduleSourceText,
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);
const templateNode = getMatchingProperty(
@ -815,17 +855,20 @@ function getMatchingObjectLiteralElement(
source: ts.SourceFile,
property: string
) {
if (!tsModule) {
tsModule = require('typescript');
}
return (
(node as ts.ObjectLiteralExpression).properties
.filter((prop) => prop.kind == ts.SyntaxKind.PropertyAssignment)
.filter((prop) => prop.kind == tsModule.SyntaxKind.PropertyAssignment)
// Filter out every fields that's not "metadataField". Also handles string literals
// (but not expressions).
.filter((prop: ts.PropertyAssignment) => {
const name = prop.name;
switch (name.kind) {
case ts.SyntaxKind.Identifier:
case tsModule.SyntaxKind.Identifier:
return (name as ts.Identifier).getText(source) === property;
case ts.SyntaxKind.StringLiteral:
case tsModule.SyntaxKind.StringLiteral:
return (name as ts.StringLiteral).text === property;
}
return false;
@ -834,15 +877,18 @@ function getMatchingObjectLiteralElement(
}
export function getTsSourceFile(host: Tree, path: string): ts.SourceFile {
if (!tsModule) {
tsModule = require('typescript');
}
const buffer = host.read(path);
if (!buffer) {
throw new Error(`Could not read TS file (${path}).`);
}
const content = buffer.toString();
const source = ts.createSourceFile(
const source = tsModule.createSourceFile(
path,
content,
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);

View File

@ -1,9 +1,9 @@
import { Tree } from '@nrwl/devkit';
import { tsquery } from '@phenomnomnominal/tsquery';
import * as ts from 'typescript';
import { insertImport } from '@nrwl/workspace/src/utilities/ast-utils';
import { addRouteToNgModule } from './ast-utils';
let tsModule: typeof import('typescript');
export function addRoute(
tree: Tree,
routesFile: string,
@ -17,14 +17,18 @@ export function addRoute(
`Path to parent routing declaration (${routesFile}) does not exist. Please ensure path is correct.`
);
}
if (!tsModule) {
tsModule = require('typescript');
}
const { tsquery } = require('@phenomnomnominal/tsquery');
let routesFileContents = tree.read(routesFile, 'utf-8');
if (!lazy) {
let parentSourceFile = ts.createSourceFile(
let parentSourceFile = tsModule.createSourceFile(
routesFile,
routesFileContents,
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);
@ -51,10 +55,10 @@ export function addRoute(
if (!isRoutesArray) {
if (routesFileContents.includes('@NgModule')) {
const sourceFile = ts.createSourceFile(
const sourceFile = tsModule.createSourceFile(
routesFile,
routesFileContents,
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);
@ -91,6 +95,7 @@ export function addProviderToRoute(
);
}
const { tsquery } = require('@phenomnomnominal/tsquery');
let routesFileContents = tree.read(routesFile, 'utf-8');
const ast = tsquery.ast(routesFileContents);

View File

@ -35,6 +35,7 @@
},
"dependencies": {
"@nrwl/devkit": "file:../devkit",
"@nrwl/js": "file:../js",
"@nrwl/linter": "file:../linter",
"@nrwl/workspace": "file:../workspace",
"@phenomnomnominal/tsquery": "4.1.1",

View File

@ -5,6 +5,7 @@ import {
extractLayoutDirectory,
formatFiles,
generateFiles,
GeneratorCallback,
getProjects,
getWorkspaceLayout,
joinPathFragments,
@ -20,7 +21,10 @@ import {
} from '@nrwl/devkit';
import { Linter, lintProjectGenerator } from '@nrwl/linter';
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript';
import {
initGenerator as jsInitGenerator,
getRelativePathToRootTsConfig,
} from '@nrwl/js';
import {
globalJavaScriptOverrides,
globalTypeScriptOverrides,
@ -261,7 +265,11 @@ export async function addLinter(host: Tree, options: CypressProjectSchema) {
export async function cypressProjectGenerator(host: Tree, schema: Schema) {
const options = normalizeOptions(host, schema);
const tasks = [];
await jsInitGenerator(host, {
js: schema.js,
skipFormat: true,
});
const tasks: GeneratorCallback[] = [];
const cypressVersion = installedCypressVersion();
// if there is an installed cypress version, then we don't call
// init since we want to keep the existing version that is installed

View File

@ -8,14 +8,11 @@ import {
visitNotIgnoredFiles,
normalizePath,
} from '@nrwl/devkit';
import { tsquery } from '@phenomnomnominal/tsquery';
import { basename, dirname, extname, relative } from 'path';
import {
isCallExpression,
isExportDeclaration,
isImportDeclaration,
StringLiteral,
} from 'typescript';
import type { StringLiteral } from 'typescript';
let tsModule: typeof import('typescript');
let tsquery: typeof import('@phenomnomnominal/tsquery').tsquery;
const validFilesEndingsToUpdate = [
'.js',
@ -272,6 +269,14 @@ export function updateImports(
oldImportPath: string,
newImportPath: string
) {
if (!tsquery) {
tsquery = require('@phenomnomnominal/tsquery').tsquery;
}
if (!tsModule) {
tsModule = require('typescript');
}
const { isCallExpression, isExportDeclaration, isImportDeclaration } =
tsModule;
const endOfImportSelector = `StringLiteral[value=/${oldImportPath}$/]`;
const fileContent = tree.read(filePath, 'utf-8');
const newContent = tsquery.replace(

View File

@ -15,7 +15,6 @@ import {
} from '@nrwl/devkit';
import { forEachExecutorOptions } from '@nrwl/workspace/src/utilities/executor-options-utils';
import { CypressExecutorOptions } from '../../executors/cypress/cypress.impl';
import { cypressVersion } from '../../utils/versions';
import {
addConfigToTsConfig,
createNewCypressConfig,

View File

@ -27,6 +27,7 @@
"dependencies": {
"@nrwl/devkit": "file:../devkit",
"@nrwl/jest": "file:../jest",
"@nrwl/js": "file:../js",
"@nrwl/linter": "file:../linter",
"@nrwl/react": "file:../react",
"@nrwl/workspace": "file:../workspace"

View File

@ -6,7 +6,7 @@ import {
toJS,
Tree,
} from '@nrwl/devkit';
import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript';
import { getRelativePathToRootTsConfig } from '@nrwl/js';
import { join } from 'path';
import { NormalizedSchema } from './normalize-options';

View File

@ -459,27 +459,27 @@ describe('ensurePackage', () => {
it('should return successfully when package is present', async () => {
writeJson(tree, 'package.json', {});
await expect(
expect(
ensurePackage(tree, '@nrwl/devkit', '>=15.0.0', {
throwOnMissing: true,
})
).resolves.toBeUndefined(); // return void
).toBeUndefined(); // return void
});
it('should throw when dependencies are missing', async () => {
writeJson(tree, 'package.json', {});
await expect(() =>
expect(() =>
ensurePackage(tree, '@nrwl/does-not-exist', '>=15.0.0', {
throwOnMissing: true,
})
).rejects.toThrow(/-D( -W)? @nrwl\/does-not-exist@>=15.0.0/);
).toThrow(/-D( -W)? @nrwl\/does-not-exist@>=15.0.0/);
await expect(() =>
expect(() =>
ensurePackage(tree, '@nrwl/does-not-exist', '>=15.0.0', {
dev: false,
throwOnMissing: true,
})
).rejects.toThrow('@nrwl/does-not-exist@>=15.0.0');
).toThrow('@nrwl/does-not-exist@>=15.0.0');
});
});

View File

@ -372,7 +372,7 @@ function requiresRemovingOfPackages(
*
* For example:
* ```typescript
* ensurePackage(tree, {}, { '@nrwl/jest': nxVersion })
* ensurePackage(tree, '@nrwl/jest', nxVersion)
* ```
* This will check that @nrwl/jest@<nxVersion> exists in devDependencies.
* If it exists then function returns, otherwise it will install the package before continuing.
@ -382,9 +382,8 @@ function requiresRemovingOfPackages(
* @param pkg the package to check (e.g. @nrwl/jest)
* @param requiredVersion the version or semver range to check (e.g. ~1.0.0, >=1.0.0 <2.0.0)
* @param {EnsurePackageOptions} options
* @returns {Promise<void>}
*/
export async function ensurePackage(
export function ensurePackage(
tree: Tree,
pkg: string,
requiredVersion: string,
@ -392,7 +391,7 @@ export async function ensurePackage(
dev?: boolean;
throwOnMissing?: boolean;
} = {}
): Promise<void> {
): void {
// Read package and version from root package.json file.
const dev = options.dev ?? true;
const throwOnMissing =

View File

@ -29,6 +29,7 @@
"@nrwl/detox": "file:../detox",
"@nrwl/devkit": "file:../devkit",
"@nrwl/jest": "file:../jest",
"@nrwl/js": "file:../js",
"@nrwl/linter": "file:../linter",
"@nrwl/react": "file:../react",
"@nrwl/webpack": "file:../webpack",

View File

@ -2,6 +2,7 @@ import {
addDependenciesToPackageJson,
convertNxGenerator,
formatFiles,
GeneratorCallback,
removeDependenciesFromPackageJson,
Tree,
} from '@nrwl/devkit';
@ -34,6 +35,7 @@ import {
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
import { jestInitGenerator } from '@nrwl/jest';
import { detoxInitGenerator } from '@nrwl/detox';
import { initGenerator as jsInitGenerator } from '@nrwl/js';
import { addGitIgnoreEntry } from './lib/add-git-ignore-entry';
import { initRootBabelConfig } from './lib/init-root-babel-config';
@ -41,8 +43,12 @@ import { initRootBabelConfig } from './lib/init-root-babel-config';
export async function expoInitGenerator(host: Tree, schema: Schema) {
addGitIgnoreEntry(host);
initRootBabelConfig(host);
await jsInitGenerator(host, {
js: schema.js,
skipFormat: true,
});
const tasks = [];
const tasks: GeneratorCallback[] = [];
if (!schema.skipPackageJson) {
tasks.push(moveDependency(host));
@ -50,7 +56,7 @@ export async function expoInitGenerator(host: Tree, schema: Schema) {
}
if (!schema.unitTestRunner || schema.unitTestRunner === 'jest') {
const jestTask = jestInitGenerator(host, {});
const jestTask = await jestInitGenerator(host, {});
tasks.push(jestTask);
}

View File

@ -3,4 +3,5 @@ export interface Schema {
skipFormat?: boolean;
e2eTestRunner?: 'detox' | 'none';
skipPackageJson?: boolean; // default is false
js?: boolean;
}

View File

@ -25,8 +25,13 @@
},
"skipPackageJson": {
"type": "boolean",
"description": "Do not add dependencies to `package.json`.",
"default": false
"default": false,
"description": "Do not add dependencies to `package.json`."
},
"js": {
"type": "boolean",
"default": false,
"description": "Use JavaScript instead of TypeScript"
}
},
"required": []

View File

@ -1,4 +1,5 @@
import {
getImportPath,
getWorkspaceLayout,
joinPathFragments,
names,
@ -34,7 +35,8 @@ export function normalizeOptions(
? options.tags.split(',').map((s) => s.trim())
: [];
const importPath = options.importPath || `@${npmScope}/${projectDirectory}`;
const importPath =
options.importPath || getImportPath(npmScope, projectDirectory);
const appMain = options.js ? 'src/index.js' : 'src/index.ts';

View File

@ -14,6 +14,7 @@ import {
updateJson,
} from '@nrwl/devkit';
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
import { updateRootTsConfig } from '@nrwl/js';
import init from '../init/init';
import { addLinting } from '../../utils/add-linting';
@ -52,7 +53,7 @@ export async function expoLibraryGenerator(
);
if (!options.skipTsConfig) {
updateBaseTsConfig(host, options);
updateRootTsConfig(host, options);
}
const jestTask = await addJest(
@ -131,31 +132,6 @@ function updateTsConfig(tree: Tree, options: NormalizedSchema) {
);
}
function updateBaseTsConfig(host: Tree, options: NormalizedSchema) {
updateJson(host, 'tsconfig.base.json', (json) => {
const c = json.compilerOptions;
c.paths = c.paths || {};
delete c.paths[options.name];
if (c.paths[options.importPath]) {
throw new Error(
`You already have a library using the import path "${options.importPath}". Make sure to specify a unique one.`
);
}
const { libsDir } = getWorkspaceLayout(host);
c.paths[options.importPath] = [
maybeJs(
options,
joinPathFragments(libsDir, `${options.projectDirectory}/src/index.ts`)
),
];
return json;
});
}
function createFiles(host: Tree, options: NormalizedSchema) {
generateFiles(
host,

View File

@ -37,6 +37,7 @@
"@jest/reporters": "28.1.1",
"@jest/test-result": "28.1.1",
"@nrwl/devkit": "file:../devkit",
"@nrwl/js": "file:../js",
"@phenomnomnominal/tsquery": "4.1.1",
"chalk": "^4.1.0",
"dotenv": "~10.0.0",

View File

@ -19,7 +19,7 @@ describe('jest', () => {
});
it('should generate files with --js flag', async () => {
jestInitGenerator(tree, { js: true });
await jestInitGenerator(tree, { js: true });
expect(tree.exists('jest.config.js')).toBeTruthy();
expect(
@ -31,7 +31,7 @@ describe('jest', () => {
});
it('should generate files ', async () => {
jestInitGenerator(tree, {});
await jestInitGenerator(tree, {});
expect(tree.exists('jest.config.ts')).toBeTruthy();
expect(
@ -64,7 +64,7 @@ export default {
}
`;
tree.write('jest.config.ts', expected);
jestInitGenerator(tree, {});
await jestInitGenerator(tree, {});
expect(tree.read('jest.config.ts', 'utf-8')).toEqual(expected);
});
@ -75,7 +75,7 @@ export default {
return json;
});
jestInitGenerator(tree, {});
await jestInitGenerator(tree, {});
const productionFileSet = readJson<NxJsonConfiguration>(tree, 'nx.json')
.namedInputs.production;
@ -98,7 +98,7 @@ export default {
return json;
});
jestInitGenerator(tree, {});
await jestInitGenerator(tree, {});
let nxJson: NxJsonConfiguration;
updateJson<NxJsonConfiguration>(tree, 'nx.json', (json) => {
@ -119,12 +119,12 @@ export default {
nxJson = json;
return json;
});
jestInitGenerator(tree, {});
await jestInitGenerator(tree, {});
expect(readJson<NxJsonConfiguration>(tree, 'nx.json')).toEqual(nxJson);
});
it('should add dependencies', async () => {
jestInitGenerator(tree, {});
await jestInitGenerator(tree, {});
const packageJson = readJson(tree, 'package.json');
expect(packageJson.devDependencies.jest).toBeDefined();
expect(packageJson.devDependencies['@nrwl/jest']).toBeDefined();
@ -133,46 +133,46 @@ export default {
expect(packageJson.devDependencies['ts-node']).toBeDefined();
});
it('should make js jest files', () => {
jestInitGenerator(tree, { js: true });
it('should make js jest files', async () => {
await jestInitGenerator(tree, { js: true });
expect(tree.exists('jest.config.js')).toBeTruthy();
expect(tree.exists('jest.preset.js')).toBeTruthy();
});
describe('Deprecated: --babelJest', () => {
it('should add babel dependencies', async () => {
jestInitGenerator(tree, { babelJest: true });
await jestInitGenerator(tree, { babelJest: true });
const packageJson = readJson(tree, 'package.json');
expect(packageJson.devDependencies['babel-jest']).toBeDefined();
});
});
describe('--compiler', () => {
it('should support tsc compiler', () => {
jestInitGenerator(tree, { compiler: 'tsc' });
it('should support tsc compiler', async () => {
await jestInitGenerator(tree, { compiler: 'tsc' });
const packageJson = readJson(tree, 'package.json');
expect(packageJson.devDependencies['ts-jest']).toBeDefined();
});
it('should support babel compiler', () => {
jestInitGenerator(tree, { compiler: 'babel' });
it('should support babel compiler', async () => {
await jestInitGenerator(tree, { compiler: 'babel' });
const packageJson = readJson(tree, 'package.json');
expect(packageJson.devDependencies['babel-jest']).toBeDefined();
});
it('should support swc compiler', () => {
jestInitGenerator(tree, { compiler: 'swc' });
it('should support swc compiler', async () => {
await jestInitGenerator(tree, { compiler: 'swc' });
const packageJson = readJson(tree, 'package.json');
expect(packageJson.devDependencies['@swc/jest']).toBeDefined();
});
});
describe('root project', () => {
it('should not add a monorepo jest.config.ts to the project', () => {
jestInitGenerator(tree, { rootProject: true });
it('should not add a monorepo jest.config.ts to the project', async () => {
await jestInitGenerator(tree, { rootProject: true });
expect(tree.exists('jest.config.ts')).toBeFalsy();
});
it('should rename the project jest.config.ts to project jest config', () => {
it('should rename the project jest.config.ts to project jest config', async () => {
addProjectConfiguration(tree, 'my-project', {
root: '.',
name: 'my-project',
@ -202,7 +202,7 @@ export default {
};
`
);
jestInitGenerator(tree, { rootProject: false });
await jestInitGenerator(tree, { rootProject: false });
expect(tree.exists('jest.config.app.ts')).toBeTruthy();
expect(tree.read('jest.config.ts', 'utf-8'))
.toEqual(`import { getJestProjects } from '@nrwl/jest';
@ -221,7 +221,7 @@ projects: getJestProjects()
`);
});
it('should work with --js', () => {
it('should work with --js', async () => {
addProjectConfiguration(tree, 'my-project', {
root: '.',
name: 'my-project',
@ -251,7 +251,7 @@ module.exports = {
};
`
);
jestInitGenerator(tree, { js: true, rootProject: false });
await jestInitGenerator(tree, { js: true, rootProject: false });
expect(tree.exists('jest.config.app.js')).toBeTruthy();
expect(tree.read('jest.config.js', 'utf-8'))
.toEqual(`const { getJestProjects } = require('@nrwl/jest');
@ -275,7 +275,7 @@ projects: getJestProjects()
});
it('should add the jest extension to the recommended property', async () => {
jestInitGenerator(tree, {});
await jestInitGenerator(tree, {});
const extensionsJson = readJson(tree, '.vscode/extensions.json');
expect(extensionsJson).toMatchInlineSnapshot(`
Object {

View File

@ -11,6 +11,8 @@ import {
updateNxJson,
updateProjectConfiguration,
} from '@nrwl/devkit';
import { initGenerator as jsInitGenerator } from '@nrwl/js';
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
import { findRootJestConfig } from '../../utils/config/find-root-jest-files';
import {
babelJestVersion,
@ -184,18 +186,27 @@ function updateExtensions(host: Tree) {
});
}
export function jestInitGenerator(tree: Tree, schema: JestInitSchema) {
export async function jestInitGenerator(
tree: Tree,
schema: JestInitSchema
): Promise<GeneratorCallback> {
const options = normalizeOptions(schema);
await jsInitGenerator(tree, {
js: schema.js,
skipFormat: true,
});
const tasks: GeneratorCallback[] = [];
createJestConfig(tree, options);
let installTask: GeneratorCallback = () => {};
if (!options.skipPackageJson) {
removeDependenciesFromPackageJson(tree, ['@nrwl/jest'], []);
installTask = updateDependencies(tree, options);
const installTask = updateDependencies(tree, options);
tasks.push(installTask);
}
updateExtensions(tree);
return installTask;
return runTasksInSerial(...tasks);
}
function normalizeOptions(options: JestInitSchema) {

View File

@ -4,7 +4,12 @@ import { createFiles } from './lib/create-files';
import { updateTsConfig } from './lib/update-tsconfig';
import { updateWorkspace } from './lib/update-workspace';
import { JestProjectSchema } from './schema';
import { formatFiles, Tree, convertNxGenerator } from '@nrwl/devkit';
import {
formatFiles,
Tree,
convertNxGenerator,
GeneratorCallback,
} from '@nrwl/devkit';
const schemaDefaults = {
setupFile: 'none',
@ -51,9 +56,9 @@ function normalizeOptions(options: JestProjectSchema) {
export async function jestProjectGenerator(
tree: Tree,
schema: JestProjectSchema
) {
): Promise<GeneratorCallback> {
const options = normalizeOptions(schema);
const installTask = init(tree, options);
const installTask = await init(tree, options);
checkForTestTarget(tree, options);
createFiles(tree, options);

View File

@ -1,9 +1,11 @@
import * as ts from 'typescript';
import type * as ts from 'typescript';
import { applyChangesToString, ChangeType, Tree } from '@nrwl/devkit';
import { Config } from '@jest/types';
import { createContext, runInContext } from 'vm';
import { dirname, join } from 'path';
let tsModule: typeof import('typescript');
function makeTextToInsert(
value: unknown,
precedingCommaNeeded: boolean
@ -15,8 +17,12 @@ function findPropertyAssignment(
object: ts.ObjectLiteralExpression,
propertyName: string
) {
if (!tsModule) {
tsModule = require('typescript');
}
return object.properties.find((prop) => {
if (!ts.isPropertyAssignment(prop)) {
if (!tsModule.isPropertyAssignment(prop)) {
return false;
}
const propNameText = prop.name.getText();
@ -35,6 +41,11 @@ export function addOrUpdateProperty(
value: unknown,
path: string
) {
if (!tsModule) {
tsModule = require('typescript');
}
const { SyntaxKind } = tsModule;
const propertyName = properties.shift();
const propertyAssignment = findPropertyAssignment(object, propertyName);
@ -42,10 +53,10 @@ export function addOrUpdateProperty(
if (propertyAssignment) {
if (
propertyAssignment.initializer.kind === ts.SyntaxKind.StringLiteral ||
propertyAssignment.initializer.kind === ts.SyntaxKind.NumericLiteral ||
propertyAssignment.initializer.kind === ts.SyntaxKind.FalseKeyword ||
propertyAssignment.initializer.kind === ts.SyntaxKind.TrueKeyword
propertyAssignment.initializer.kind === SyntaxKind.StringLiteral ||
propertyAssignment.initializer.kind === SyntaxKind.NumericLiteral ||
propertyAssignment.initializer.kind === SyntaxKind.FalseKeyword ||
propertyAssignment.initializer.kind === SyntaxKind.TrueKeyword
) {
const updatedContents = applyChangesToString(originalContents, [
{
@ -65,8 +76,7 @@ export function addOrUpdateProperty(
}
if (
propertyAssignment.initializer.kind ===
ts.SyntaxKind.ArrayLiteralExpression
propertyAssignment.initializer.kind === SyntaxKind.ArrayLiteralExpression
) {
const arrayLiteral =
propertyAssignment.initializer as ts.ArrayLiteralExpression;
@ -106,8 +116,7 @@ export function addOrUpdateProperty(
return;
}
} else if (
propertyAssignment.initializer.kind ===
ts.SyntaxKind.ObjectLiteralExpression
propertyAssignment.initializer.kind === SyntaxKind.ObjectLiteralExpression
) {
return addOrUpdateProperty(
tree,
@ -143,6 +152,10 @@ export function removeProperty(
object: ts.ObjectLiteralExpression,
properties: string[]
): ts.PropertyAssignment | null {
if (!tsModule) {
tsModule = require('typescript');
}
const propertyName = properties.shift();
const propertyAssignment = findPropertyAssignment(object, propertyName);
@ -150,7 +163,7 @@ export function removeProperty(
if (
properties.length > 0 &&
propertyAssignment.initializer.kind ===
ts.SyntaxKind.ObjectLiteralExpression
tsModule.SyntaxKind.ObjectLiteralExpression
) {
return removeProperty(
propertyAssignment.initializer as ts.ObjectLiteralExpression,
@ -164,20 +177,28 @@ export function removeProperty(
}
function isModuleExport(node: ts.Statement) {
if (!tsModule) {
tsModule = require('typescript');
}
return (
ts.isExpressionStatement(node) &&
tsModule.isExpressionStatement(node) &&
node.expression?.kind &&
ts.isBinaryExpression(node.expression) &&
tsModule.isBinaryExpression(node.expression) &&
node.expression.left.getText() === 'module.exports' &&
node.expression.operatorToken?.kind === ts.SyntaxKind.EqualsToken
node.expression.operatorToken?.kind === tsModule.SyntaxKind.EqualsToken
);
}
function isDefaultExport(node: ts.Statement) {
if (!tsModule) {
tsModule = require('typescript');
}
return (
ts.isExportAssignment(node) &&
tsModule.isExportAssignment(node) &&
node.expression?.kind &&
ts.isObjectLiteralExpression(node.expression) &&
tsModule.isObjectLiteralExpression(node.expression) &&
node.getText().startsWith('export default')
);
}
@ -188,10 +209,14 @@ function isDefaultExport(node: ts.Statement) {
export function jestConfigObjectAst(
fileContent: string
): ts.ObjectLiteralExpression {
const sourceFile = ts.createSourceFile(
if (!tsModule) {
tsModule = require('typescript');
}
const sourceFile = tsModule.createSourceFile(
'jest.config.ts',
fileContent,
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);
@ -200,7 +225,7 @@ export function jestConfigObjectAst(
);
let ast: ts.ObjectLiteralExpression;
if (ts.isExpressionStatement(exportStatement)) {
if (tsModule.isExpressionStatement(exportStatement)) {
const moduleExports = exportStatement.expression as ts.BinaryExpression;
if (!moduleExports) {
throw new Error(
@ -211,7 +236,7 @@ export function jestConfigObjectAst(
}
ast = moduleExports.right as ts.ObjectLiteralExpression;
} else if (ts.isExportAssignment(exportStatement)) {
} else if (tsModule.isExportAssignment(exportStatement)) {
const defaultExport =
exportStatement.expression as ts.ObjectLiteralExpression;
@ -233,7 +258,7 @@ export function jestConfigObjectAst(
);
}
if (!ts.isObjectLiteralExpression(ast)) {
if (!tsModule.isObjectLiteralExpression(ast)) {
throw new Error(
`The 'export default' or 'module.exports' expression is not an object literal.`
);

View File

@ -14,7 +14,7 @@
"schema": "./src/generators/init/schema.json",
"aliases": ["lib"],
"x-type": "init",
"description": "Init placeholder.",
"description": "Initialize a TS/JS workspace.",
"hidden": true
},
"convert-to-swc": {
@ -38,7 +38,7 @@
"schema": "./src/generators/init/schema.json",
"aliases": ["lib"],
"x-type": "init",
"description": "Init placeholder.",
"description": "Initialize a TS/JS workspace.",
"hidden": true
},
"convert-to-swc": {

View File

@ -40,7 +40,6 @@
"@babel/preset-typescript": "^7.15.0",
"@babel/runtime": "^7.14.8",
"@nrwl/devkit": "file:../devkit",
"@nrwl/linter": "file:../linter",
"@nrwl/workspace": "file:../workspace",
"babel-plugin-const-enum": "^1.0.1",
"babel-plugin-macros": "^2.8.0",

View File

@ -2,7 +2,7 @@ import { readProjectConfiguration, Tree } from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { join } from 'path';
import { LibraryGeneratorSchema } from '../../utils/schema';
import { libraryGenerator } from '../library/library';
import { libraryGenerator as jsLibraryGenerator } from '../library/library';
import { convertToSwcGenerator } from './convert-to-swc';
describe('convert to swc', () => {
@ -28,7 +28,7 @@ describe('convert to swc', () => {
});
it('should convert tsc to swc', async () => {
await libraryGenerator(tree, {
await jsLibraryGenerator(tree, {
...defaultLibGenerationOptions,
name: 'tsc-lib',
buildable: true,

View File

@ -1,10 +1,33 @@
import { convertNxGenerator, logger } from '@nrwl/devkit';
import {
convertNxGenerator,
ensurePackage,
formatFiles,
generateFiles,
joinPathFragments,
Tree,
} from '@nrwl/devkit';
import { getRootTsConfigFileName } from '../../utils/typescript/ts-config';
import { typescriptVersion } from '../../utils/versions';
import { InitSchema } from './schema';
export async function initGenerator() {
logger.info(
'This is a placeholder for @nrwl/js:init generator. If you want to create a library, use @nrwl/js:lib instead'
);
export async function initGenerator(
host: Tree,
schema: InitSchema
): Promise<void> {
if (!schema.js) {
ensurePackage(host, 'typescript', typescriptVersion);
}
// add tsconfig.base.json
if (!getRootTsConfigFileName()) {
generateFiles(host, joinPathFragments(__dirname, './files'), '.', {});
}
if (!schema.skipFormat) {
await formatFiles(host);
}
}
export default initGenerator;
export const initSchematic = convertNxGenerator(initGenerator);

View File

@ -0,0 +1,4 @@
export interface InitSchema {
js?: boolean;
skipFormat?: boolean;
}

View File

@ -3,5 +3,19 @@
"$id": "NxTypescriptInit",
"cli": "nx",
"title": "Init nrwl/js",
"description": "Init generator placeholder for nrwl/js."
"description": "Init generator placeholder for nrwl/js.",
"properties": {
"js": {
"type": "boolean",
"default": false,
"description": "Use JavaScript instead of TypeScript"
},
"skipFormat": {
"type": "boolean",
"aliases": ["skip-format"],
"description": "Skip formatting files.",
"default": true,
"x-priority": "internal"
}
}
}

View File

@ -19,12 +19,11 @@ import {
writeJson,
} from '@nrwl/devkit';
import { getImportPath } from 'nx/src/utils/path';
import { Linter, lintProjectGenerator } from '@nrwl/linter';
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
import {
getRelativePathToRootTsConfig,
getRootTsConfigPathInTree,
} from '@nrwl/workspace/src/utilities/typescript';
updateRootTsConfig,
} from '../../utils/typescript/ts-config';
import { join } from 'path';
import { addMinimalPublishScript } from '../../utils/minimal-publish-script';
import { LibraryGeneratorSchema } from '../../utils/schema';
@ -35,6 +34,7 @@ import {
nxVersion,
typesNodeVersion,
} from '../../utils/versions';
import jsInitGenerator from '../init/init';
export async function libraryGenerator(
tree: Tree,
@ -54,6 +54,10 @@ export async function projectGenerator(
destinationDir: string,
filesDir: string
) {
await jsInitGenerator(tree, {
js: schema.js,
skipFormat: true,
});
const tasks: GeneratorCallback[] = [];
const options = normalizeOptions(tree, schema, destinationDir);
@ -64,7 +68,7 @@ export async function projectGenerator(
tasks.push(addProjectDependencies(tree, options));
if (options.bundler === 'vite') {
await ensurePackage(tree, '@nrwl/vite', nxVersion);
ensurePackage(tree, '@nrwl/vite', nxVersion);
// nx-ignore-next-line
const { viteConfigurationGenerator } = require('@nrwl/vite');
const viteTask = await viteConfigurationGenerator(tree, {
@ -77,10 +81,6 @@ export async function projectGenerator(
tasks.push(viteTask);
}
if (!schema.skipTsConfig) {
updateRootTsConfig(tree, options);
}
if (schema.bundler === 'webpack' || schema.bundler === 'rollup') {
ensureBabelRootConfigExists(tree);
}
@ -99,7 +99,7 @@ export async function projectGenerator(
options.unitTestRunner === 'vitest' &&
options.bundler !== 'vite' // Test would have been set up already
) {
await ensurePackage(tree, '@nrwl/vite', nxVersion);
ensurePackage(tree, '@nrwl/vite', nxVersion);
// nx-ignore-next-line
const { vitestGenerator } = require('@nrwl/vite');
const vitestTask = await vitestGenerator(tree, {
@ -110,6 +110,10 @@ export async function projectGenerator(
tasks.push(vitestTask);
}
if (!schema.skipTsConfig) {
updateRootTsConfig(tree, options);
}
if (!options.skipFormat) {
await formatFiles(tree);
}
@ -191,10 +195,12 @@ function addProject(
}
}
export function addLint(
export async function addLint(
tree: Tree,
options: NormalizedSchema
): Promise<GeneratorCallback> {
ensurePackage(tree, '@nrwl/linter', nxVersion);
const { lintProjectGenerator } = require('@nrwl/linter');
return lintProjectGenerator(tree, {
project: options.name,
linter: options.linter,
@ -320,7 +326,7 @@ async function addJest(
tree: Tree,
options: NormalizedSchema
): Promise<GeneratorCallback> {
await ensurePackage(tree, '@nrwl/jest', nxVersion);
ensurePackage(tree, '@nrwl/jest', nxVersion);
const { jestProjectGenerator } = require('@nrwl/jest');
return await jestProjectGenerator(tree, {
...options,
@ -372,6 +378,7 @@ function normalizeOptions(
options.buildable = true;
}
const { Linter } = require('@nrwl/linter');
if (options.config === 'npm-scripts') {
options.unitTestRunner = 'none';
options.linter = Linter.None;
@ -435,30 +442,6 @@ function getCaseAwareFileName(options: {
return options.pascalCaseFiles ? normalized.className : normalized.fileName;
}
function updateRootTsConfig(host: Tree, options: NormalizedSchema) {
updateJson(host, getRootTsConfigPathInTree(host), (json) => {
const c = json.compilerOptions;
c.paths = c.paths || {};
delete c.paths[options.name];
if (c.paths[options.importPath]) {
throw new Error(
`You already have a library using the import path "${options.importPath}". Make sure to specify a unique one.`
);
}
c.paths[options.importPath] = [
joinPathFragments(
options.projectRoot,
'./src',
'index.' + (options.js ? 'js' : 'ts')
),
];
return json;
});
}
function addProjectDependencies(
tree: Tree,
options: NormalizedSchema

View File

@ -1,10 +1,13 @@
export * from './utils/typescript/load-ts-transformers';
export * from './utils/typescript/print-diagnostics';
export * from './utils/typescript/run-type-check';
export * from './utils/compiler-helper-dependency';
export * from './utils/typescript/ts-config';
export * from './utils/typescript/create-ts-config';
export * from './utils/package-json';
export * from './utils/assets';
export * from './utils/package-json/update-package-json';
export { libraryGenerator } from './generators/library/library';
export { initGenerator } from './generators/init/init';
export { createLockFile } from 'nx/src/lock-file/lock-file';
export { createPackageJson } from 'nx/src/utils/create-package-json';

View File

@ -15,9 +15,9 @@ describe('Migration: adjust .swcrc', () => {
let tree: Tree;
let projectConfiguration: ProjectConfiguration;
beforeEach(() => {
beforeEach(async () => {
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
libraryGenerator(tree, {
await libraryGenerator(tree, {
name: 'swc',
buildable: true,
linter: 'none',

View File

@ -5,8 +5,8 @@ import {
readJsonFile,
} from '@nrwl/devkit';
import { DependentBuildableProjectNode } from '@nrwl/workspace/src/utilities/buildable-libs-utils';
import { readTsConfig } from '@nrwl/workspace/src/utilities/typescript';
import { join } from 'path';
import { readTsConfig } from './typescript/ts-config';
import { ExecutorOptions, SwcExecutorOptions } from './schema';
import { getSwcrcPath } from './swc/get-swcrc-path';

View File

@ -1,5 +1,5 @@
// nx-ignore-next-line
const { Linter } = require('@nrwl/linter');
const { Linter } = require('@nrwl/linter'); // use require to import to avoid circular dependency
import type {
AssetGlob,
FileInputOutput,

View File

@ -1,9 +1,9 @@
import { readTsConfig } from '@nrwl/workspace/src/utilities/typescript';
import * as chalk from 'chalk';
import * as path from 'path';
import type { BuilderProgram, Diagnostic, Program } from 'typescript';
import { codeFrameColumns } from 'nx/src/utils/code-frames';
import { highlight } from '../code-frames/highlight';
import { readTsConfig } from '../../utils/typescript/ts-config';
export interface TypeCheckResult {
warnings?: string[];

View File

@ -0,0 +1,97 @@
import {
joinPathFragments,
offsetFromRoot,
Tree,
updateJson,
workspaceRoot,
} from '@nrwl/devkit';
import { existsSync } from 'fs';
import { dirname, join } from 'path';
let tsModule: typeof import('typescript');
export function readTsConfig(tsConfigPath: string) {
if (!tsModule) {
tsModule = require('typescript');
}
const readResult = tsModule.readConfigFile(
tsConfigPath,
tsModule.sys.readFile
);
return tsModule.parseJsonConfigFileContent(
readResult.config,
tsModule.sys,
dirname(tsConfigPath)
);
}
export function getRootTsConfigPathInTree(tree: Tree): string | null {
for (const path of ['tsconfig.base.json', 'tsconfig.json']) {
if (tree.exists(path)) {
return path;
}
}
return 'tsconfig.base.json';
}
export function getRelativePathToRootTsConfig(
tree: Tree,
targetPath: string
): string {
return offsetFromRoot(targetPath) + getRootTsConfigPathInTree(tree);
}
export function getRootTsConfigFileName(): string | null {
for (const tsConfigName of ['tsconfig.base.json', 'tsconfig.json']) {
const tsConfigPath = join(workspaceRoot, tsConfigName);
if (existsSync(tsConfigPath)) {
return tsConfigName;
}
}
return null;
}
export function getRootTsConfigPath(): string | null {
const tsConfigFileName = getRootTsConfigFileName();
return tsConfigFileName ? join(workspaceRoot, tsConfigFileName) : null;
}
export function updateRootTsConfig(
host: Tree,
options: {
name: string;
importPath?: string;
projectRoot: string;
js?: boolean;
}
) {
if (!options.importPath) {
throw new Error(
`Unable to update ${options.name} using the import path "${options.importPath}". Make sure to specify a valid import path one.`
);
}
updateJson(host, getRootTsConfigPathInTree(host), (json) => {
const c = json.compilerOptions;
c.paths = c.paths || {};
delete c.paths[options.name];
if (c.paths[options.importPath]) {
throw new Error(
`You already have a library using the import path "${options.importPath}". Make sure to specify a unique one.`
);
}
c.paths[options.importPath] = [
joinPathFragments(
options.projectRoot,
'./src',
'index.' + (options.js ? 'js' : 'ts')
),
];
return json;
});
}

View File

@ -6,3 +6,4 @@ export const esbuildVersion = '^0.17.5';
export const swcCliVersion = '~0.1.55';
export const swcHelpersVersion = '~0.4.11';
export const typesNodeVersion = '18.7.1';
export const typescriptVersion = '~4.8.2';

View File

@ -34,6 +34,7 @@
},
"dependencies": {
"@nrwl/devkit": "file:../devkit",
"@nrwl/js": "file:../js",
"@phenomnomnominal/tsquery": "4.1.1",
"tmp": "~0.2.1",
"tslib": "^2.3.0"

View File

@ -13,7 +13,7 @@ import {
updateJson,
updateNxJson,
} from '@nrwl/devkit';
import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript';
import { getRelativePathToRootTsConfig } from '@nrwl/js';
import { join } from 'path';
import { workspaceLintPluginDir } from '../../utils/workspace-lint-rules';
import { swcCoreVersion, swcNodeVersion } from 'nx/src/utils/versions';
@ -24,7 +24,7 @@ export const WORKSPACE_RULES_PROJECT_NAME = 'eslint-rules';
export const WORKSPACE_PLUGIN_DIR = 'tools/eslint-rules';
export async function lintWorkspaceRulesProjectGenerator(tree: Tree) {
await ensurePackage(tree, '@nrwl/jest/', nxVersion);
ensurePackage(tree, '@nrwl/jest/', nxVersion);
const { addPropertyToJestConfig, jestProjectGenerator } = await import(
'@nrwl/jest'
);

View File

@ -10,7 +10,7 @@ import { nxVersion } from '../../utils/versions';
export default async function eslint8Updates(tree: Tree) {
try {
await ensurePackage(tree, '@nrwl/jest/', nxVersion);
ensurePackage(tree, '@nrwl/jest/', nxVersion);
const { addPropertyToJestConfig } = await import('@nrwl/jest');
const existingJestConfigPath = normalizePath(
'tools/eslint-rules/jest.config.js'

View File

@ -3,19 +3,23 @@ import {
addGlobal,
removeChange,
} from '@nrwl/workspace/src/utilities/ast-utils';
import * as ts from 'typescript';
import type { NormalizedOptions } from '../schema';
let tsModule: typeof import('typescript');
export function addExportsToBarrelFile(
tree: Tree,
options: NormalizedOptions
): void {
if (!tsModule) {
tsModule = require('typescript');
}
const indexPath = `${options.projectRoot}/src/index.ts`;
const indexContent = tree.read(indexPath, 'utf-8');
let sourceFile = ts.createSourceFile(
let sourceFile = tsModule.createSourceFile(
indexPath,
indexContent,
ts.ScriptTarget.Latest,
tsModule.ScriptTarget.Latest,
true
);

View File

@ -1,7 +1,6 @@
import type { GeneratorCallback, Tree } from '@nrwl/devkit';
import { convertNxGenerator, formatFiles } from '@nrwl/devkit';
import { libraryGenerator as jsLibraryGenerator } from '@nrwl/js';
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
import { addDependencies } from '../init/lib';
import {
addExportsToBarrelFile,
@ -19,10 +18,7 @@ export async function libraryGenerator(
rawOptions: LibraryGeneratorOptions
): Promise<GeneratorCallback> {
const options = normalizeOptions(tree, rawOptions);
const jsLibraryTask = await jsLibraryGenerator(
tree,
toJsLibraryGeneratorOptions(options)
);
await jsLibraryGenerator(tree, toJsLibraryGeneratorOptions(options));
const installDepsTask = addDependencies(tree);
deleteFiles(tree, options);
createFiles(tree, options);
@ -34,7 +30,7 @@ export async function libraryGenerator(
await formatFiles(tree);
}
return runTasksInSerial(jsLibraryTask, installDepsTask);
return installDepsTask;
}
export default libraryGenerator;

View File

@ -6,7 +6,10 @@ import {
Tree,
updateJson,
} from '@nrwl/devkit';
import { extendReactEslintJson, extraEslintDependencies } from '@nrwl/react';
import {
extendReactEslintJson,
extraEslintDependencies,
} from '@nrwl/react/src/utils/lint';
import { NormalizedSchema } from './normalize-options';
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';

View File

@ -1,11 +1,12 @@
import { join } from 'path';
import { generateFiles, names, toJS, Tree } from '@nrwl/devkit';
import { getRelativePathToRootTsConfig } from '@nrwl/js';
import { NormalizedSchema } from './normalize-options';
import {
createAppJsx,
createStyleRules,
} from './create-application-files.helpers';
import { generateFiles, names, toJS, Tree } from '@nrwl/devkit';
import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript';
export function createApplicationFiles(host: Tree, options: NormalizedSchema) {
const templateVariables = {

Some files were not shown because too many files have changed in this diff Show More