feat(core): move tsconfig.base.json to @nrwl/js:init (#14467)
This commit is contained in:
parent
f913b905a1
commit
a97212b601
@ -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`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -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`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -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": [],
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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"],
|
||||
|
||||
@ -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": []
|
||||
|
||||
@ -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).",
|
||||
|
||||
228
e2e/workspace-create/src/create-nx-workspace-npm.test.ts
Normal file
228
e2e/workspace-create/src/create-nx-workspace-npm.test.ts
Normal 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');
|
||||
});
|
||||
});
|
||||
@ -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', () => {
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
);
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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'
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
);
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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 */');
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 =
|
||||
|
||||
@ -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 =
|
||||
|
||||
@ -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,
|
||||
});
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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> {
|
||||
|
||||
@ -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> {
|
||||
|
||||
@ -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])';
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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
|
||||
);
|
||||
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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
|
||||
);
|
||||
|
||||
|
||||
@ -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
|
||||
);
|
||||
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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
|
||||
);
|
||||
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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';
|
||||
|
||||
|
||||
@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
@ -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 =
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -3,4 +3,5 @@ export interface Schema {
|
||||
skipFormat?: boolean;
|
||||
e2eTestRunner?: 'detox' | 'none';
|
||||
skipPackageJson?: boolean; // default is false
|
||||
js?: boolean;
|
||||
}
|
||||
|
||||
@ -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": []
|
||||
|
||||
@ -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';
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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.`
|
||||
);
|
||||
|
||||
@ -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": {
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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);
|
||||
|
||||
4
packages/js/src/generators/init/schema.d.ts
vendored
Normal file
4
packages/js/src/generators/init/schema.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
export interface InitSchema {
|
||||
js?: boolean;
|
||||
skipFormat?: boolean;
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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';
|
||||
|
||||
|
||||
2
packages/js/src/utils/schema.d.ts
vendored
2
packages/js/src/utils/schema.d.ts
vendored
@ -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,
|
||||
|
||||
@ -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[];
|
||||
|
||||
97
packages/js/src/utils/typescript/ts-config.ts
Normal file
97
packages/js/src/utils/typescript/ts-config.ts
Normal 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;
|
||||
});
|
||||
}
|
||||
@ -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';
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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'
|
||||
);
|
||||
|
||||
@ -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'
|
||||
|
||||
@ -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
|
||||
);
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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';
|
||||
|
||||
|
||||
@ -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
Loading…
x
Reference in New Issue
Block a user