feat(angular): support angular v14.0.0-rc.2 (#8883)
This commit is contained in:
parent
daddcde73c
commit
62afcb79b0
@ -299,6 +299,11 @@
|
|||||||
"default": false,
|
"default": false,
|
||||||
"alias": "t"
|
"alias": "t"
|
||||||
},
|
},
|
||||||
|
"standalone": {
|
||||||
|
"description": "Whether the generated component is standalone.",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
"viewEncapsulation": {
|
"viewEncapsulation": {
|
||||||
"description": "The view encapsulation strategy to use in the new component.",
|
"description": "The view encapsulation strategy to use in the new component.",
|
||||||
"enum": ["Emulated", "None", "ShadowDom"],
|
"enum": ["Emulated", "None", "ShadowDom"],
|
||||||
@ -2304,7 +2309,8 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"input": {
|
"input": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The file to include."
|
"description": "The file to include.",
|
||||||
|
"pattern": "\\.[cm]?jsx?$"
|
||||||
},
|
},
|
||||||
"bundleName": {
|
"bundleName": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@ -2320,7 +2326,11 @@
|
|||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"required": ["input"]
|
"required": ["input"]
|
||||||
},
|
},
|
||||||
{ "type": "string", "description": "The file to include." }
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "The file to include.",
|
||||||
|
"pattern": "\\.[cm]?jsx?$"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2335,7 +2345,8 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"input": {
|
"input": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The file to include."
|
"description": "The file to include.",
|
||||||
|
"pattern": "\\.(?:css|scss|sass|less|styl)$"
|
||||||
},
|
},
|
||||||
"bundleName": {
|
"bundleName": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@ -2351,7 +2362,11 @@
|
|||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"required": ["input"]
|
"required": ["input"]
|
||||||
},
|
},
|
||||||
{ "type": "string", "description": "The file to include." }
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "The file to include.",
|
||||||
|
"pattern": "\\.(?:css|scss|sass|less|styl)$"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2606,15 +2621,9 @@
|
|||||||
"description": "Extract all licenses in a separate file.",
|
"description": "Extract all licenses in a separate file.",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
"showCircularDependencies": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Show circular dependency warnings on builds.",
|
|
||||||
"default": false,
|
|
||||||
"x-deprecated": "The recommended method to detect circular dependencies in project code is to use either a lint rule or other external tooling."
|
|
||||||
},
|
|
||||||
"buildOptimizer": {
|
"buildOptimizer": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Enables '@angular-devkit/build-optimizer' optimizations when using the 'aot' option.",
|
"description": "Enables advanced build optimizations when using the 'aot' option.",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
"namedChunks": {
|
"namedChunks": {
|
||||||
@ -2829,32 +2838,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"extraEntryPoint": {
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"input": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The file to include."
|
|
||||||
},
|
|
||||||
"bundleName": {
|
|
||||||
"type": "string",
|
|
||||||
"pattern": "^[\\w\\-.]*$",
|
|
||||||
"description": "The bundle name for this extra entry point."
|
|
||||||
},
|
|
||||||
"inject": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "If the bundle will be referenced in the HTML file.",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false,
|
|
||||||
"required": ["input"]
|
|
||||||
},
|
|
||||||
{ "type": "string", "description": "The file to include." }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"budget": {
|
"budget": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
@ -85,13 +85,13 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
|
|||||||
updateFile('tsconfig.json', JSON.stringify(tsConfig, null, 2));
|
updateFile('tsconfig.json', JSON.stringify(tsConfig, null, 2));
|
||||||
|
|
||||||
// add an extra script file
|
// add an extra script file
|
||||||
updateFile('src/scripts.ts', 'const x = 1;');
|
updateFile('src/scripts.js', 'const x = 1;');
|
||||||
|
|
||||||
// update angular.json
|
// update angular.json
|
||||||
const angularJson = readJson('angular.json');
|
const angularJson = readJson('angular.json');
|
||||||
angularJson.projects[project].architect.build.options.scripts =
|
angularJson.projects[project].architect.build.options.scripts =
|
||||||
angularJson.projects[project].architect.test.options.scripts = [
|
angularJson.projects[project].architect.test.options.scripts = [
|
||||||
'src/scripts.ts',
|
'src/scripts.js',
|
||||||
];
|
];
|
||||||
angularJson.projects[project].architect.test.options.styles = [
|
angularJson.projects[project].architect.test.options.styles = [
|
||||||
'src/styles.css',
|
'src/styles.css',
|
||||||
@ -144,7 +144,6 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
|
|||||||
defaultCollection: '@nrwl/angular',
|
defaultCollection: '@nrwl/angular',
|
||||||
packageManager: packageManager,
|
packageManager: packageManager,
|
||||||
},
|
},
|
||||||
defaultProject: project,
|
|
||||||
implicitDependencies: {
|
implicitDependencies: {
|
||||||
'.eslintrc.json': '*',
|
'.eslintrc.json': '*',
|
||||||
'package.json': {
|
'package.json': {
|
||||||
@ -196,7 +195,7 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
|
|||||||
`apps/${project}/src/assets`,
|
`apps/${project}/src/assets`,
|
||||||
],
|
],
|
||||||
styles: [`apps/${project}/src/styles.css`],
|
styles: [`apps/${project}/src/styles.css`],
|
||||||
scripts: [`apps/${project}/src/scripts.ts`],
|
scripts: [`apps/${project}/src/scripts.js`],
|
||||||
},
|
},
|
||||||
configurations: {
|
configurations: {
|
||||||
production: {
|
production: {
|
||||||
@ -251,7 +250,7 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
|
|||||||
`apps/${project}/src/assets`,
|
`apps/${project}/src/assets`,
|
||||||
],
|
],
|
||||||
styles: [`apps/${project}/src/styles.css`],
|
styles: [`apps/${project}/src/styles.css`],
|
||||||
scripts: [`apps/${project}/src/scripts.ts`],
|
scripts: [`apps/${project}/src/scripts.js`],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
expect(projectConfig.targets.e2e).toBeUndefined();
|
expect(projectConfig.targets.e2e).toBeUndefined();
|
||||||
@ -271,7 +270,7 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
runCLI('build --configuration production --outputHashing none');
|
runCLI(`build ${project} --configuration production --outputHashing none`);
|
||||||
checkFilesExist(`dist/apps/${project}/main.js`);
|
checkFilesExist(`dist/apps/${project}/main.js`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -193,44 +193,9 @@ describe('Angular Projects', () => {
|
|||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/angular:library ${childLib} --publishable=true --importPath=@${proj}/${childLib} --no-interactive`
|
`generate @nrwl/angular:library ${childLib} --publishable=true --importPath=@${proj}/${childLib} --no-interactive`
|
||||||
);
|
);
|
||||||
|
runCLI(
|
||||||
// create secondary entrypoint
|
`generate @nrwl/angular:secondary-entry-point --name=sub --library=${childLib} --no-interactive`
|
||||||
updateFile(
|
|
||||||
`libs/${childLib}/sub/package.json`,
|
|
||||||
`
|
|
||||||
{
|
|
||||||
"ngPackage": {}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
);
|
);
|
||||||
updateFile(
|
|
||||||
`libs/${childLib}/sub/src/lib/sub.module.ts`,
|
|
||||||
`
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
@NgModule({ imports: [CommonModule] })
|
|
||||||
export class SubModule {}
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`libs/${childLib}/sub/src/public_api.ts`,
|
|
||||||
`export * from './lib/sub.module';`
|
|
||||||
);
|
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`libs/${childLib}/sub/src/index.ts`,
|
|
||||||
`export * from './public_api';`
|
|
||||||
);
|
|
||||||
|
|
||||||
updateFile(`tsconfig.base.json`, (s) => {
|
|
||||||
return s.replace(
|
|
||||||
`"@${proj}/${childLib}": ["libs/${childLib}/src/index.ts"],`,
|
|
||||||
`"@${proj}/${childLib}": ["libs/${childLib}/src/index.ts"],
|
|
||||||
"@${proj}/${childLib}/sub": ["libs/${childLib}/sub/src/index.ts"],
|
|
||||||
`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const moduleContent = `
|
const moduleContent = `
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
|
|||||||
@ -260,14 +260,10 @@ export function runNgNew(
|
|||||||
): string {
|
): string {
|
||||||
projName = projectName;
|
projName = projectName;
|
||||||
|
|
||||||
// Use the latest version of the currently supported @angular/cli major version
|
|
||||||
// to cover existing usage out there while avoiding the tests to fail when a new
|
|
||||||
// major comes out and is still not supported
|
|
||||||
const ngCliMajorVersion = coerce(angularCliVersion).major;
|
|
||||||
const npmMajorVersion = getNpmMajorVersion();
|
const npmMajorVersion = getNpmMajorVersion();
|
||||||
const command = `npx ${
|
const command = `npx ${
|
||||||
+npmMajorVersion >= 7 ? '--yes' : ''
|
+npmMajorVersion >= 7 ? '--yes' : ''
|
||||||
} @angular/cli@${ngCliMajorVersion} new ${projectName} --package-manager=${packageManager}`;
|
} @angular/cli@${angularCliVersion} new ${projectName} --package-manager=${packageManager}`;
|
||||||
|
|
||||||
return execSync(command, {
|
return execSync(command, {
|
||||||
cwd: e2eCwd,
|
cwd: e2eCwd,
|
||||||
|
|||||||
@ -469,7 +469,6 @@ describe('Move Angular Project', () => {
|
|||||||
expect(moveOutput).toContain(
|
expect(moveOutput).toContain(
|
||||||
`CREATE apps/${newPath}/src/environments/environment.ts`
|
`CREATE apps/${newPath}/src/environments/environment.ts`
|
||||||
);
|
);
|
||||||
expect(moveOutput).toContain(`UPDATE nx.json`);
|
|
||||||
expect(moveOutput).toContain(`UPDATE workspace.json`);
|
expect(moveOutput).toContain(`UPDATE workspace.json`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
65
package.json
65
package.json
@ -25,24 +25,24 @@
|
|||||||
"prepare": "is-ci || husky install"
|
"prepare": "is-ci || husky install"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/architect": "~0.1303.0",
|
"@angular-devkit/architect": "~0.1400.0-rc.2",
|
||||||
"@angular-devkit/build-angular": "~13.3.0",
|
"@angular-devkit/build-angular": "~14.0.0-rc.2",
|
||||||
"@angular-devkit/core": "~13.3.0",
|
"@angular-devkit/core": "~14.0.0-rc.2",
|
||||||
"@angular-devkit/schematics": "~13.3.0",
|
"@angular-devkit/schematics": "~14.0.0-rc.2",
|
||||||
"@angular-eslint/eslint-plugin": "~13.1.0",
|
"@angular-eslint/eslint-plugin": "~13.2.1",
|
||||||
"@angular-eslint/eslint-plugin-template": "~13.1.0",
|
"@angular-eslint/eslint-plugin-template": "~13.2.1",
|
||||||
"@angular-eslint/template-parser": "~13.1.0",
|
"@angular-eslint/template-parser": "~13.2.1",
|
||||||
"@angular/cli": "~13.3.0",
|
"@angular/cli": "~14.0.0-rc.2",
|
||||||
"@angular/common": "~13.3.0",
|
"@angular/common": "~14.0.0-rc.2",
|
||||||
"@angular/compiler": "~13.3.0",
|
"@angular/compiler": "~14.0.0-rc.2",
|
||||||
"@angular/compiler-cli": "~13.3.0",
|
"@angular/compiler-cli": "~14.0.0-rc.2",
|
||||||
"@angular/core": "~13.3.0",
|
"@angular/core": "~14.0.0-rc.2",
|
||||||
"@angular/forms": "~13.3.0",
|
"@angular/forms": "~14.0.0-rc.2",
|
||||||
"@angular/platform-browser": "~13.3.0",
|
"@angular/platform-browser": "~14.0.0-rc.2",
|
||||||
"@angular/platform-browser-dynamic": "~13.3.0",
|
"@angular/platform-browser-dynamic": "~14.0.0-rc.2",
|
||||||
"@angular/router": "~13.3.0",
|
"@angular/router": "~14.0.0-rc.2",
|
||||||
"@angular/service-worker": "~13.3.0",
|
"@angular/service-worker": "~14.0.0-rc.2",
|
||||||
"@angular/upgrade": "~13.3.0",
|
"@angular/upgrade": "~14.0.0-rc.2",
|
||||||
"@babel/helper-create-regexp-features-plugin": "^7.14.5",
|
"@babel/helper-create-regexp-features-plugin": "^7.14.5",
|
||||||
"@cypress/webpack-preprocessor": "^5.9.1",
|
"@cypress/webpack-preprocessor": "^5.9.1",
|
||||||
"@nestjs/common": "^8.0.0",
|
"@nestjs/common": "^8.0.0",
|
||||||
@ -51,13 +51,13 @@
|
|||||||
"@nestjs/schematics": "^8.0.0",
|
"@nestjs/schematics": "^8.0.0",
|
||||||
"@nestjs/swagger": "^5.0.9",
|
"@nestjs/swagger": "^5.0.9",
|
||||||
"@nestjs/testing": "^8.0.0",
|
"@nestjs/testing": "^8.0.0",
|
||||||
"@ngrx/component-store": "~13.0.0",
|
"@ngrx/component-store": "~13.2.0",
|
||||||
"@ngrx/effects": "~13.0.0",
|
"@ngrx/effects": "~13.2.0",
|
||||||
"@ngrx/entity": "~13.0.0",
|
"@ngrx/entity": "~13.2.0",
|
||||||
"@ngrx/router-store": "~13.0.0",
|
"@ngrx/router-store": "~13.2.0",
|
||||||
"@ngrx/schematics": "~13.0.0",
|
"@ngrx/schematics": "~13.2.0",
|
||||||
"@ngrx/store": "~13.0.0",
|
"@ngrx/store": "~13.2.0",
|
||||||
"@ngrx/store-devtools": "~13.0.0",
|
"@ngrx/store-devtools": "~13.2.0",
|
||||||
"@nrwl/eslint-plugin-nx": "14.1.9-beta.1",
|
"@nrwl/eslint-plugin-nx": "14.1.9-beta.1",
|
||||||
"@nrwl/jest": "14.1.9-beta.1",
|
"@nrwl/jest": "14.1.9-beta.1",
|
||||||
"@nrwl/next": "14.1.9-beta.1",
|
"@nrwl/next": "14.1.9-beta.1",
|
||||||
@ -74,7 +74,7 @@
|
|||||||
"@rollup/plugin-image": "^2.1.0",
|
"@rollup/plugin-image": "^2.1.0",
|
||||||
"@rollup/plugin-json": "^4.1.0",
|
"@rollup/plugin-json": "^4.1.0",
|
||||||
"@rollup/plugin-node-resolve": "^13.0.4",
|
"@rollup/plugin-node-resolve": "^13.0.4",
|
||||||
"@schematics/angular": "~13.3.0",
|
"@schematics/angular": "~14.0.0-rc.2",
|
||||||
"@storybook/addon-essentials": "~6.5.4",
|
"@storybook/addon-essentials": "~6.5.4",
|
||||||
"@storybook/addon-knobs": "~6.3.0",
|
"@storybook/addon-knobs": "~6.3.0",
|
||||||
"@storybook/angular": "~6.5.4",
|
"@storybook/angular": "~6.5.4",
|
||||||
@ -107,9 +107,9 @@
|
|||||||
"@types/tar-stream": "^2.2.2",
|
"@types/tar-stream": "^2.2.2",
|
||||||
"@types/tmp": "^0.2.0",
|
"@types/tmp": "^0.2.0",
|
||||||
"@types/yargs": "^17.0.10",
|
"@types/yargs": "^17.0.10",
|
||||||
"@typescript-eslint/eslint-plugin": "5.18.0",
|
"@typescript-eslint/eslint-plugin": "~5.24.0",
|
||||||
"@typescript-eslint/experimental-utils": "5.18.0",
|
"@typescript-eslint/experimental-utils": "~5.24.0",
|
||||||
"@typescript-eslint/parser": "5.18.0",
|
"@typescript-eslint/parser": "~5.24.0",
|
||||||
"@xstate/immer": "^0.2.0",
|
"@xstate/immer": "^0.2.0",
|
||||||
"@xstate/inspect": "^0.5.1",
|
"@xstate/inspect": "^0.5.1",
|
||||||
"@xstate/react": "^1.6.3",
|
"@xstate/react": "^1.6.3",
|
||||||
@ -135,7 +135,7 @@
|
|||||||
"dotenv": "~10.0.0",
|
"dotenv": "~10.0.0",
|
||||||
"ejs": "^3.1.7",
|
"ejs": "^3.1.7",
|
||||||
"enhanced-resolve": "^5.8.3",
|
"enhanced-resolve": "^5.8.3",
|
||||||
"eslint": "8.12.0",
|
"eslint": "8.15.0",
|
||||||
"eslint-config-next": "12.1.5",
|
"eslint-config-next": "12.1.5",
|
||||||
"eslint-config-prettier": "^8.1.0",
|
"eslint-config-prettier": "^8.1.0",
|
||||||
"eslint-plugin-cypress": "^2.10.3",
|
"eslint-plugin-cypress": "^2.10.3",
|
||||||
@ -164,7 +164,7 @@
|
|||||||
"jasmine-spec-reporter": "~4.2.1",
|
"jasmine-spec-reporter": "~4.2.1",
|
||||||
"jest": "27.5.1",
|
"jest": "27.5.1",
|
||||||
"jest-circus": "27.2.3",
|
"jest-circus": "27.2.3",
|
||||||
"jest-preset-angular": "11.1.1",
|
"jest-preset-angular": "~11.1.2",
|
||||||
"jsonc-eslint-parser": "^2.1.0",
|
"jsonc-eslint-parser": "^2.1.0",
|
||||||
"jsonc-parser": "3.0.0",
|
"jsonc-parser": "3.0.0",
|
||||||
"karma": "~4.0.0",
|
"karma": "~4.0.0",
|
||||||
@ -185,7 +185,7 @@
|
|||||||
"mini-css-extract-plugin": "~2.4.7",
|
"mini-css-extract-plugin": "~2.4.7",
|
||||||
"minimatch": "3.0.5",
|
"minimatch": "3.0.5",
|
||||||
"next-sitemap": "^1.6.108",
|
"next-sitemap": "^1.6.108",
|
||||||
"ng-packagr": "~13.3.0",
|
"ng-packagr": "~14.0.0-rc.0",
|
||||||
"ngrx-store-freeze": "0.2.4",
|
"ngrx-store-freeze": "0.2.4",
|
||||||
"node-fetch": "^2.6.7",
|
"node-fetch": "^2.6.7",
|
||||||
"nx": "14.1.9-beta.1",
|
"nx": "14.1.9-beta.1",
|
||||||
@ -301,7 +301,6 @@
|
|||||||
"weak-napi": "^2.0.2"
|
"weak-napi": "^2.0.2"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"ng-packagr/rxjs": "6.6.7",
|
|
||||||
"**/xmlhttprequest-ssl": "~1.6.2",
|
"**/xmlhttprequest-ssl": "~1.6.2",
|
||||||
"minimist": "^1.2.6"
|
"minimist": "^1.2.6"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -112,6 +112,36 @@
|
|||||||
"version": "14.0.0-beta.1",
|
"version": "14.0.0-beta.1",
|
||||||
"description": "Rename mfe.config.js to module-federation.config.js for consistent terminology.",
|
"description": "Rename mfe.config.js to module-federation.config.js for consistent terminology.",
|
||||||
"factory": "./src/migrations/update-14-0-0/rename-mf-config"
|
"factory": "./src/migrations/update-14-0-0/rename-mf-config"
|
||||||
|
},
|
||||||
|
"remove-show-circular-dependencies-option": {
|
||||||
|
"cli": "nx",
|
||||||
|
"version": "14.2.0-beta.0",
|
||||||
|
"description": "Remove 'showCircularDependencies' option from browser and server executors.",
|
||||||
|
"factory": "./src/migrations/update-14-2-0/remove-show-circular-dependencies-option"
|
||||||
|
},
|
||||||
|
"update-angular-cli-version": {
|
||||||
|
"cli": "nx",
|
||||||
|
"version": "14.2.0-beta.0",
|
||||||
|
"description": "Update the @angular/cli package version.",
|
||||||
|
"factory": "./src/migrations/update-14-2-0/update-angular-cli"
|
||||||
|
},
|
||||||
|
"update-libraries-secondary-entrypoints": {
|
||||||
|
"cli": "nx",
|
||||||
|
"version": "14.2.0-beta.0",
|
||||||
|
"description": "Remove 'package.json' files from library projects secondary entrypoints.",
|
||||||
|
"factory": "./src/migrations/update-14-2-0/update-libraries-secondary-entrypoints"
|
||||||
|
},
|
||||||
|
"update-postinstall-script-ngcc-target": {
|
||||||
|
"cli": "nx",
|
||||||
|
"version": "14.2.0-beta.0",
|
||||||
|
"description": "Update postinstall script running ngcc to use ES2020 target.",
|
||||||
|
"factory": "./src/migrations/update-14-2-0/update-ngcc-target"
|
||||||
|
},
|
||||||
|
"update-tsconfig-target": {
|
||||||
|
"cli": "nx",
|
||||||
|
"version": "14.2.0-beta.0",
|
||||||
|
"description": "Update TypeScript compilation target to 'ES2020'.",
|
||||||
|
"factory": "./src/migrations/update-14-2-0/update-tsconfig-target"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packageJsonUpdates": {
|
"packageJsonUpdates": {
|
||||||
@ -1088,6 +1118,87 @@
|
|||||||
"alwaysAddToPackageJson": false
|
"alwaysAddToPackageJson": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"14.2.0": {
|
||||||
|
"version": "14.2.0-beta.0",
|
||||||
|
"packages": {
|
||||||
|
"@angular-devkit/architect": {
|
||||||
|
"version": "~0.1400.0-rc.2",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"@angular-devkit/build-angular": {
|
||||||
|
"version": "~14.0.0-rc.2",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"@angular-devkit/build-webpack": {
|
||||||
|
"version": "~0.1400.0-rc.2",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"@angular-devkit/core": {
|
||||||
|
"version": "~14.0.0-rc.2",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"@angular-devkit/schematics": {
|
||||||
|
"version": "~14.0.0-rc.2",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"@angular/core": {
|
||||||
|
"version": "~14.0.0-rc.2",
|
||||||
|
"alwaysAddToPackageJson": true
|
||||||
|
},
|
||||||
|
"@angular/material": {
|
||||||
|
"version": "~14.0.0-rc.1",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"ng-packagr": {
|
||||||
|
"version": "~14.0.0-rc.0",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"@angular-eslint/eslint-plugin": {
|
||||||
|
"version": "~13.2.1",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"@angular-eslint/eslint-plugin-template": {
|
||||||
|
"version": "~13.2.1",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"@angular-eslint/template-parser": {
|
||||||
|
"version": "~13.2.1",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"@ngrx/store": {
|
||||||
|
"version": "~13.2.0",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"@ngrx/effects": {
|
||||||
|
"version": "~13.2.0",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"@ngrx/entity": {
|
||||||
|
"version": "~13.2.0",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"@ngrx/router-store": {
|
||||||
|
"version": "~13.2.0",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"@ngrx/schematics": {
|
||||||
|
"version": "~13.2.0",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"@ngrx/store-devtools": {
|
||||||
|
"version": "~13.2.0",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"@ngrx/component-store": {
|
||||||
|
"version": "~13.2.0",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
},
|
||||||
|
"jest-preset-angular": {
|
||||||
|
"version": "~11.1.2",
|
||||||
|
"alwaysAddToPackageJson": false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,7 +37,7 @@
|
|||||||
"migrations": "./migrations.json"
|
"migrations": "./migrations.json"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular-devkit/schematics": "~13.3.0",
|
"@angular-devkit/schematics": "~14.0.0-rc.2",
|
||||||
"@nrwl/cypress": "file:../cypress",
|
"@nrwl/cypress": "file:../cypress",
|
||||||
"@nrwl/devkit": "file:../devkit",
|
"@nrwl/devkit": "file:../devkit",
|
||||||
"@nrwl/jest": "file:../jest",
|
"@nrwl/jest": "file:../jest",
|
||||||
@ -45,7 +45,7 @@
|
|||||||
"@nrwl/storybook": "file:../storybook",
|
"@nrwl/storybook": "file:../storybook",
|
||||||
"@nrwl/workspace": "file:../workspace",
|
"@nrwl/workspace": "file:../workspace",
|
||||||
"@phenomnomnominal/tsquery": "4.1.1",
|
"@phenomnomnominal/tsquery": "4.1.1",
|
||||||
"@schematics/angular": "~13.3.0",
|
"@schematics/angular": "~14.0.0-rc.2",
|
||||||
"chalk": "4.1.0",
|
"chalk": "4.1.0",
|
||||||
"chokidar": "^3.5.1",
|
"chokidar": "^3.5.1",
|
||||||
"http-server": "^14.1.0",
|
"http-server": "^14.1.0",
|
||||||
|
|||||||
@ -47,7 +47,35 @@
|
|||||||
"type": "array",
|
"type": "array",
|
||||||
"default": [],
|
"default": [],
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/extraEntryPoint"
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"input": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The file to include.",
|
||||||
|
"pattern": "\\.[cm]?jsx?$"
|
||||||
|
},
|
||||||
|
"bundleName": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^[\\w\\-.]*$",
|
||||||
|
"description": "The bundle name for this extra entry point."
|
||||||
|
},
|
||||||
|
"inject": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "If the bundle will be referenced in the HTML file.",
|
||||||
|
"default": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["input"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "The file to include.",
|
||||||
|
"pattern": "\\.[cm]?jsx?$"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"styles": {
|
"styles": {
|
||||||
@ -55,7 +83,35 @@
|
|||||||
"type": "array",
|
"type": "array",
|
||||||
"default": [],
|
"default": [],
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/extraEntryPoint"
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"input": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The file to include.",
|
||||||
|
"pattern": "\\.(?:css|scss|sass|less|styl)$"
|
||||||
|
},
|
||||||
|
"bundleName": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^[\\w\\-.]*$",
|
||||||
|
"description": "The bundle name for this extra entry point."
|
||||||
|
},
|
||||||
|
"inject": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "If the bundle will be referenced in the HTML file.",
|
||||||
|
"default": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["input"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "The file to include.",
|
||||||
|
"pattern": "\\.(?:css|scss|sass|less|styl)$"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"inlineStyleLanguage": {
|
"inlineStyleLanguage": {
|
||||||
@ -291,15 +347,9 @@
|
|||||||
"description": "Extract all licenses in a separate file.",
|
"description": "Extract all licenses in a separate file.",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
"showCircularDependencies": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Show circular dependency warnings on builds.",
|
|
||||||
"default": false,
|
|
||||||
"x-deprecated": "The recommended method to detect circular dependencies in project code is to use either a lint rule or other external tooling."
|
|
||||||
},
|
|
||||||
"buildOptimizer": {
|
"buildOptimizer": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Enables '@angular-devkit/build-optimizer' optimizations when using the 'aot' option.",
|
"description": "Enables advanced build optimizations when using the 'aot' option.",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
"namedChunks": {
|
"namedChunks": {
|
||||||
@ -471,35 +521,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"extraEntryPoint": {
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"input": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The file to include."
|
|
||||||
},
|
|
||||||
"bundleName": {
|
|
||||||
"type": "string",
|
|
||||||
"pattern": "^[\\w\\-.]*$",
|
|
||||||
"description": "The bundle name for this extra entry point."
|
|
||||||
},
|
|
||||||
"inject": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "If the bundle will be referenced in the HTML file.",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false,
|
|
||||||
"required": ["input"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "The file to include."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"budget": {
|
"budget": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { logger } from '@nrwl/devkit';
|
import { logger } from '@nrwl/devkit';
|
||||||
|
import { BuildGraph } from 'ng-packagr/lib/graph/build-graph';
|
||||||
import { Node } from 'ng-packagr/lib/graph/node';
|
import { Node } from 'ng-packagr/lib/graph/node';
|
||||||
import { transformFromPromise } from 'ng-packagr/lib/graph/transform';
|
import { transformFromPromise } from 'ng-packagr/lib/graph/transform';
|
||||||
import { NgEntryPoint } from 'ng-packagr/lib/ng-package/entry-point/entry-point';
|
import { NgEntryPoint } from 'ng-packagr/lib/ng-package/entry-point/entry-point';
|
||||||
@ -22,6 +23,7 @@ import { NgPackage } from 'ng-packagr/lib/ng-package/package';
|
|||||||
import { copyFile, rmdir, stat, writeFile } from 'ng-packagr/lib/utils/fs';
|
import { copyFile, rmdir, stat, writeFile } from 'ng-packagr/lib/utils/fs';
|
||||||
import { globFiles } from 'ng-packagr/lib/utils/glob';
|
import { globFiles } from 'ng-packagr/lib/utils/glob';
|
||||||
import { ensureUnixPath } from 'ng-packagr/lib/utils/path';
|
import { ensureUnixPath } from 'ng-packagr/lib/utils/path';
|
||||||
|
import { AssetPattern } from 'ng-packagr/ng-package.schema';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
export const nxWritePackageTransform = (options: NgPackagrOptions) =>
|
export const nxWritePackageTransform = (options: NgPackagrOptions) =>
|
||||||
@ -31,69 +33,22 @@ export const nxWritePackageTransform = (options: NgPackagrOptions) =>
|
|||||||
const ngPackageNode: PackageNode = graph.find(isPackage);
|
const ngPackageNode: PackageNode = graph.find(isPackage);
|
||||||
const ngPackage = ngPackageNode.data;
|
const ngPackage = ngPackageNode.data;
|
||||||
const { destinationFiles } = entryPoint.data;
|
const { destinationFiles } = entryPoint.data;
|
||||||
const ignorePaths: string[] = [
|
|
||||||
'.gitkeep',
|
|
||||||
'**/.DS_Store',
|
|
||||||
'**/Thumbs.db',
|
|
||||||
'**/node_modules/**',
|
|
||||||
`${ngPackage.dest}/**`,
|
|
||||||
];
|
|
||||||
|
|
||||||
if (!ngEntryPoint.isSecondaryEntryPoint) {
|
if (!ngEntryPoint.isSecondaryEntryPoint) {
|
||||||
const assetFiles: string[] = [];
|
|
||||||
|
|
||||||
// COPY ASSET FILES TO DESTINATION
|
|
||||||
logger.log('Copying assets');
|
logger.log('Copying assets');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (const asset of ngPackage.assets) {
|
await copyAssets(graph, entryPoint, ngPackageNode);
|
||||||
let assetFullPath = path.join(ngPackage.src, asset);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const stats = await stat(assetFullPath);
|
|
||||||
if (stats.isFile()) {
|
|
||||||
assetFiles.push(assetFullPath);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stats.isDirectory()) {
|
|
||||||
assetFullPath = path.join(assetFullPath, '**/*');
|
|
||||||
}
|
|
||||||
} catch {}
|
|
||||||
|
|
||||||
const files = await globFiles(assetFullPath, {
|
|
||||||
ignore: ignorePaths,
|
|
||||||
cache: ngPackageNode.cache.globCache,
|
|
||||||
dot: true,
|
|
||||||
nodir: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (files.length) {
|
|
||||||
assetFiles.push(...files);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const file of assetFiles) {
|
|
||||||
const relativePath = path.relative(ngPackage.src, file);
|
|
||||||
const destination = path.resolve(ngPackage.dest, relativePath);
|
|
||||||
const nodeUri = fileUrl(ensureUnixPath(file));
|
|
||||||
let node = graph.get(nodeUri);
|
|
||||||
if (!node) {
|
|
||||||
node = new Node(nodeUri);
|
|
||||||
graph.put(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
entryPoint.dependsOn(node);
|
|
||||||
await copyFile(file, destination);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. WRITE PACKAGE.JSON
|
// 6. WRITE PACKAGE.JSON
|
||||||
|
// As of APF 14 only the primary entrypoint has a package.json
|
||||||
|
if (!ngEntryPoint.isSecondaryEntryPoint) {
|
||||||
try {
|
try {
|
||||||
logger.info('Writing package metadata');
|
logger.info('Writing package manifest');
|
||||||
const relativeUnixFromDestPath = (filePath: string) =>
|
const relativeUnixFromDestPath = (filePath: string) =>
|
||||||
ensureUnixPath(path.relative(ngEntryPoint.destinationPath, filePath));
|
ensureUnixPath(path.relative(ngEntryPoint.destinationPath, filePath));
|
||||||
|
|
||||||
@ -113,11 +68,98 @@ export const nxWritePackageTransform = (options: NgPackagrOptions) =>
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
logger.info(`Built ${ngEntryPoint.moduleId}`);
|
logger.info(`Built ${ngEntryPoint.moduleId}`);
|
||||||
|
|
||||||
return graph;
|
return graph;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
type AssetEntry = Exclude<AssetPattern, string>;
|
||||||
|
|
||||||
|
async function copyAssets(
|
||||||
|
graph: BuildGraph,
|
||||||
|
entryPointNode: EntryPointNode,
|
||||||
|
ngPackageNode: PackageNode
|
||||||
|
): Promise<void> {
|
||||||
|
const ngPackage = ngPackageNode.data;
|
||||||
|
|
||||||
|
const globsForceIgnored: string[] = [
|
||||||
|
'.gitkeep',
|
||||||
|
'**/.DS_Store',
|
||||||
|
'**/Thumbs.db',
|
||||||
|
`${ngPackage.dest}/**`,
|
||||||
|
];
|
||||||
|
|
||||||
|
const assets: AssetEntry[] = [];
|
||||||
|
|
||||||
|
for (const item of ngPackage.assets) {
|
||||||
|
const asset: Partial<AssetEntry> = {};
|
||||||
|
if (typeof item == 'object') {
|
||||||
|
asset.glob = item.glob;
|
||||||
|
asset.input = path.join(ngPackage.src, item.input);
|
||||||
|
asset.output = path.join(ngPackage.dest, item.output);
|
||||||
|
asset.ignore = item.ignore;
|
||||||
|
} else {
|
||||||
|
const assetPath = item; // might be a glob
|
||||||
|
const assetFullPath = path.join(ngPackage.src, assetPath);
|
||||||
|
const [isDir, isFile] = await stat(assetFullPath)
|
||||||
|
.then((stats) => [stats.isDirectory(), stats.isFile()])
|
||||||
|
.catch(() => [false, false]);
|
||||||
|
if (isDir) {
|
||||||
|
asset.glob = '**/*';
|
||||||
|
asset.input = assetFullPath;
|
||||||
|
asset.output = path.join(ngPackage.dest, assetPath);
|
||||||
|
} else if (isFile) {
|
||||||
|
asset.glob = path.basename(assetFullPath); // filenames are their own glob
|
||||||
|
asset.input = path.dirname(assetFullPath);
|
||||||
|
asset.output = path.dirname(path.join(ngPackage.dest, assetPath));
|
||||||
|
} else {
|
||||||
|
asset.glob = assetPath;
|
||||||
|
asset.input = ngPackage.src;
|
||||||
|
asset.output = ngPackage.dest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const isAncestorPath = (target: string, datum: string) =>
|
||||||
|
path.relative(datum, target).startsWith('..');
|
||||||
|
if (isAncestorPath(asset.input, ngPackage.src)) {
|
||||||
|
throw new Error(
|
||||||
|
'Cannot read assets from a location outside of the project root.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (isAncestorPath(asset.output, ngPackage.dest)) {
|
||||||
|
throw new Error(
|
||||||
|
'Cannot write assets to a location outside of the output path.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
assets.push(asset as AssetEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const asset of assets) {
|
||||||
|
const filePaths = await globFiles(asset.glob, {
|
||||||
|
cwd: asset.input,
|
||||||
|
ignore: [...(asset.ignore ?? []), ...globsForceIgnored],
|
||||||
|
cache: ngPackageNode.cache.globCache,
|
||||||
|
dot: true,
|
||||||
|
nodir: true,
|
||||||
|
follow: asset.followSymlinks,
|
||||||
|
});
|
||||||
|
for (const filePath of filePaths) {
|
||||||
|
const fileSrcFullPath = path.join(asset.input, filePath);
|
||||||
|
const fileDestFullPath = path.join(asset.output, filePath);
|
||||||
|
const nodeUri = fileUrl(ensureUnixPath(fileSrcFullPath));
|
||||||
|
let node = graph.get(nodeUri);
|
||||||
|
if (!node) {
|
||||||
|
node = new Node(nodeUri);
|
||||||
|
graph.put(node);
|
||||||
|
}
|
||||||
|
entryPointNode.dependsOn(node);
|
||||||
|
await copyFile(fileSrcFullPath, fileDestFullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and writes a `package.json` file of the entry point used by the `node_module`
|
* Creates and writes a `package.json` file of the entry point used by the `node_module`
|
||||||
* resolution strategies.
|
* resolution strategies.
|
||||||
@ -146,7 +188,6 @@ async function writePackageJson(
|
|||||||
// version at least matches that of angular if we use require('tslib').version
|
// version at least matches that of angular if we use require('tslib').version
|
||||||
// it will get what installed and not the minimum version nor if it is a `~` or `^`
|
// it will get what installed and not the minimum version nor if it is a `~` or `^`
|
||||||
// this is only required for primary
|
// this is only required for primary
|
||||||
if (!entryPoint.isSecondaryEntryPoint) {
|
|
||||||
if (isWatchMode) {
|
if (isWatchMode) {
|
||||||
// Needed because of Webpack's 5 `cachemanagedpaths`
|
// Needed because of Webpack's 5 `cachemanagedpaths`
|
||||||
// https://github.com/angular/angular-cli/issues/20962
|
// https://github.com/angular/angular-cli/issues/20962
|
||||||
@ -181,7 +222,6 @@ async function writePackageJson(
|
|||||||
|
|
||||||
delete packageJson.peerDependencies.tslib;
|
delete packageJson.peerDependencies.tslib;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Verify non-peerDependencies as they can easily lead to duplicate installs or version conflicts
|
// Verify non-peerDependencies as they can easily lead to duplicate installs or version conflicts
|
||||||
// in the node_modules folder of an application
|
// in the node_modules folder of an application
|
||||||
|
|||||||
@ -12,12 +12,10 @@ import { BuildGraph } from 'ng-packagr/lib/graph/build-graph';
|
|||||||
import { Node } from 'ng-packagr/lib/graph/node';
|
import { Node } from 'ng-packagr/lib/graph/node';
|
||||||
import { EntryPointNode, fileUrl } from 'ng-packagr/lib/ng-package/nodes';
|
import { EntryPointNode, fileUrl } from 'ng-packagr/lib/ng-package/nodes';
|
||||||
import { ensureUnixPath } from 'ng-packagr/lib/utils/path';
|
import { ensureUnixPath } from 'ng-packagr/lib/utils/path';
|
||||||
|
import { NgPackageConfig } from 'ng-packagr/ng-package.schema';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
import {
|
import { StylesheetProcessor } from '../styles/stylesheet-processor';
|
||||||
InlineStyleLanguage,
|
|
||||||
StylesheetProcessor,
|
|
||||||
} from '../styles/stylesheet-processor';
|
|
||||||
|
|
||||||
export function cacheCompilerHost(
|
export function cacheCompilerHost(
|
||||||
graph: BuildGraph,
|
graph: BuildGraph,
|
||||||
@ -25,7 +23,7 @@ export function cacheCompilerHost(
|
|||||||
compilerOptions: CompilerOptions,
|
compilerOptions: CompilerOptions,
|
||||||
moduleResolutionCache: ts.ModuleResolutionCache,
|
moduleResolutionCache: ts.ModuleResolutionCache,
|
||||||
stylesheetProcessor?: StylesheetProcessor,
|
stylesheetProcessor?: StylesheetProcessor,
|
||||||
inlineStyleLanguage?: InlineStyleLanguage,
|
inlineStyleLanguage?: NgPackageConfig['inlineStyleLanguage'],
|
||||||
sourcesFileCache: FileCache = entryPoint.cache.sourcesFileCache
|
sourcesFileCache: FileCache = entryPoint.cache.sourcesFileCache
|
||||||
): CompilerHost {
|
): CompilerHost {
|
||||||
const compilerHost = ts.createIncrementalCompilerHost(compilerOptions);
|
const compilerHost = ts.createIncrementalCompilerHost(compilerOptions);
|
||||||
@ -47,6 +45,11 @@ export function cacheCompilerHost(
|
|||||||
entryPoint.dependsOn(node);
|
entryPoint.dependsOn(node);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const { flatModuleFile, entryFile } = entryPoint.data.entryPoint;
|
||||||
|
const flatModuleFileDtsFilename = `${flatModuleFile}.d.ts`;
|
||||||
|
const hasIndexEntryFile =
|
||||||
|
path.basename(entryFile.toLowerCase()) === 'index.ts';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...compilerHost,
|
...compilerHost,
|
||||||
|
|
||||||
@ -82,6 +85,18 @@ export function cacheCompilerHost(
|
|||||||
sourceFiles?: ReadonlyArray<ts.SourceFile>
|
sourceFiles?: ReadonlyArray<ts.SourceFile>
|
||||||
) => {
|
) => {
|
||||||
if (fileName.endsWith('.d.ts')) {
|
if (fileName.endsWith('.d.ts')) {
|
||||||
|
if (
|
||||||
|
hasIndexEntryFile &&
|
||||||
|
path.basename(fileName) === flatModuleFileDtsFilename
|
||||||
|
) {
|
||||||
|
// In case the entry file is index.ts, we should not emit the `d.ts` which are a re-export of the `index.ts`.
|
||||||
|
// Because it will cause a conflict.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rename file to index.d.ts so that TypeScript can resolve types without
|
||||||
|
// them needing to be referenced in the package.json manifest.
|
||||||
|
fileName = fileName.replace(flatModuleFileDtsFilename, 'index.d.ts');
|
||||||
sourceFiles.forEach((source) => {
|
sourceFiles.forEach((source) => {
|
||||||
const cache = sourcesFileCache.getOrCreate(source.fileName);
|
const cache = sourcesFileCache.getOrCreate(source.fileName);
|
||||||
if (!cache.declarationFileName) {
|
if (!cache.declarationFileName) {
|
||||||
|
|||||||
@ -17,7 +17,7 @@ import {
|
|||||||
saveCacheEntry,
|
saveCacheEntry,
|
||||||
} from 'ng-packagr/lib/utils/cache';
|
} from 'ng-packagr/lib/utils/cache';
|
||||||
import * as log from 'ng-packagr/lib/utils/log';
|
import * as log from 'ng-packagr/lib/utils/log';
|
||||||
import { dirname, extname, join, resolve } from 'path';
|
import { dirname, extname, join } from 'path';
|
||||||
import * as postcssPresetEnv from 'postcss-preset-env';
|
import * as postcssPresetEnv from 'postcss-preset-env';
|
||||||
import * as postcssUrl from 'postcss-url';
|
import * as postcssUrl from 'postcss-url';
|
||||||
import {
|
import {
|
||||||
@ -34,13 +34,6 @@ export enum CssUrl {
|
|||||||
none = 'none',
|
none = 'none',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum InlineStyleLanguage {
|
|
||||||
sass = 'sass',
|
|
||||||
scss = 'scss',
|
|
||||||
css = 'css',
|
|
||||||
less = 'less',
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Result {
|
export interface Result {
|
||||||
css: string;
|
css: string;
|
||||||
warnings: string[];
|
warnings: string[];
|
||||||
|
|||||||
@ -12,12 +12,10 @@ import { BuildGraph } from 'ng-packagr/lib/graph/build-graph';
|
|||||||
import { Node } from 'ng-packagr/lib/graph/node';
|
import { Node } from 'ng-packagr/lib/graph/node';
|
||||||
import { EntryPointNode, fileUrl } from 'ng-packagr/lib/ng-package/nodes';
|
import { EntryPointNode, fileUrl } from 'ng-packagr/lib/ng-package/nodes';
|
||||||
import { ensureUnixPath } from 'ng-packagr/lib/utils/path';
|
import { ensureUnixPath } from 'ng-packagr/lib/utils/path';
|
||||||
|
import { NgPackageConfig } from 'ng-packagr/ng-package.schema';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
import {
|
import { StylesheetProcessor } from '../styles/stylesheet-processor';
|
||||||
InlineStyleLanguage,
|
|
||||||
StylesheetProcessor,
|
|
||||||
} from '../styles/stylesheet-processor';
|
|
||||||
|
|
||||||
export function cacheCompilerHost(
|
export function cacheCompilerHost(
|
||||||
graph: BuildGraph,
|
graph: BuildGraph,
|
||||||
@ -25,7 +23,7 @@ export function cacheCompilerHost(
|
|||||||
compilerOptions: CompilerOptions,
|
compilerOptions: CompilerOptions,
|
||||||
moduleResolutionCache: ts.ModuleResolutionCache,
|
moduleResolutionCache: ts.ModuleResolutionCache,
|
||||||
stylesheetProcessor?: StylesheetProcessor,
|
stylesheetProcessor?: StylesheetProcessor,
|
||||||
inlineStyleLanguage?: InlineStyleLanguage,
|
inlineStyleLanguage?: NgPackageConfig['inlineStyleLanguage'],
|
||||||
sourcesFileCache: FileCache = entryPoint.cache.sourcesFileCache
|
sourcesFileCache: FileCache = entryPoint.cache.sourcesFileCache
|
||||||
): CompilerHost {
|
): CompilerHost {
|
||||||
const compilerHost = ts.createIncrementalCompilerHost(compilerOptions);
|
const compilerHost = ts.createIncrementalCompilerHost(compilerOptions);
|
||||||
@ -47,6 +45,11 @@ export function cacheCompilerHost(
|
|||||||
entryPoint.dependsOn(node);
|
entryPoint.dependsOn(node);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const { flatModuleFile, entryFile } = entryPoint.data.entryPoint;
|
||||||
|
const flatModuleFileDtsFilename = `${flatModuleFile}.d.ts`;
|
||||||
|
const hasIndexEntryFile =
|
||||||
|
path.basename(entryFile.toLowerCase()) === 'index.ts';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...compilerHost,
|
...compilerHost,
|
||||||
|
|
||||||
@ -82,6 +85,18 @@ export function cacheCompilerHost(
|
|||||||
sourceFiles?: ReadonlyArray<ts.SourceFile>
|
sourceFiles?: ReadonlyArray<ts.SourceFile>
|
||||||
) => {
|
) => {
|
||||||
if (fileName.endsWith('.d.ts')) {
|
if (fileName.endsWith('.d.ts')) {
|
||||||
|
if (
|
||||||
|
hasIndexEntryFile &&
|
||||||
|
path.basename(fileName) === flatModuleFileDtsFilename
|
||||||
|
) {
|
||||||
|
// In case the entry file is index.ts, we should not emit the `d.ts` which are a re-export of the `index.ts`.
|
||||||
|
// Because it will cause a conflict.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rename file to index.d.ts so that TypeScript can resolve types without
|
||||||
|
// them needing to be referenced in the package.json manifest.
|
||||||
|
fileName = fileName.replace(flatModuleFileDtsFilename, 'index.d.ts');
|
||||||
sourceFiles.forEach((source) => {
|
sourceFiles.forEach((source) => {
|
||||||
const cache = sourcesFileCache.getOrCreate(source.fileName);
|
const cache = sourcesFileCache.getOrCreate(source.fileName);
|
||||||
if (!cache.declarationFileName) {
|
if (!cache.declarationFileName) {
|
||||||
|
|||||||
@ -168,6 +168,7 @@ Object {
|
|||||||
exports[`app not nested should generate files 1`] = `
|
exports[`app not nested should generate files 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"angularCompilerOptions": Object {
|
"angularCompilerOptions": Object {
|
||||||
|
"enableI18nLegacyMessageIdFormat": false,
|
||||||
"strictInjectionParameters": true,
|
"strictInjectionParameters": true,
|
||||||
"strictInputAccessModifiers": true,
|
"strictInputAccessModifiers": true,
|
||||||
"strictTemplates": true,
|
"strictTemplates": true,
|
||||||
|
|||||||
@ -34,6 +34,7 @@ export function enableStrictTypeChecking(
|
|||||||
// update Angular Template Settings
|
// update Angular Template Settings
|
||||||
json.angularCompilerOptions = {
|
json.angularCompilerOptions = {
|
||||||
...(json.angularCompilerOptions ?? {}),
|
...(json.angularCompilerOptions ?? {}),
|
||||||
|
enableI18nLegacyMessageIdFormat: false,
|
||||||
strictInjectionParameters: true,
|
strictInjectionParameters: true,
|
||||||
strictInputAccessModifiers: true,
|
strictInputAccessModifiers: true,
|
||||||
strictTemplates: true,
|
strictTemplates: true,
|
||||||
|
|||||||
@ -25,12 +25,17 @@ function updateTsConfigOptions(host: Tree, options: NormalizedSchema) {
|
|||||||
compilerOptions: {
|
compilerOptions: {
|
||||||
...json.compilerOptions,
|
...json.compilerOptions,
|
||||||
outDir: `${offsetFromRoot(options.appProjectRoot)}dist/out-tsc`,
|
outDir: `${offsetFromRoot(options.appProjectRoot)}dist/out-tsc`,
|
||||||
target: 'ES2017',
|
|
||||||
},
|
},
|
||||||
exclude: [
|
exclude: [
|
||||||
...new Set([...(json.exclude || []), '**/*.test.ts', '**/*.spec.ts']),
|
...new Set([...(json.exclude || []), '**/*.test.ts', '**/*.spec.ts']),
|
||||||
],
|
],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// tsconfig.json
|
||||||
|
updateJson(host, `${options.appProjectRoot}/tsconfig.json`, (json) => ({
|
||||||
|
...json,
|
||||||
|
compilerOptions: { ...json.compilerOptions, target: 'es2020' },
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateAppAndE2EProjectConfigurations(
|
function updateAppAndE2EProjectConfigurations(
|
||||||
|
|||||||
@ -60,10 +60,6 @@ function exportComponent(tree: Tree, schema: Schema) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (projectType === 'application') {
|
if (projectType === 'application') {
|
||||||
logger.warn(
|
|
||||||
'--export=true was ignored as the project the component being generated in is not a library.'
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@ export interface Schema {
|
|||||||
displayBlock?: boolean;
|
displayBlock?: boolean;
|
||||||
inlineStyle?: boolean;
|
inlineStyle?: boolean;
|
||||||
inlineTemplate?: boolean;
|
inlineTemplate?: boolean;
|
||||||
|
standalone?: boolean;
|
||||||
viewEncapsulation?: 'Emulated' | 'None' | 'ShadowDom';
|
viewEncapsulation?: 'Emulated' | 'None' | 'ShadowDom';
|
||||||
changeDetection?: 'Default' | 'OnPush';
|
changeDetection?: 'Default' | 'OnPush';
|
||||||
style?: 'css' | 'scss' | 'sass' | 'less' | 'none';
|
style?: 'css' | 'scss' | 'sass' | 'less' | 'none';
|
||||||
|
|||||||
@ -47,6 +47,11 @@
|
|||||||
"default": false,
|
"default": false,
|
||||||
"alias": "t"
|
"alias": "t"
|
||||||
},
|
},
|
||||||
|
"standalone": {
|
||||||
|
"description": "Whether the generated component is standalone.",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
"viewEncapsulation": {
|
"viewEncapsulation": {
|
||||||
"description": "The view encapsulation strategy to use in the new component.",
|
"description": "The view encapsulation strategy to use in the new component.",
|
||||||
"enum": ["Emulated", "None", "ShadowDom"],
|
"enum": ["Emulated", "None", "ShadowDom"],
|
||||||
|
|||||||
@ -573,14 +573,14 @@ exports[`convert-tslint-to-eslint should work for Angular applications 1`] = `
|
|||||||
Object {
|
Object {
|
||||||
"dependencies": Object {},
|
"dependencies": Object {},
|
||||||
"devDependencies": Object {
|
"devDependencies": Object {
|
||||||
"@angular-eslint/eslint-plugin": "~13.1.0",
|
"@angular-eslint/eslint-plugin": "~13.2.1",
|
||||||
"@angular-eslint/eslint-plugin-template": "~13.1.0",
|
"@angular-eslint/eslint-plugin-template": "~13.2.1",
|
||||||
"@angular-eslint/template-parser": "~13.1.0",
|
"@angular-eslint/template-parser": "~13.2.1",
|
||||||
"@nrwl/eslint-plugin-nx": "0.0.1",
|
"@nrwl/eslint-plugin-nx": "0.0.1",
|
||||||
"@nrwl/linter": "0.0.1",
|
"@nrwl/linter": "0.0.1",
|
||||||
"@typescript-eslint/eslint-plugin": "~5.18.0",
|
"@typescript-eslint/eslint-plugin": "~5.24.0",
|
||||||
"@typescript-eslint/parser": "~5.18.0",
|
"@typescript-eslint/parser": "~5.24.0",
|
||||||
"eslint": "~8.12.0",
|
"eslint": "~8.15.0",
|
||||||
"eslint-config-prettier": "8.1.0",
|
"eslint-config-prettier": "8.1.0",
|
||||||
"eslint-plugin-import": "latest",
|
"eslint-plugin-import": "latest",
|
||||||
},
|
},
|
||||||
@ -931,14 +931,14 @@ exports[`convert-tslint-to-eslint should work for Angular libraries 1`] = `
|
|||||||
Object {
|
Object {
|
||||||
"dependencies": Object {},
|
"dependencies": Object {},
|
||||||
"devDependencies": Object {
|
"devDependencies": Object {
|
||||||
"@angular-eslint/eslint-plugin": "~13.1.0",
|
"@angular-eslint/eslint-plugin": "~13.2.1",
|
||||||
"@angular-eslint/eslint-plugin-template": "~13.1.0",
|
"@angular-eslint/eslint-plugin-template": "~13.2.1",
|
||||||
"@angular-eslint/template-parser": "~13.1.0",
|
"@angular-eslint/template-parser": "~13.2.1",
|
||||||
"@nrwl/eslint-plugin-nx": "0.0.1",
|
"@nrwl/eslint-plugin-nx": "0.0.1",
|
||||||
"@nrwl/linter": "0.0.1",
|
"@nrwl/linter": "0.0.1",
|
||||||
"@typescript-eslint/eslint-plugin": "~5.18.0",
|
"@typescript-eslint/eslint-plugin": "~5.24.0",
|
||||||
"@typescript-eslint/parser": "~5.18.0",
|
"@typescript-eslint/parser": "~5.24.0",
|
||||||
"eslint": "~8.12.0",
|
"eslint": "~8.15.0",
|
||||||
"eslint-config-prettier": "8.1.0",
|
"eslint-config-prettier": "8.1.0",
|
||||||
"eslint-plugin-import": "latest",
|
"eslint-plugin-import": "latest",
|
||||||
},
|
},
|
||||||
|
|||||||
@ -54,7 +54,7 @@ describe('init', () => {
|
|||||||
|
|
||||||
// ASSERT
|
// ASSERT
|
||||||
expect(packageJson.scripts.postinstall).toEqual(
|
expect(packageJson.scripts.postinstall).toEqual(
|
||||||
'ngcc --properties es2015 browser module main'
|
'ngcc --properties es2020 browser module main'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -87,7 +87,7 @@ function setDefaults(host: Tree, options: Schema) {
|
|||||||
function addPostInstall(host: Tree) {
|
function addPostInstall(host: Tree) {
|
||||||
updateJson(host, 'package.json', (pkgJson) => {
|
updateJson(host, 'package.json', (pkgJson) => {
|
||||||
pkgJson.scripts = pkgJson.scripts ?? {};
|
pkgJson.scripts = pkgJson.scripts ?? {};
|
||||||
const command = 'ngcc --properties es2015 browser module main';
|
const command = 'ngcc --properties es2020 browser module main';
|
||||||
if (!pkgJson.scripts.postinstall) {
|
if (!pkgJson.scripts.postinstall) {
|
||||||
pkgJson.scripts.postinstall = command;
|
pkgJson.scripts.postinstall = command;
|
||||||
} else if (!pkgJson.scripts.postinstall.includes('ngcc')) {
|
} else if (!pkgJson.scripts.postinstall.includes('ngcc')) {
|
||||||
|
|||||||
@ -49,6 +49,7 @@ function updateTsConfig(host: Tree, options: NormalizedSchema) {
|
|||||||
// update Angular Template Settings
|
// update Angular Template Settings
|
||||||
json.angularCompilerOptions = {
|
json.angularCompilerOptions = {
|
||||||
...(json.angularCompilerOptions ?? {}),
|
...(json.angularCompilerOptions ?? {}),
|
||||||
|
enableI18nLegacyMessageIdFormat: false,
|
||||||
strictInjectionParameters: true,
|
strictInjectionParameters: true,
|
||||||
strictInputAccessModifiers: true,
|
strictInputAccessModifiers: true,
|
||||||
strictTemplates: true,
|
strictTemplates: true,
|
||||||
|
|||||||
@ -39,6 +39,12 @@ function updateProjectConfig(host: Tree, options: NormalizedSchema) {
|
|||||||
];
|
];
|
||||||
return json;
|
return json;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// tsconfig.json
|
||||||
|
updateJson(host, `${options.projectRoot}/tsconfig.json`, (json) => ({
|
||||||
|
...json,
|
||||||
|
compilerOptions: { ...json.compilerOptions, target: 'es2020' },
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateProjectIvyConfig(host: Tree, options: NormalizedSchema) {
|
function updateProjectIvyConfig(host: Tree, options: NormalizedSchema) {
|
||||||
|
|||||||
@ -287,6 +287,7 @@ describe('lib', () => {
|
|||||||
expect(tsconfigJson).toEqual({
|
expect(tsconfigJson).toEqual({
|
||||||
extends: '../../tsconfig.base.json',
|
extends: '../../tsconfig.base.json',
|
||||||
angularCompilerOptions: {
|
angularCompilerOptions: {
|
||||||
|
enableI18nLegacyMessageIdFormat: false,
|
||||||
strictInjectionParameters: true,
|
strictInjectionParameters: true,
|
||||||
strictInputAccessModifiers: true,
|
strictInputAccessModifiers: true,
|
||||||
strictTemplates: true,
|
strictTemplates: true,
|
||||||
@ -298,6 +299,7 @@ describe('lib', () => {
|
|||||||
noImplicitOverride: true,
|
noImplicitOverride: true,
|
||||||
noImplicitReturns: true,
|
noImplicitReturns: true,
|
||||||
strict: true,
|
strict: true,
|
||||||
|
target: 'es2020',
|
||||||
},
|
},
|
||||||
files: [],
|
files: [],
|
||||||
include: [],
|
include: [],
|
||||||
@ -653,6 +655,7 @@ describe('lib', () => {
|
|||||||
expect(tsconfigJson).toEqual({
|
expect(tsconfigJson).toEqual({
|
||||||
extends: '../../../tsconfig.base.json',
|
extends: '../../../tsconfig.base.json',
|
||||||
angularCompilerOptions: {
|
angularCompilerOptions: {
|
||||||
|
enableI18nLegacyMessageIdFormat: false,
|
||||||
strictInjectionParameters: true,
|
strictInjectionParameters: true,
|
||||||
strictInputAccessModifiers: true,
|
strictInputAccessModifiers: true,
|
||||||
strictTemplates: true,
|
strictTemplates: true,
|
||||||
@ -664,6 +667,7 @@ describe('lib', () => {
|
|||||||
noImplicitOverride: true,
|
noImplicitOverride: true,
|
||||||
noImplicitReturns: true,
|
noImplicitReturns: true,
|
||||||
strict: true,
|
strict: true,
|
||||||
|
target: 'es2020',
|
||||||
},
|
},
|
||||||
files: [],
|
files: [],
|
||||||
include: [],
|
include: [],
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
|
addDependenciesToPackageJson,
|
||||||
formatFiles,
|
formatFiles,
|
||||||
installPackagesTask,
|
installPackagesTask,
|
||||||
moveFilesToNewDirectory,
|
moveFilesToNewDirectory,
|
||||||
|
removeDependenciesFromPackageJson,
|
||||||
Tree,
|
Tree,
|
||||||
} from '@nrwl/devkit';
|
} from '@nrwl/devkit';
|
||||||
import { wrapAngularDevkitSchematic } from '@nrwl/devkit/ngcli-adapter';
|
import { wrapAngularDevkitSchematic } from '@nrwl/devkit/ngcli-adapter';
|
||||||
@ -9,6 +11,7 @@ import { jestProjectGenerator } from '@nrwl/jest';
|
|||||||
import { Linter } from '@nrwl/linter';
|
import { Linter } from '@nrwl/linter';
|
||||||
import { convertToNxProjectGenerator } from '@nrwl/workspace/generators';
|
import { convertToNxProjectGenerator } from '@nrwl/workspace/generators';
|
||||||
import init from '../../generators/init/init';
|
import init from '../../generators/init/init';
|
||||||
|
import { ngPackagrVersion } from '../../utils/versions';
|
||||||
import addLintingGenerator from '../add-linting/add-linting';
|
import addLintingGenerator from '../add-linting/add-linting';
|
||||||
import karmaProjectGenerator from '../karma-project/karma-project';
|
import karmaProjectGenerator from '../karma-project/karma-project';
|
||||||
import setupTailwindGenerator from '../setup-tailwind/setup-tailwind';
|
import setupTailwindGenerator from '../setup-tailwind/setup-tailwind';
|
||||||
@ -86,6 +89,14 @@ export async function libraryGenerator(host: Tree, schema: Partial<Schema>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.buildable || options.publishable) {
|
if (options.buildable || options.publishable) {
|
||||||
|
removeDependenciesFromPackageJson(host, [], ['ng-packagr']);
|
||||||
|
addDependenciesToPackageJson(
|
||||||
|
host,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
'ng-packagr': ngPackagrVersion,
|
||||||
|
}
|
||||||
|
);
|
||||||
addBuildableLibrariesPostCssDependencies(host);
|
addBuildableLibrariesPostCssDependencies(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,12 @@
|
|||||||
import type { Tree } from '@nrwl/devkit';
|
import {
|
||||||
import { joinPathFragments, logger } from '@nrwl/devkit';
|
joinPathFragments,
|
||||||
|
logger,
|
||||||
|
Tree,
|
||||||
|
visitNotIgnoredFiles,
|
||||||
|
} from '@nrwl/devkit';
|
||||||
import { tsquery } from '@phenomnomnominal/tsquery';
|
import { tsquery } from '@phenomnomnominal/tsquery';
|
||||||
import { basename, dirname } from 'path';
|
import { basename, dirname, extname, relative } from 'path';
|
||||||
import type { SourceFile, Statement } from 'typescript';
|
import type { Identifier, SourceFile, Statement } from 'typescript';
|
||||||
import { SyntaxKind } from 'typescript';
|
import { SyntaxKind } from 'typescript';
|
||||||
import { getTsSourceFile } from '../../../utils/nx-devkit/ast-utils';
|
import { getTsSourceFile } from '../../../utils/nx-devkit/ast-utils';
|
||||||
import { getModuleDeclaredComponents } from './module-info';
|
import { getModuleDeclaredComponents } from './module-info';
|
||||||
@ -43,6 +47,47 @@ export function getComponentsInfo(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getStandaloneComponentsInfo(
|
||||||
|
tree: Tree,
|
||||||
|
projectPath: string
|
||||||
|
): ComponentInfo[] {
|
||||||
|
const componentsInfo: ComponentInfo[] = [];
|
||||||
|
|
||||||
|
visitNotIgnoredFiles(tree, projectPath, (filePath: string) => {
|
||||||
|
if (extname(filePath) !== '.ts') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const standaloneComponents = getStandaloneComponents(tree, filePath);
|
||||||
|
if (!standaloneComponents.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
standaloneComponents.forEach((componentName) => {
|
||||||
|
componentsInfo.push({
|
||||||
|
componentFileName: basename(filePath, '.ts'),
|
||||||
|
moduleFolderPath: projectPath,
|
||||||
|
name: componentName,
|
||||||
|
path: dirname(relative(projectPath, filePath)),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return componentsInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStandaloneComponents(tree: Tree, filePath: string): string[] {
|
||||||
|
const fileContent = tree.read(filePath, 'utf-8');
|
||||||
|
const ast = tsquery.ast(fileContent);
|
||||||
|
const components = tsquery<Identifier>(
|
||||||
|
ast,
|
||||||
|
'ClassDeclaration:has(Decorator > CallExpression:has(Identifier[name=Component]) ObjectLiteralExpression PropertyAssignment Identifier[name=standalone] ~ TrueKeyword) > Identifier',
|
||||||
|
{ visitAllChildren: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
return components.map((component) => component.getText());
|
||||||
|
}
|
||||||
|
|
||||||
function getComponentImportPath(
|
function getComponentImportPath(
|
||||||
componentName: string,
|
componentName: string,
|
||||||
imports: Statement[]
|
imports: Statement[]
|
||||||
|
|||||||
@ -3,7 +3,10 @@ import { logger } from '@nrwl/devkit';
|
|||||||
import { getProjectRootPath } from '@nrwl/workspace/src/utilities/project-type';
|
import { getProjectRootPath } from '@nrwl/workspace/src/utilities/project-type';
|
||||||
import componentCypressSpecGenerator from '../component-cypress-spec/component-cypress-spec';
|
import componentCypressSpecGenerator from '../component-cypress-spec/component-cypress-spec';
|
||||||
import componentStoryGenerator from '../component-story/component-story';
|
import componentStoryGenerator from '../component-story/component-story';
|
||||||
import { getComponentsInfo } from './lib/component-info';
|
import {
|
||||||
|
getComponentsInfo,
|
||||||
|
getStandaloneComponentsInfo,
|
||||||
|
} from './lib/component-info';
|
||||||
import { getE2EProject } from './lib/get-e2e-project';
|
import { getE2EProject } from './lib/get-e2e-project';
|
||||||
import { getModuleFilePaths } from './lib/module-info';
|
import { getModuleFilePaths } from './lib/module-info';
|
||||||
import type { StoriesGeneratorOptions } from './schema';
|
import type { StoriesGeneratorOptions } from './schema';
|
||||||
@ -16,7 +19,11 @@ export function angularStoriesGenerator(
|
|||||||
const e2eProject = getE2EProject(tree, e2eProjectName);
|
const e2eProject = getE2EProject(tree, e2eProjectName);
|
||||||
const projectPath = getProjectRootPath(tree, options.name);
|
const projectPath = getProjectRootPath(tree, options.name);
|
||||||
const moduleFilePaths = getModuleFilePaths(tree, projectPath);
|
const moduleFilePaths = getModuleFilePaths(tree, projectPath);
|
||||||
const componentsInfo = getComponentsInfo(tree, moduleFilePaths, options.name);
|
const componentsInfo = [
|
||||||
|
...getComponentsInfo(tree, moduleFilePaths, options.name),
|
||||||
|
// TODO(leo): uncomment once Storybook supports standalone components https://github.com/storybookjs/storybook/pull/18272
|
||||||
|
// ...getStandaloneComponentsInfo(tree, projectPath),
|
||||||
|
];
|
||||||
|
|
||||||
if (options.generateCypressSpecs && !e2eProject) {
|
if (options.generateCypressSpecs && !e2eProject) {
|
||||||
logger.info(
|
logger.info(
|
||||||
|
|||||||
@ -0,0 +1,86 @@
|
|||||||
|
import {
|
||||||
|
addProjectConfiguration,
|
||||||
|
readProjectConfiguration,
|
||||||
|
Tree,
|
||||||
|
} from '@nrwl/devkit';
|
||||||
|
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
||||||
|
import removeShowCircularDependencies from './remove-show-circular-dependencies-option';
|
||||||
|
|
||||||
|
describe('remove-show-circular-dependencies-option migration', () => {
|
||||||
|
let tree: Tree;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
tree = createTreeWithEmptyWorkspace(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
'@angular-devkit/build-angular:browser',
|
||||||
|
'@angular-devkit/build-angular:server',
|
||||||
|
'@nrwl/angular:webpack-browser',
|
||||||
|
])(
|
||||||
|
'should remove "showCircularDependencies" option from target using the "%s" executor',
|
||||||
|
async (executor) => {
|
||||||
|
addProjectConfiguration(tree, 'app1', {
|
||||||
|
root: 'apps/app1',
|
||||||
|
sourceRoot: 'apps/app1/src',
|
||||||
|
projectType: 'application',
|
||||||
|
targets: {
|
||||||
|
build: {
|
||||||
|
executor,
|
||||||
|
options: { extractCss: false, showCircularDependencies: true },
|
||||||
|
configurations: {
|
||||||
|
one: { showCircularDependencies: false, aot: true },
|
||||||
|
two: { showCircularDependencies: false, aot: true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await removeShowCircularDependencies(tree);
|
||||||
|
|
||||||
|
const project = readProjectConfiguration(tree, 'app1');
|
||||||
|
expect(
|
||||||
|
project.targets.build.options.showCircularDependencies
|
||||||
|
).toBeUndefined();
|
||||||
|
expect(project.targets.build.configurations).toBeDefined();
|
||||||
|
expect(
|
||||||
|
project.targets.build.configurations.one.showCircularDependencies
|
||||||
|
).toBeUndefined();
|
||||||
|
expect(
|
||||||
|
project.targets.build.configurations.two.showCircularDependencies
|
||||||
|
).toBeUndefined();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it('should not remove "showCircularDependencies" from target not using the relevant executors', async () => {
|
||||||
|
addProjectConfiguration(tree, 'app1', {
|
||||||
|
root: 'apps/app1',
|
||||||
|
sourceRoot: 'apps/app1/src',
|
||||||
|
projectType: 'application',
|
||||||
|
targets: {
|
||||||
|
build: {
|
||||||
|
executor: '@org/awesome-plugin:executor',
|
||||||
|
options: { extractCss: false, showCircularDependencies: true },
|
||||||
|
configurations: {
|
||||||
|
one: { showCircularDependencies: false, aot: true },
|
||||||
|
two: { showCircularDependencies: false, aot: true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await removeShowCircularDependencies(tree);
|
||||||
|
|
||||||
|
const project = readProjectConfiguration(tree, 'app1');
|
||||||
|
expect(
|
||||||
|
project.targets.build.options.showCircularDependencies
|
||||||
|
).toBeDefined();
|
||||||
|
expect(project.targets.build.configurations).toBeDefined();
|
||||||
|
expect(
|
||||||
|
project.targets.build.configurations.one.showCircularDependencies
|
||||||
|
).toBeDefined();
|
||||||
|
expect(
|
||||||
|
project.targets.build.configurations.two.showCircularDependencies
|
||||||
|
).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
import {
|
||||||
|
formatFiles,
|
||||||
|
readProjectConfiguration,
|
||||||
|
Tree,
|
||||||
|
updateProjectConfiguration,
|
||||||
|
} from '@nrwl/devkit';
|
||||||
|
import { forEachExecutorOptions } from '@nrwl/workspace/src/utilities/executor-options-utils';
|
||||||
|
|
||||||
|
const executors = [
|
||||||
|
'@angular-devkit/build-angular:browser',
|
||||||
|
'@angular-devkit/build-angular:server',
|
||||||
|
'@nrwl/angular:webpack-browser',
|
||||||
|
];
|
||||||
|
|
||||||
|
export default async function (tree: Tree) {
|
||||||
|
executors.forEach((executor) => {
|
||||||
|
forEachExecutorOptions(
|
||||||
|
tree,
|
||||||
|
executor,
|
||||||
|
(_options, projectName, targetName, configurationName) => {
|
||||||
|
const projectConfiguration = readProjectConfiguration(
|
||||||
|
tree,
|
||||||
|
projectName
|
||||||
|
);
|
||||||
|
const config = configurationName
|
||||||
|
? projectConfiguration.targets[targetName].configurations[
|
||||||
|
configurationName
|
||||||
|
]
|
||||||
|
: projectConfiguration.targets[targetName].options;
|
||||||
|
delete config.showCircularDependencies;
|
||||||
|
updateProjectConfiguration(tree, projectName, projectConfiguration);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
await formatFiles(tree);
|
||||||
|
}
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
import { readJson, Tree, writeJson } from '@nrwl/devkit';
|
||||||
|
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
||||||
|
import updateAngularCli from './update-angular-cli';
|
||||||
|
|
||||||
|
describe('update-angular-cli migration', () => {
|
||||||
|
let tree: Tree;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
tree = createTreeWithEmptyWorkspace(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update @angular/cli version when defined as a dev dependency', async () => {
|
||||||
|
writeJson(tree, 'package.json', {
|
||||||
|
devDependencies: { '@angular/cli': '~13.3.0' },
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateAngularCli(tree);
|
||||||
|
|
||||||
|
const { devDependencies } = readJson(tree, 'package.json');
|
||||||
|
expect(devDependencies['@angular/cli']).toEqual('~14.0.0-rc.2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update @angular/cli version when defined as a dependency', async () => {
|
||||||
|
writeJson(tree, 'package.json', {
|
||||||
|
dependencies: { '@angular/cli': '~13.3.0' },
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateAngularCli(tree);
|
||||||
|
|
||||||
|
const { dependencies } = readJson(tree, 'package.json');
|
||||||
|
expect(dependencies['@angular/cli']).toEqual('~14.0.0-rc.2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add @angular/cli to package.json when it is not set', async () => {
|
||||||
|
const initialPackageJson = readJson(tree, 'package.json');
|
||||||
|
|
||||||
|
await updateAngularCli(tree);
|
||||||
|
|
||||||
|
const packageJson = readJson(tree, 'package.json');
|
||||||
|
expect(packageJson).toStrictEqual(initialPackageJson);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
import { formatFiles, Tree, updateJson } from '@nrwl/devkit';
|
||||||
|
|
||||||
|
export default async function (tree: Tree) {
|
||||||
|
let shouldFormat = false;
|
||||||
|
|
||||||
|
updateJson(tree, 'package.json', (json) => {
|
||||||
|
if (json.devDependencies?.['@angular/cli']) {
|
||||||
|
json.devDependencies['@angular/cli'] = '~14.0.0-rc.2';
|
||||||
|
shouldFormat = true;
|
||||||
|
} else if (json.dependencies?.['@angular/cli']) {
|
||||||
|
json.dependencies['@angular/cli'] = '~14.0.0-rc.2';
|
||||||
|
shouldFormat = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (shouldFormat) {
|
||||||
|
await formatFiles(tree);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,97 @@
|
|||||||
|
import {
|
||||||
|
addProjectConfiguration,
|
||||||
|
readJson,
|
||||||
|
Tree,
|
||||||
|
writeJson,
|
||||||
|
} from '@nrwl/devkit';
|
||||||
|
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
||||||
|
import updateLibrariesSecondaryEntrypoints from './update-libraries-secondary-entrypoints';
|
||||||
|
|
||||||
|
const libraryExecutors = [
|
||||||
|
'@angular-devkit/build-angular:ng-packagr',
|
||||||
|
'@nrwl/angular:ng-packagr-lite',
|
||||||
|
'@nrwl/angular:package',
|
||||||
|
];
|
||||||
|
|
||||||
|
describe('update-libraries-secondary-entrypoints migration', () => {
|
||||||
|
let tree: Tree;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
tree = createTreeWithEmptyWorkspace(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each(libraryExecutors)(
|
||||||
|
'should not delete "package.json" of the primary entrypoint (%s)',
|
||||||
|
async (executor) => {
|
||||||
|
addProjectConfiguration(tree, 'lib1', {
|
||||||
|
root: 'libs/lib1',
|
||||||
|
targets: { build: { executor } },
|
||||||
|
});
|
||||||
|
writeJson(tree, 'libs/lib1/package.json', { version: '0.0.0' });
|
||||||
|
|
||||||
|
await updateLibrariesSecondaryEntrypoints(tree);
|
||||||
|
|
||||||
|
expect(tree.exists('libs/lib1/package.json')).toBe(true);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each(libraryExecutors)(
|
||||||
|
'should delete "package.json" of the secondary entrypoint (%s)',
|
||||||
|
async (executor) => {
|
||||||
|
addProjectConfiguration(tree, 'lib1', {
|
||||||
|
root: 'libs/lib1',
|
||||||
|
targets: { build: { executor } },
|
||||||
|
});
|
||||||
|
writeJson(tree, 'libs/lib1/package.json', { version: '0.0.0' });
|
||||||
|
writeJson(tree, 'libs/lib1/secondary/package.json', {
|
||||||
|
version: '0.0.0',
|
||||||
|
ngPackage: { lib: { entryFile: 'src/index.ts' } },
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateLibrariesSecondaryEntrypoints(tree);
|
||||||
|
|
||||||
|
expect(tree.exists('libs/lib1/secondary/package.json')).toBe(false);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each(libraryExecutors)(
|
||||||
|
'should move ng-packagr configuration from "package.json" to "ng-package.json" (%s)',
|
||||||
|
async (executor) => {
|
||||||
|
addProjectConfiguration(tree, 'lib1', {
|
||||||
|
root: 'libs/lib1',
|
||||||
|
targets: { build: { executor } },
|
||||||
|
});
|
||||||
|
writeJson(tree, 'libs/lib1/package.json', { version: '0.0.0' });
|
||||||
|
writeJson(tree, 'libs/lib1/secondary/package.json', {
|
||||||
|
version: '0.0.0',
|
||||||
|
ngPackage: { lib: { entryFile: 'src/index.ts' } },
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateLibrariesSecondaryEntrypoints(tree);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
readJson(tree, 'libs/lib1/secondary/ng-package.json')
|
||||||
|
).toStrictEqual({
|
||||||
|
lib: { entryFile: 'src/index.ts' },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it('should do nothing when not using any of the relevant executors', async () => {
|
||||||
|
addProjectConfiguration(tree, 'lib1', {
|
||||||
|
root: 'libs/lib1',
|
||||||
|
targets: { test: { executor: '@nrwl/jest:jest' } },
|
||||||
|
});
|
||||||
|
writeJson(tree, 'libs/lib1/package.json', { version: '0.0.0' });
|
||||||
|
writeJson(tree, 'libs/lib1/secondary/package.json', {
|
||||||
|
version: '0.0.0',
|
||||||
|
ngPackage: { lib: { entryFile: 'src/index.ts' } },
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateLibrariesSecondaryEntrypoints(tree);
|
||||||
|
|
||||||
|
expect(tree.exists('libs/lib1/package.json')).toBe(true);
|
||||||
|
expect(tree.exists('libs/lib1/secondary/package.json')).toBe(true);
|
||||||
|
expect(tree.exists('libs/lib1/secondary/ng-package.json')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
import {
|
||||||
|
formatFiles,
|
||||||
|
getProjects,
|
||||||
|
joinPathFragments,
|
||||||
|
readJson,
|
||||||
|
Tree,
|
||||||
|
visitNotIgnoredFiles,
|
||||||
|
writeJson,
|
||||||
|
} from '@nrwl/devkit';
|
||||||
|
import { basename, dirname } from 'path';
|
||||||
|
|
||||||
|
const libraryExecutors = [
|
||||||
|
'@angular-devkit/build-angular:ng-packagr',
|
||||||
|
'@nrwl/angular:ng-packagr-lite',
|
||||||
|
'@nrwl/angular:package',
|
||||||
|
];
|
||||||
|
|
||||||
|
export default async function (tree: Tree) {
|
||||||
|
const projects = getProjects(tree);
|
||||||
|
|
||||||
|
for (const [, project] of projects) {
|
||||||
|
if (
|
||||||
|
!Object.values(project.targets ?? {}).some((target) =>
|
||||||
|
libraryExecutors.includes(target.executor)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
visitNotIgnoredFiles(tree, project.root, (filePath) => {
|
||||||
|
if (
|
||||||
|
basename(filePath) !== 'package.json' ||
|
||||||
|
filePath === joinPathFragments(project.root, 'package.json')
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const json = readJson(tree, filePath);
|
||||||
|
if (json.ngPackage) {
|
||||||
|
// Migrate ng-packagr config to an ng-packagr config file.
|
||||||
|
const configFilePath = joinPathFragments(
|
||||||
|
dirname(filePath),
|
||||||
|
'ng-package.json'
|
||||||
|
);
|
||||||
|
writeJson(tree, configFilePath, json.ngPackage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete package.json as it is no longer needed in APF 14.
|
||||||
|
tree.delete(filePath);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await formatFiles(tree);
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
import { readJson } from '@nrwl/devkit';
|
||||||
|
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
||||||
|
import updateNgccTarget from './update-ngcc-target';
|
||||||
|
|
||||||
|
describe('update-ngcc-postinstall-target migration', () => {
|
||||||
|
[
|
||||||
|
{
|
||||||
|
test: 'node ./decorate-angular-cli.js && ngcc --properties es2015 browser module main',
|
||||||
|
expected:
|
||||||
|
'node ./decorate-angular-cli.js && ngcc --properties es2020 browser module main',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: 'node ./decorate-angular-cli.js && ngcc --properties es2015 browser module main && echo "hi"',
|
||||||
|
expected:
|
||||||
|
'node ./decorate-angular-cli.js && ngcc --properties es2020 browser module main && echo "hi"',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: 'ngcc --properties es2015 browser module main && node ./decorate-angular-cli.js && echo "hi"',
|
||||||
|
expected:
|
||||||
|
'ngcc --properties es2020 browser module main && node ./decorate-angular-cli.js && echo "hi"',
|
||||||
|
},
|
||||||
|
].forEach((testEntry) => {
|
||||||
|
it(`should adjust ngcc target for: "${testEntry.test}"`, async () => {
|
||||||
|
const tree = createTreeWithEmptyWorkspace();
|
||||||
|
tree.write(
|
||||||
|
'/package.json',
|
||||||
|
JSON.stringify({ scripts: { postinstall: testEntry.test } })
|
||||||
|
);
|
||||||
|
|
||||||
|
await updateNgccTarget(tree);
|
||||||
|
|
||||||
|
const packageJson = readJson(tree, 'package.json');
|
||||||
|
expect(packageJson.scripts.postinstall).toEqual(testEntry.expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
test: 'node ngcc.js',
|
||||||
|
expected: 'node ngcc.js',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: 'any random postinstall script',
|
||||||
|
expected: 'any random postinstall script',
|
||||||
|
},
|
||||||
|
].forEach((testEntry) => {
|
||||||
|
it(`should not update postinstall script: "${testEntry.test}"`, async () => {
|
||||||
|
const tree = createTreeWithEmptyWorkspace();
|
||||||
|
tree.write(
|
||||||
|
'/package.json',
|
||||||
|
JSON.stringify({ scripts: { postinstall: testEntry.test } })
|
||||||
|
);
|
||||||
|
|
||||||
|
await updateNgccTarget(tree);
|
||||||
|
|
||||||
|
const packageJson = readJson(tree, 'package.json');
|
||||||
|
expect(packageJson.scripts.postinstall).toEqual(testEntry.expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
import { formatFiles, Tree, updateJson } from '@nrwl/devkit';
|
||||||
|
|
||||||
|
export default async function (tree: Tree) {
|
||||||
|
let shouldFormat = false;
|
||||||
|
|
||||||
|
updateJson(tree, 'package.json', (json) => {
|
||||||
|
if (json.scripts?.postinstall?.includes('ngcc ')) {
|
||||||
|
json.scripts.postinstall = json.scripts.postinstall.replace(
|
||||||
|
/(.*)(ngcc --properties es2015 )(.*)/,
|
||||||
|
'$1ngcc --properties es2020 $3'
|
||||||
|
);
|
||||||
|
shouldFormat = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (shouldFormat) {
|
||||||
|
await formatFiles(tree);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,608 @@
|
|||||||
|
import { logger, ProjectGraph, Tree } from '@nrwl/devkit';
|
||||||
|
import {
|
||||||
|
addProjectConfiguration,
|
||||||
|
DependencyType,
|
||||||
|
readJson,
|
||||||
|
writeJson,
|
||||||
|
} from '@nrwl/devkit';
|
||||||
|
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
||||||
|
import updateTsConfigTarget from './update-tsconfig-target';
|
||||||
|
|
||||||
|
let projectGraph: ProjectGraph;
|
||||||
|
jest.mock('@nrwl/devkit', () => ({
|
||||||
|
...jest.requireActual<any>('@nrwl/devkit'),
|
||||||
|
createProjectGraphAsync: jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementation(async () => projectGraph),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('update-tsconfig-target migration', () => {
|
||||||
|
let tree: Tree;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
tree = createTreeWithEmptyWorkspace(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update target in "tsconfig.json" at the project root when it is an Angular project', async () => {
|
||||||
|
addProjectConfiguration(tree, 'app1', {
|
||||||
|
root: 'apps/app1',
|
||||||
|
sourceRoot: 'apps/app1/src',
|
||||||
|
projectType: 'application',
|
||||||
|
targets: {
|
||||||
|
build: {
|
||||||
|
executor: '@nrwl/angular:webpack-browser',
|
||||||
|
options: { tsConfig: 'apps/app1/tsconfig.app.json' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
projectGraph = {
|
||||||
|
dependencies: {
|
||||||
|
app1: [
|
||||||
|
{
|
||||||
|
type: DependencyType.static,
|
||||||
|
source: 'app1',
|
||||||
|
target: 'npm:@angular/core',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
nodes: {},
|
||||||
|
};
|
||||||
|
writeJson(tree, 'apps/app1/tsconfig.json', {
|
||||||
|
compilerOptions: { target: 'es2017' },
|
||||||
|
});
|
||||||
|
writeJson(tree, 'apps/app1/tsconfig.app.json', {
|
||||||
|
compilerOptions: { target: 'es2017' },
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateTsConfigTarget(tree);
|
||||||
|
|
||||||
|
const { compilerOptions } = readJson(tree, 'apps/app1/tsconfig.json');
|
||||||
|
expect(compilerOptions.target).toBe('es2020');
|
||||||
|
const optionTsConfig = readJson(tree, 'apps/app1/tsconfig.app.json');
|
||||||
|
expect(optionTsConfig.compilerOptions.target).toBe('es2020');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not update target in a tsconfig file referenced by a target option when it does not have the target set and there is a "tsconfig.json" at the project root', async () => {
|
||||||
|
addProjectConfiguration(tree, 'app1', {
|
||||||
|
root: 'apps/app1',
|
||||||
|
sourceRoot: 'apps/app1/src',
|
||||||
|
projectType: 'application',
|
||||||
|
targets: {
|
||||||
|
build: {
|
||||||
|
executor: '@nrwl/angular:webpack-browser',
|
||||||
|
options: { tsConfig: 'apps/app1/tsconfig.app.json' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
projectGraph = {
|
||||||
|
dependencies: {
|
||||||
|
app1: [
|
||||||
|
{
|
||||||
|
type: DependencyType.static,
|
||||||
|
source: 'app1',
|
||||||
|
target: 'npm:@angular/core',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
nodes: {},
|
||||||
|
};
|
||||||
|
writeJson(tree, 'apps/app1/tsconfig.json', {
|
||||||
|
compilerOptions: { target: 'es2017' },
|
||||||
|
});
|
||||||
|
writeJson(tree, 'apps/app1/tsconfig.app.json', {
|
||||||
|
compilerOptions: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateTsConfigTarget(tree);
|
||||||
|
|
||||||
|
const { compilerOptions } = readJson(tree, 'apps/app1/tsconfig.json');
|
||||||
|
expect(compilerOptions.target).toBe('es2020');
|
||||||
|
const optionTsConfig = readJson(tree, 'apps/app1/tsconfig.app.json');
|
||||||
|
expect(optionTsConfig.compilerOptions).toStrictEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
['@angular-devkit/build-angular:browser', 'tsconfig.app.json'],
|
||||||
|
['@angular-devkit/build-angular:karma', 'tsconfig.spec.json'],
|
||||||
|
['@nrwl/angular:webpack-browser', 'tsconfig.app.json'],
|
||||||
|
['@nrwl/angular:delegate-build', 'tsconfig.app.json'],
|
||||||
|
])(
|
||||||
|
'should update target in the tsconfig file referenced by the target configuration when using the "%s" executor and there is no "tsconfig.json" at the project root',
|
||||||
|
async (executor, tsConfig) => {
|
||||||
|
const tsConfigPath = `apps/app1/${tsConfig}`;
|
||||||
|
addProjectConfiguration(tree, 'app1', {
|
||||||
|
root: 'apps/app1',
|
||||||
|
sourceRoot: 'apps/app1/src',
|
||||||
|
projectType: 'application',
|
||||||
|
targets: {
|
||||||
|
build: { executor, options: { tsConfig: tsConfigPath } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
projectGraph = {
|
||||||
|
dependencies: {
|
||||||
|
app1: [
|
||||||
|
{
|
||||||
|
type: DependencyType.static,
|
||||||
|
source: 'app1',
|
||||||
|
target: 'npm:@angular/core',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
nodes: {},
|
||||||
|
};
|
||||||
|
writeJson(tree, tsConfigPath, {
|
||||||
|
compilerOptions: { target: 'es2017' },
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateTsConfigTarget(tree);
|
||||||
|
|
||||||
|
const { compilerOptions } = readJson(tree, tsConfigPath);
|
||||||
|
expect(compilerOptions.target).toBe('es2020');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
'@angular-devkit/build-angular:ng-packagr',
|
||||||
|
'@nrwl/angular:ng-packagr-lite',
|
||||||
|
'@nrwl/angular:package',
|
||||||
|
])(
|
||||||
|
'should update target in the tsconfig file referenced by the target configuration when using the "%s" executor and there is no "tsconfig.json" at the project root',
|
||||||
|
async (executor) => {
|
||||||
|
addProjectConfiguration(tree, 'lib1', {
|
||||||
|
root: 'libs/lib1',
|
||||||
|
sourceRoot: 'libs/lib1/src',
|
||||||
|
projectType: 'library',
|
||||||
|
targets: {
|
||||||
|
build: {
|
||||||
|
executor,
|
||||||
|
options: { tsConfig: 'libs/lib1/tsconfig.lib.json' },
|
||||||
|
configurations: {
|
||||||
|
production: { tsConfig: 'libs/lib1/tsconfig.lib.prod.json' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
projectGraph = {
|
||||||
|
dependencies: {
|
||||||
|
lib1: [
|
||||||
|
{
|
||||||
|
type: DependencyType.static,
|
||||||
|
source: 'lib1',
|
||||||
|
target: 'npm:@angular/core',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
nodes: {},
|
||||||
|
};
|
||||||
|
writeJson(tree, 'libs/lib1/tsconfig.lib.json', {
|
||||||
|
compilerOptions: { target: 'es2017' },
|
||||||
|
});
|
||||||
|
writeJson(tree, 'libs/lib1/tsconfig.lib.prod.json', {});
|
||||||
|
|
||||||
|
await updateTsConfigTarget(tree);
|
||||||
|
|
||||||
|
const { compilerOptions } = readJson(tree, 'libs/lib1/tsconfig.lib.json');
|
||||||
|
expect(compilerOptions.target).toBe('es2020');
|
||||||
|
const tsConfigProd = readJson(tree, 'libs/lib1/tsconfig.lib.prod.json');
|
||||||
|
expect(tsConfigProd.compilerOptions.target).toBe('es2020');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it('should not error and log a warning when the tsconfig file specified in target does not exist', async () => {
|
||||||
|
jest.spyOn(logger, 'warn');
|
||||||
|
addProjectConfiguration(tree, 'lib1', {
|
||||||
|
root: 'libs/lib1',
|
||||||
|
sourceRoot: 'libs/lib1/src',
|
||||||
|
projectType: 'library',
|
||||||
|
targets: {
|
||||||
|
build: {
|
||||||
|
executor: '@nrwl/angular:package',
|
||||||
|
options: { tsConfig: 'libs/lib1/tsconfig.lib.json' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
projectGraph = {
|
||||||
|
dependencies: {
|
||||||
|
lib1: [
|
||||||
|
{
|
||||||
|
type: DependencyType.static,
|
||||||
|
source: 'lib1',
|
||||||
|
target: 'npm:@angular/core',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
nodes: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
await expect(updateTsConfigTarget(tree)).resolves.not.toThrow();
|
||||||
|
|
||||||
|
expect(logger.warn).toHaveBeenCalledWith(
|
||||||
|
expect.stringContaining(
|
||||||
|
`The "libs/lib1/tsconfig.lib.json" file specified in the "build" target of the "lib1" project could not be found.`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update target in tsconfig file specified in the jest config when it is an Angular project', async () => {
|
||||||
|
addProjectConfiguration(tree, 'lib1', {
|
||||||
|
root: 'libs/lib1',
|
||||||
|
sourceRoot: 'libs/lib1/src',
|
||||||
|
projectType: 'library',
|
||||||
|
targets: {
|
||||||
|
build: {
|
||||||
|
executor: '@nrwl/jest:jest',
|
||||||
|
options: { jestConfig: 'libs/lib1/jest.config.ts' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
projectGraph = {
|
||||||
|
dependencies: {
|
||||||
|
lib1: [
|
||||||
|
{
|
||||||
|
type: DependencyType.static,
|
||||||
|
source: 'lib1',
|
||||||
|
target: 'npm:@angular/core',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
nodes: {},
|
||||||
|
};
|
||||||
|
tree.write(
|
||||||
|
'libs/lib1/jest.config.ts',
|
||||||
|
`export default {
|
||||||
|
displayName: 'lib1',
|
||||||
|
preset: '../../jest.preset.js',
|
||||||
|
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||||
|
globals: {
|
||||||
|
'ts-jest': {
|
||||||
|
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||||
|
stringifyContentPathRegex: '\\.(html|svg)$',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
coverageDirectory: '../../coverage/libs/lib1',
|
||||||
|
transform: {
|
||||||
|
'^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular',
|
||||||
|
},
|
||||||
|
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
|
||||||
|
snapshotSerializers: [
|
||||||
|
'jest-preset-angular/build/serializers/no-ng-attributes',
|
||||||
|
'jest-preset-angular/build/serializers/ng-snapshot',
|
||||||
|
'jest-preset-angular/build/serializers/html-comment',
|
||||||
|
],
|
||||||
|
};`
|
||||||
|
);
|
||||||
|
writeJson(tree, 'libs/lib1/tsconfig.spec.json', {
|
||||||
|
compilerOptions: { target: 'es2017' },
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateTsConfigTarget(tree);
|
||||||
|
|
||||||
|
const { compilerOptions } = readJson(tree, 'libs/lib1/tsconfig.spec.json');
|
||||||
|
expect(compilerOptions.target).toBe('es2020');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not error and log a warning when the tsconfig file specified in the jest configuration does not exist', async () => {
|
||||||
|
jest.spyOn(logger, 'warn');
|
||||||
|
addProjectConfiguration(tree, 'lib1', {
|
||||||
|
root: 'libs/lib1',
|
||||||
|
sourceRoot: 'libs/lib1/src',
|
||||||
|
projectType: 'library',
|
||||||
|
targets: {
|
||||||
|
test: {
|
||||||
|
executor: '@nrwl/jest:jest',
|
||||||
|
options: { jestConfig: 'libs/lib1/jest.config.ts' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
projectGraph = {
|
||||||
|
dependencies: {
|
||||||
|
lib1: [
|
||||||
|
{
|
||||||
|
type: DependencyType.static,
|
||||||
|
source: 'lib1',
|
||||||
|
target: 'npm:@angular/core',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
nodes: {},
|
||||||
|
};
|
||||||
|
tree.write(
|
||||||
|
'libs/lib1/jest.config.ts',
|
||||||
|
`export default {
|
||||||
|
globals: {
|
||||||
|
'ts-jest': {
|
||||||
|
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||||
|
stringifyContentPathRegex: '\\.(html|svg)$',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};`
|
||||||
|
);
|
||||||
|
|
||||||
|
await expect(updateTsConfigTarget(tree)).resolves.not.toThrow();
|
||||||
|
|
||||||
|
expect(logger.warn).toHaveBeenCalledWith(
|
||||||
|
expect.stringContaining(
|
||||||
|
`The "<rootDir>/tsconfig.spec.json" file specified in the Jest configuration file "libs/lib1/jest.config.ts" of the "test" target of the "lib1" project could not be found.`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not error and log a warning when the jest configuration does not specify the "tsconfig"', async () => {
|
||||||
|
jest.spyOn(logger, 'warn');
|
||||||
|
addProjectConfiguration(tree, 'lib1', {
|
||||||
|
root: 'libs/lib1',
|
||||||
|
sourceRoot: 'libs/lib1/src',
|
||||||
|
projectType: 'library',
|
||||||
|
targets: {
|
||||||
|
test: {
|
||||||
|
executor: '@nrwl/jest:jest',
|
||||||
|
options: { jestConfig: 'libs/lib1/jest.config.ts' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
projectGraph = {
|
||||||
|
dependencies: {
|
||||||
|
lib1: [
|
||||||
|
{
|
||||||
|
type: DependencyType.static,
|
||||||
|
source: 'lib1',
|
||||||
|
target: 'npm:@angular/core',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
nodes: {},
|
||||||
|
};
|
||||||
|
tree.write('libs/lib1/jest.config.ts', `export default {};`);
|
||||||
|
|
||||||
|
await expect(updateTsConfigTarget(tree)).resolves.not.toThrow();
|
||||||
|
|
||||||
|
expect(logger.warn).toHaveBeenCalledWith(
|
||||||
|
expect.stringContaining(
|
||||||
|
`Couldn't find the "tsconfig" property for "ts-jest" in the Jest configuration file "libs/lib1/jest.config.ts" specified in the "test" target of the "lib1" project.`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not error and log a warning when the jest configuration file does not exist', async () => {
|
||||||
|
jest.spyOn(logger, 'warn');
|
||||||
|
addProjectConfiguration(tree, 'lib1', {
|
||||||
|
root: 'libs/lib1',
|
||||||
|
sourceRoot: 'libs/lib1/src',
|
||||||
|
projectType: 'library',
|
||||||
|
targets: {
|
||||||
|
test: {
|
||||||
|
executor: '@nrwl/jest:jest',
|
||||||
|
options: { jestConfig: 'libs/lib1/jest.config.ts' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
projectGraph = {
|
||||||
|
dependencies: {
|
||||||
|
lib1: [
|
||||||
|
{
|
||||||
|
type: DependencyType.static,
|
||||||
|
source: 'lib1',
|
||||||
|
target: 'npm:@angular/core',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
nodes: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
await expect(updateTsConfigTarget(tree)).resolves.not.toThrow();
|
||||||
|
|
||||||
|
expect(logger.warn).toHaveBeenCalledWith(
|
||||||
|
expect.stringContaining(
|
||||||
|
`The "libs/lib1/jest.config.ts" file specified in the "test" target of the "lib1" project could not be found.`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not error and log a warning when the jest configuration file is not specified', async () => {
|
||||||
|
jest.spyOn(logger, 'warn');
|
||||||
|
addProjectConfiguration(tree, 'lib1', {
|
||||||
|
root: 'libs/lib1',
|
||||||
|
sourceRoot: 'libs/lib1/src',
|
||||||
|
projectType: 'library',
|
||||||
|
targets: { test: { executor: '@nrwl/jest:jest', options: {} } },
|
||||||
|
});
|
||||||
|
projectGraph = {
|
||||||
|
dependencies: {
|
||||||
|
lib1: [
|
||||||
|
{
|
||||||
|
type: DependencyType.static,
|
||||||
|
source: 'lib1',
|
||||||
|
target: 'npm:@angular/core',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
nodes: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
await expect(updateTsConfigTarget(tree)).resolves.not.toThrow();
|
||||||
|
|
||||||
|
expect(logger.warn).toHaveBeenCalledWith(
|
||||||
|
expect.stringContaining(
|
||||||
|
`The "test" target of the "lib1" project is using the "@nrwl/jest:jest" executor but no "jestConfig" property was specified.`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each(['es2021', 'es2022', 'esnext'])(
|
||||||
|
'should not update target when it is already set to a target greater than es2020 ("%s")',
|
||||||
|
async (target) => {
|
||||||
|
addProjectConfiguration(tree, 'app1', {
|
||||||
|
root: 'apps/app1',
|
||||||
|
sourceRoot: 'apps/app1/src',
|
||||||
|
projectType: 'library',
|
||||||
|
targets: {
|
||||||
|
build: {
|
||||||
|
executor: '@angular-devkit/build-angular:browser',
|
||||||
|
options: { tsConfig: 'apps/app1/tsconfig.other.json' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
projectGraph = {
|
||||||
|
dependencies: {
|
||||||
|
app1: [
|
||||||
|
{
|
||||||
|
type: DependencyType.static,
|
||||||
|
source: 'app1',
|
||||||
|
target: 'npm:@angular/core',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
nodes: {},
|
||||||
|
};
|
||||||
|
writeJson(tree, 'apps/app1/tsconfig.json', {
|
||||||
|
compilerOptions: { target },
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateTsConfigTarget(tree);
|
||||||
|
|
||||||
|
const { compilerOptions } = readJson(tree, 'apps/app1/tsconfig.json');
|
||||||
|
expect(compilerOptions.target).toBe(target);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it('should not update target in "tsconfig.json" at the project root when it is not an angular project', async () => {
|
||||||
|
addProjectConfiguration(tree, 'lib1', {
|
||||||
|
root: 'libs/lib1',
|
||||||
|
sourceRoot: 'libs/lib1/src',
|
||||||
|
projectType: 'library',
|
||||||
|
});
|
||||||
|
projectGraph = {
|
||||||
|
dependencies: {
|
||||||
|
lib1: [
|
||||||
|
{
|
||||||
|
type: DependencyType.static,
|
||||||
|
source: 'lib1',
|
||||||
|
target: 'npm:lodash',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
nodes: {},
|
||||||
|
};
|
||||||
|
writeJson(tree, 'libs/lib1/tsconfig.json', {
|
||||||
|
compilerOptions: { target: 'es2017' },
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateTsConfigTarget(tree);
|
||||||
|
|
||||||
|
const { compilerOptions } = readJson(tree, 'libs/lib1/tsconfig.json');
|
||||||
|
expect(compilerOptions.target).toBe('es2017');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not update target in a tsconfig file referenced by a target option when not using the relevant executors', async () => {
|
||||||
|
jest.spyOn(logger, 'warn');
|
||||||
|
addProjectConfiguration(tree, 'lib1', {
|
||||||
|
root: 'libs/lib1',
|
||||||
|
sourceRoot: 'libs/lib1/src',
|
||||||
|
projectType: 'library',
|
||||||
|
targets: {
|
||||||
|
build: {
|
||||||
|
executor: '@org/awesome-plugin:executor',
|
||||||
|
options: { tsConfig: 'libs/lib1/tsconfig.other.json' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
projectGraph = {
|
||||||
|
dependencies: {
|
||||||
|
lib1: [
|
||||||
|
{
|
||||||
|
type: DependencyType.static,
|
||||||
|
source: 'lib1',
|
||||||
|
target: 'npm:@angular/core',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
nodes: {},
|
||||||
|
};
|
||||||
|
writeJson(tree, 'libs/lib1/tsconfig.other.json', {
|
||||||
|
compilerOptions: { target: 'es2017' },
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateTsConfigTarget(tree);
|
||||||
|
|
||||||
|
const { compilerOptions } = readJson(tree, 'libs/lib1/tsconfig.other.json');
|
||||||
|
expect(compilerOptions.target).toBe('es2017');
|
||||||
|
expect(logger.warn).toHaveBeenCalledWith(
|
||||||
|
expect.stringContaining(
|
||||||
|
'The "build" target of the "lib1" project is using an executor not supported by the migration.'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not update target in a tsconfig file referenced by a target configuration when not using the relevant executors', async () => {
|
||||||
|
addProjectConfiguration(tree, 'lib1', {
|
||||||
|
root: 'libs/lib1',
|
||||||
|
sourceRoot: 'libs/lib1/src',
|
||||||
|
projectType: 'library',
|
||||||
|
targets: {
|
||||||
|
build: {
|
||||||
|
executor: '@org/awesome-plugin:executor',
|
||||||
|
configurations: {
|
||||||
|
production: { tsConfig: 'libs/lib1/tsconfig.other.json' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
projectGraph = {
|
||||||
|
dependencies: {
|
||||||
|
lib1: [
|
||||||
|
{
|
||||||
|
type: DependencyType.static,
|
||||||
|
source: 'lib1',
|
||||||
|
target: 'npm:@angular/core',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
nodes: {},
|
||||||
|
};
|
||||||
|
writeJson(tree, 'libs/lib1/tsconfig.other.json', {
|
||||||
|
compilerOptions: { target: 'es2017' },
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateTsConfigTarget(tree);
|
||||||
|
|
||||||
|
const { compilerOptions } = readJson(tree, 'libs/lib1/tsconfig.other.json');
|
||||||
|
expect(compilerOptions.target).toBe('es2017');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not update target in workspace "tsconfig.base.json"', async () => {
|
||||||
|
addProjectConfiguration(tree, 'app1', {
|
||||||
|
root: 'apps/app1',
|
||||||
|
sourceRoot: 'apps/app1/src',
|
||||||
|
projectType: 'application',
|
||||||
|
targets: {
|
||||||
|
build: {
|
||||||
|
executor: '@nrwl/angular:webpack-browser',
|
||||||
|
options: { tsConfig: 'apps/app1/tsconfig.json' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
projectGraph = {
|
||||||
|
dependencies: {
|
||||||
|
app1: [
|
||||||
|
{
|
||||||
|
type: DependencyType.static,
|
||||||
|
source: 'app1',
|
||||||
|
target: 'npm:@angular/core',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
nodes: {},
|
||||||
|
};
|
||||||
|
writeJson(tree, 'apps/app1/tsconfig.json', {
|
||||||
|
compilerOptions: { target: 'es2017' },
|
||||||
|
});
|
||||||
|
writeJson(tree, 'tsconfig.base.json', {
|
||||||
|
compilerOptions: { target: 'es2017' },
|
||||||
|
});
|
||||||
|
|
||||||
|
await updateTsConfigTarget(tree);
|
||||||
|
|
||||||
|
const { compilerOptions } = readJson(tree, 'tsconfig.base.json');
|
||||||
|
expect(compilerOptions.target).toBe('es2017');
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,247 @@
|
|||||||
|
import {
|
||||||
|
ProjectConfiguration,
|
||||||
|
readJson,
|
||||||
|
TargetConfiguration,
|
||||||
|
Tree,
|
||||||
|
} from '@nrwl/devkit';
|
||||||
|
import {
|
||||||
|
createProjectGraphAsync,
|
||||||
|
formatFiles,
|
||||||
|
joinPathFragments,
|
||||||
|
logger,
|
||||||
|
readProjectConfiguration,
|
||||||
|
updateJson,
|
||||||
|
} from '@nrwl/devkit';
|
||||||
|
import { tsquery } from '@phenomnomnominal/tsquery';
|
||||||
|
import { dirname } from 'path';
|
||||||
|
import type { StringLiteral } from 'typescript';
|
||||||
|
|
||||||
|
const jestExecutor = '@nrwl/jest:jest';
|
||||||
|
const executors = [
|
||||||
|
'@angular-devkit/build-angular:browser',
|
||||||
|
'@angular-devkit/build-angular:karma',
|
||||||
|
'@angular-devkit/build-angular:ng-packagr',
|
||||||
|
'@nrwl/angular:webpack-browser',
|
||||||
|
'@nrwl/angular:delegate-build',
|
||||||
|
'@nrwl/angular:ng-packagr-lite',
|
||||||
|
'@nrwl/angular:package',
|
||||||
|
];
|
||||||
|
const skipTargets = ['es2020', 'es2021', 'es2022', 'esnext'];
|
||||||
|
|
||||||
|
export default async function (tree: Tree) {
|
||||||
|
const tsConfigPaths = await collectTsConfigPaths(tree);
|
||||||
|
|
||||||
|
for (const tsConfigPath of tsConfigPaths) {
|
||||||
|
updateJson(tree, tsConfigPath, (json) => {
|
||||||
|
if (
|
||||||
|
!json.compilerOptions?.target ||
|
||||||
|
(json.compilerOptions?.target &&
|
||||||
|
!skipTargets.includes(json.compilerOptions.target.toLowerCase()))
|
||||||
|
) {
|
||||||
|
json.compilerOptions ??= {};
|
||||||
|
json.compilerOptions.target = 'es2020';
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await formatFiles(tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function collectTsConfigPaths(tree: Tree): Promise<string[]> {
|
||||||
|
const uniqueTsConfigs = new Set([]);
|
||||||
|
|
||||||
|
const projectGraph = await createProjectGraphAsync();
|
||||||
|
const angularProjects = Object.entries(projectGraph.dependencies)
|
||||||
|
.filter(([, dep]) =>
|
||||||
|
dep.some(({ target }) => target === 'npm:@angular/core')
|
||||||
|
)
|
||||||
|
.map(([projectName]) => ({
|
||||||
|
projectName,
|
||||||
|
project: readProjectConfiguration(tree, projectName),
|
||||||
|
}));
|
||||||
|
|
||||||
|
for (const { projectName, project } of angularProjects) {
|
||||||
|
const tsConfigPath = joinPathFragments(project.root, 'tsconfig.json');
|
||||||
|
if (tree.exists(tsConfigPath)) {
|
||||||
|
uniqueTsConfigs.add(tsConfigPath);
|
||||||
|
|
||||||
|
const targetTsConfigPaths = getProjectTsConfigPaths(
|
||||||
|
tree,
|
||||||
|
project,
|
||||||
|
projectName,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
targetTsConfigPaths.forEach((tsConfigPath) => {
|
||||||
|
const tsConfig = readJson(tree, tsConfigPath);
|
||||||
|
if (tsConfig.compilerOptions?.target) {
|
||||||
|
uniqueTsConfigs.add(tsConfigPath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tsConfigPaths = getProjectTsConfigPaths(tree, project, projectName);
|
||||||
|
for (const tsConfigPath of tsConfigPaths) {
|
||||||
|
uniqueTsConfigs.add(tsConfigPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.from(uniqueTsConfigs);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getProjectTsConfigPaths(
|
||||||
|
tree: Tree,
|
||||||
|
project: ProjectConfiguration,
|
||||||
|
projectName: string,
|
||||||
|
shouldWarn: boolean = true
|
||||||
|
): string[] {
|
||||||
|
const tsConfigPaths = new Set<string>();
|
||||||
|
|
||||||
|
for (const [targetName, target] of Object.entries(project.targets || {})) {
|
||||||
|
if (executors.includes(target.executor)) {
|
||||||
|
const tsConfigPathsFromTarget = getPathValuesFromTarget(
|
||||||
|
target,
|
||||||
|
'tsConfig'
|
||||||
|
);
|
||||||
|
tsConfigPathsFromTarget.forEach((tsConfigPath) => {
|
||||||
|
if (tree.exists(tsConfigPath)) {
|
||||||
|
tsConfigPaths.add(tsConfigPath);
|
||||||
|
} else if (shouldWarn) {
|
||||||
|
logger.warn(
|
||||||
|
`The "${tsConfigPath}" file specified in the "${targetName}" target of the "${projectName}" project could not be found. ` +
|
||||||
|
'Skipping setting the target to ES2020.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (target.executor === jestExecutor) {
|
||||||
|
const tsConfigPathsFromJestTarget = getTsConfigPathsFromJestTarget(
|
||||||
|
tree,
|
||||||
|
target,
|
||||||
|
targetName,
|
||||||
|
projectName,
|
||||||
|
shouldWarn
|
||||||
|
);
|
||||||
|
tsConfigPathsFromJestTarget.forEach((tsConfigPath) => {
|
||||||
|
tsConfigPaths.add(tsConfigPath);
|
||||||
|
});
|
||||||
|
} else if (shouldWarn) {
|
||||||
|
logger.warn(
|
||||||
|
`The "${targetName}" target of the "${projectName}" project is using an executor not supported by the migration. ` +
|
||||||
|
'Skipping setting the TS target to ES2020 for the project.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.from(tsConfigPaths);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTsConfigPathsFromJestTarget(
|
||||||
|
tree: Tree,
|
||||||
|
target: TargetConfiguration,
|
||||||
|
targetName: string,
|
||||||
|
projectName: string,
|
||||||
|
shouldWarn: boolean
|
||||||
|
): string[] {
|
||||||
|
const tsConfigPaths: string[] = [];
|
||||||
|
|
||||||
|
const jestConfigPaths = getPathValuesFromTarget(target, 'jestConfig');
|
||||||
|
if (!jestConfigPaths.length && shouldWarn) {
|
||||||
|
logger.warn(
|
||||||
|
`The "${targetName}" target of the "${projectName}" project is using the "${jestExecutor}" executor but no "jestConfig" property was specified. ` +
|
||||||
|
'Skipping setting the TS compilation target to ES2020 for the project.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const jestConfigPath of jestConfigPaths) {
|
||||||
|
const tsConfigPath = getTsConfigFromJestConfig(
|
||||||
|
tree,
|
||||||
|
jestConfigPath,
|
||||||
|
targetName,
|
||||||
|
projectName,
|
||||||
|
shouldWarn
|
||||||
|
);
|
||||||
|
if (tsConfigPath) {
|
||||||
|
tsConfigPaths.push(tsConfigPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tsConfigPaths;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTsConfigFromJestConfig(
|
||||||
|
tree: Tree,
|
||||||
|
jestConfigPath: string,
|
||||||
|
targetName: string,
|
||||||
|
projectName: string,
|
||||||
|
shouldWarn: boolean
|
||||||
|
): string {
|
||||||
|
if (!tree.exists(jestConfigPath)) {
|
||||||
|
if (shouldWarn) {
|
||||||
|
logger.warn(
|
||||||
|
`The "${jestConfigPath}" file specified in the "${targetName}" target of the "${projectName}" project could not be found. ` +
|
||||||
|
`The TS config file used by the target can't be determined. Skipping setting the target to ES2020.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const jestConfig = tree.read(jestConfigPath, 'utf-8');
|
||||||
|
const jestConfigAst = tsquery.ast(jestConfig);
|
||||||
|
const tsJestTsConfigStringLiteral = tsquery(
|
||||||
|
jestConfigAst,
|
||||||
|
'PropertyAssignment:has(Identifier[name=globals]) PropertyAssignment:has(StringLiteral[value=ts-jest]) PropertyAssignment Identifier[name=tsconfig] ~ StringLiteral',
|
||||||
|
{ visitAllChildren: true }
|
||||||
|
)[0] as StringLiteral;
|
||||||
|
|
||||||
|
if (!tsJestTsConfigStringLiteral) {
|
||||||
|
if (shouldWarn) {
|
||||||
|
logger.warn(
|
||||||
|
`Couldn't find the "tsconfig" property for "ts-jest" in the Jest configuration file "${jestConfigPath}" specified in the ` +
|
||||||
|
`"${targetName}" target of the "${projectName}" project. The TS config file used by the target can't be determined. ` +
|
||||||
|
'Skipping setting the target to ES2020.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tsJestTsConfigValue = tsJestTsConfigStringLiteral
|
||||||
|
.getText()
|
||||||
|
.replace(/['"]/g, '');
|
||||||
|
const tsConfigPath = tsJestTsConfigValue.replace(
|
||||||
|
'<rootDir>',
|
||||||
|
dirname(jestConfigPath)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!tree.exists(tsConfigPath)) {
|
||||||
|
if (shouldWarn) {
|
||||||
|
logger.warn(
|
||||||
|
`The "${tsJestTsConfigValue}" file specified in the Jest configuration file "${jestConfigPath}" of the "${targetName}" target ` +
|
||||||
|
`of the "${projectName}" project could not be found. Skipping setting the target to ES2020.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tsConfigPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPathValuesFromTarget(
|
||||||
|
target: TargetConfiguration,
|
||||||
|
option: string
|
||||||
|
): string[] {
|
||||||
|
const values: string[] = [];
|
||||||
|
|
||||||
|
if (target.options?.[option]) {
|
||||||
|
values.push(target.options[option]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.values(target.configurations ?? {}).forEach((options) => {
|
||||||
|
if (options[option]) {
|
||||||
|
values.push(options[option]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
@ -232,6 +232,78 @@ describe('MFE Webpack Utils', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should collect secondary entry points from exports and fall back to lookinp up for package.json', () => {
|
||||||
|
// ARRANGE
|
||||||
|
(fs.existsSync as jest.Mock).mockImplementation(
|
||||||
|
(path) => !path.endsWith('/secondary/package.json')
|
||||||
|
);
|
||||||
|
jest.spyOn(devkit, 'readJsonFile').mockImplementation((file) => {
|
||||||
|
if (file.endsWith('pkg1/package.json')) {
|
||||||
|
return {
|
||||||
|
name: 'pkg1',
|
||||||
|
version: '1.0.0',
|
||||||
|
exports: {
|
||||||
|
'.': './index.js',
|
||||||
|
'./package.json': './package.json',
|
||||||
|
'./secondary': './secondary/index.js',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// @angular/core/package.json won't have exports, so it looks up for package.json
|
||||||
|
return {
|
||||||
|
name: file
|
||||||
|
.replace(/\\/g, '/')
|
||||||
|
.replace(/^.*node_modules[/]/, '')
|
||||||
|
.replace('/package.json', ''),
|
||||||
|
dependencies: { pkg1: '1.0.0', '@angular/core': '~13.2.0' },
|
||||||
|
};
|
||||||
|
});
|
||||||
|
(fs.readdirSync as jest.Mock).mockImplementation(
|
||||||
|
(directoryPath: string) => {
|
||||||
|
const packages = {
|
||||||
|
pkg1: ['secondary'],
|
||||||
|
'@angular/core': ['testing'],
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const key of Object.keys(packages)) {
|
||||||
|
if (directoryPath.endsWith(key)) {
|
||||||
|
return packages[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
(fs.lstatSync as jest.Mock).mockReturnValue({ isDirectory: () => true });
|
||||||
|
|
||||||
|
// ACT
|
||||||
|
const packages = sharePackages(['pkg1', '@angular/core']);
|
||||||
|
|
||||||
|
// ASSERT
|
||||||
|
expect(packages).toStrictEqual({
|
||||||
|
pkg1: {
|
||||||
|
singleton: true,
|
||||||
|
strictVersion: true,
|
||||||
|
requiredVersion: '1.0.0',
|
||||||
|
},
|
||||||
|
'pkg1/secondary': {
|
||||||
|
singleton: true,
|
||||||
|
strictVersion: true,
|
||||||
|
requiredVersion: '1.0.0',
|
||||||
|
},
|
||||||
|
'@angular/core': {
|
||||||
|
singleton: true,
|
||||||
|
strictVersion: true,
|
||||||
|
requiredVersion: '~13.2.0',
|
||||||
|
},
|
||||||
|
'@angular/core/testing': {
|
||||||
|
singleton: true,
|
||||||
|
strictVersion: true,
|
||||||
|
requiredVersion: '~13.2.0',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should not throw when the main entry point package.json cannot be required', () => {
|
it('should not throw when the main entry point package.json cannot be required', () => {
|
||||||
// ARRANGE
|
// ARRANGE
|
||||||
(fs.existsSync as jest.Mock).mockImplementation(
|
(fs.existsSync as jest.Mock).mockImplementation(
|
||||||
|
|||||||
@ -102,27 +102,36 @@ function recursivelyCollectSecondaryEntryPointsFromDirectory(
|
|||||||
pkgName: string,
|
pkgName: string,
|
||||||
pkgVersion: string,
|
pkgVersion: string,
|
||||||
pkgRoot: string,
|
pkgRoot: string,
|
||||||
|
mainEntryPointExports: any | undefined,
|
||||||
directories: string[],
|
directories: string[],
|
||||||
collectedPackages: { name: string; version: string }[]
|
collectedPackages: { name: string; version: string }[]
|
||||||
): void {
|
): void {
|
||||||
for (const directory of directories) {
|
for (const directory of directories) {
|
||||||
const packageJsonPath = join(directory, 'package.json');
|
const packageJsonPath = join(directory, 'package.json');
|
||||||
|
const relativeEntryPointPath = relative(pkgRoot, directory);
|
||||||
|
const entryPointName = joinPathFragments(pkgName, relativeEntryPointPath);
|
||||||
if (existsSync(packageJsonPath)) {
|
if (existsSync(packageJsonPath)) {
|
||||||
const importName = joinPathFragments(
|
|
||||||
pkgName,
|
|
||||||
relative(pkgRoot, directory)
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// require the secondary entry point to try to rule out sample code
|
// require the secondary entry point to try to rule out sample code
|
||||||
require.resolve(importName, { paths: [workspaceRoot] });
|
require.resolve(entryPointName, { paths: [workspaceRoot] });
|
||||||
const { name } = readJsonFile(packageJsonPath);
|
const { name } = readJsonFile(packageJsonPath);
|
||||||
// further check to make sure what we were able to require is the
|
// further check to make sure what we were able to require is the
|
||||||
// same as the package name
|
// same as the package name
|
||||||
if (name === importName) {
|
if (name === entryPointName) {
|
||||||
collectedPackages.push({ name, version: pkgVersion });
|
collectedPackages.push({ name, version: pkgVersion });
|
||||||
}
|
}
|
||||||
} catch {}
|
} catch {}
|
||||||
|
} else if (mainEntryPointExports) {
|
||||||
|
// if the package.json doesn't exist, check if the directory is
|
||||||
|
// exported by the main entry point
|
||||||
|
const entryPointExportKey = `./${relativeEntryPointPath}`;
|
||||||
|
const entryPointInfo = mainEntryPointExports[entryPointExportKey];
|
||||||
|
if (entryPointInfo) {
|
||||||
|
collectedPackages.push({
|
||||||
|
name: entryPointName,
|
||||||
|
version: pkgVersion,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const subDirs = getNonNodeModulesSubDirs(directory);
|
const subDirs = getNonNodeModulesSubDirs(directory);
|
||||||
@ -130,6 +139,7 @@ function recursivelyCollectSecondaryEntryPointsFromDirectory(
|
|||||||
pkgName,
|
pkgName,
|
||||||
pkgVersion,
|
pkgVersion,
|
||||||
pkgRoot,
|
pkgRoot,
|
||||||
|
mainEntryPointExports,
|
||||||
subDirs,
|
subDirs,
|
||||||
collectedPackages
|
collectedPackages
|
||||||
);
|
);
|
||||||
@ -142,8 +152,9 @@ function collectPackageSecondaryEntryPoints(
|
|||||||
collectedPackages: { name: string; version: string }[]
|
collectedPackages: { name: string; version: string }[]
|
||||||
): void {
|
): void {
|
||||||
let pathToPackage: string;
|
let pathToPackage: string;
|
||||||
|
let packageJsonPath: string;
|
||||||
try {
|
try {
|
||||||
const packageJsonPath = require.resolve(`${pkgName}/package.json`, {
|
packageJsonPath = require.resolve(`${pkgName}/package.json`, {
|
||||||
paths: [workspaceRoot],
|
paths: [workspaceRoot],
|
||||||
});
|
});
|
||||||
pathToPackage = dirname(packageJsonPath);
|
pathToPackage = dirname(packageJsonPath);
|
||||||
@ -152,17 +163,20 @@ function collectPackageSecondaryEntryPoints(
|
|||||||
// entry and is not exporting the package.json file, fall back to trying
|
// entry and is not exporting the package.json file, fall back to trying
|
||||||
// to find it from the top-level node_modules
|
// to find it from the top-level node_modules
|
||||||
pathToPackage = join(workspaceRoot, 'node_modules', pkgName);
|
pathToPackage = join(workspaceRoot, 'node_modules', pkgName);
|
||||||
if (!existsSync(join(pathToPackage, 'package.json'))) {
|
packageJsonPath = join(pathToPackage, 'package.json');
|
||||||
|
if (!existsSync(packageJsonPath)) {
|
||||||
// might not exist if it's nested in another package, just return here
|
// might not exist if it's nested in another package, just return here
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { exports } = readJsonFile(packageJsonPath);
|
||||||
const subDirs = getNonNodeModulesSubDirs(pathToPackage);
|
const subDirs = getNonNodeModulesSubDirs(pathToPackage);
|
||||||
recursivelyCollectSecondaryEntryPointsFromDirectory(
|
recursivelyCollectSecondaryEntryPointsFromDirectory(
|
||||||
pkgName,
|
pkgName,
|
||||||
pkgVersion,
|
pkgVersion,
|
||||||
pathToPackage,
|
pathToPackage,
|
||||||
|
exports,
|
||||||
subDirs,
|
subDirs,
|
||||||
collectedPackages
|
collectedPackages
|
||||||
);
|
);
|
||||||
|
|||||||
@ -32,7 +32,7 @@ const migrationTestRunner = new SchematicTestRunner(
|
|||||||
join(__dirname, '../../migrations.json')
|
join(__dirname, '../../migrations.json')
|
||||||
);
|
);
|
||||||
|
|
||||||
export function runMigration<SchemaOptions = any>(
|
export function runMigration<SchemaOptions extends object = any>(
|
||||||
schematicName: string,
|
schematicName: string,
|
||||||
options: SchemaOptions,
|
options: SchemaOptions,
|
||||||
tree: Tree
|
tree: Tree
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
export const nxVersion = require('../../package.json').version;
|
export const nxVersion = require('../../package.json').version;
|
||||||
export const angularVersion = '~13.3.0';
|
export const angularVersion = '~14.0.0-rc.2';
|
||||||
export const angularDevkitVersion = '~13.3.0';
|
export const angularDevkitVersion = '~14.0.0-rc.2';
|
||||||
|
export const ngPackagrVersion = '~14.0.0-rc.0';
|
||||||
export const angularJsVersion = '1.7.9';
|
export const angularJsVersion = '1.7.9';
|
||||||
export const ngrxVersion = '~13.0.0';
|
export const ngrxVersion = '~13.2.0';
|
||||||
export const rxjsVersion = '~7.4.0';
|
export const rxjsVersion = '~7.4.0';
|
||||||
export const jestPresetAngularVersion = '11.1.1';
|
export const jestPresetAngularVersion = '~11.1.2';
|
||||||
export const angularEslintVersion = '~13.1.0';
|
export const angularEslintVersion = '~13.2.1';
|
||||||
export const tailwindVersion = '^3.0.2';
|
export const tailwindVersion = '^3.0.2';
|
||||||
export const postcssVersion = '^8.4.5';
|
export const postcssVersion = '^8.4.5';
|
||||||
export const autoprefixerVersion = '^10.4.0';
|
export const autoprefixerVersion = '^10.4.0';
|
||||||
|
|||||||
@ -6,9 +6,9 @@ Object {
|
|||||||
"devDependencies": Object {
|
"devDependencies": Object {
|
||||||
"@nrwl/eslint-plugin-nx": "0.0.1",
|
"@nrwl/eslint-plugin-nx": "0.0.1",
|
||||||
"@nrwl/linter": "0.0.1",
|
"@nrwl/linter": "0.0.1",
|
||||||
"@typescript-eslint/eslint-plugin": "~5.18.0",
|
"@typescript-eslint/eslint-plugin": "~5.24.0",
|
||||||
"@typescript-eslint/parser": "~5.18.0",
|
"@typescript-eslint/parser": "~5.24.0",
|
||||||
"eslint": "~8.12.0",
|
"eslint": "~8.15.0",
|
||||||
"eslint-config-prettier": "8.1.0",
|
"eslint-config-prettier": "8.1.0",
|
||||||
"eslint-plugin-cypress": "^2.10.3",
|
"eslint-plugin-cypress": "^2.10.3",
|
||||||
"eslint-plugin-import": "latest",
|
"eslint-plugin-import": "latest",
|
||||||
|
|||||||
@ -23,7 +23,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://nx.dev",
|
"homepage": "https://nx.dev",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@typescript-eslint/parser": "~5.18.0",
|
"@typescript-eslint/parser": "~5.24.0",
|
||||||
"eslint-config-prettier": "^8.1.0"
|
"eslint-config-prettier": "^8.1.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
@ -34,7 +34,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nrwl/devkit": "file:../devkit",
|
"@nrwl/devkit": "file:../devkit",
|
||||||
"@nrwl/workspace": "file:../workspace",
|
"@nrwl/workspace": "file:../workspace",
|
||||||
"@typescript-eslint/experimental-utils": "~5.18.0",
|
"@typescript-eslint/experimental-utils": "~5.24.0",
|
||||||
"chalk": "4.1.0",
|
"chalk": "4.1.0",
|
||||||
"confusing-browser-globals": "^1.0.9"
|
"confusing-browser-globals": "^1.0.9"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ const migrationTestRunner = new SchematicTestRunner(
|
|||||||
join(__dirname, '../../migrations.json')
|
join(__dirname, '../../migrations.json')
|
||||||
);
|
);
|
||||||
|
|
||||||
export function runSchematic<T = any>(
|
export function runSchematic<T extends object = any>(
|
||||||
schematicName: string,
|
schematicName: string,
|
||||||
options: T,
|
options: T,
|
||||||
tree: Tree
|
tree: Tree
|
||||||
@ -26,9 +26,9 @@ export function callRule(rule: Rule, tree: Tree) {
|
|||||||
return testRunner.callRule(rule, tree).toPromise();
|
return testRunner.callRule(rule, tree).toPromise();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function runMigration(
|
export function runMigration<T extends object = any>(
|
||||||
migrationName: string,
|
migrationName: string,
|
||||||
options: unknown,
|
options: T,
|
||||||
tree: Tree
|
tree: Tree
|
||||||
) {
|
) {
|
||||||
return migrationTestRunner
|
return migrationTestRunner
|
||||||
|
|||||||
@ -208,6 +208,23 @@
|
|||||||
"version": "~8.12.0"
|
"version": "~8.12.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"14.2.0": {
|
||||||
|
"version": "14.2.0-beta.0",
|
||||||
|
"packages": {
|
||||||
|
"@typescript-eslint/parser": {
|
||||||
|
"version": "~5.24.0"
|
||||||
|
},
|
||||||
|
"@typescript-eslint/eslint-plugin": {
|
||||||
|
"version": "~5.24.0"
|
||||||
|
},
|
||||||
|
"@typescript-eslint/experimental-utils": {
|
||||||
|
"version": "~5.24.0"
|
||||||
|
},
|
||||||
|
"eslint": {
|
||||||
|
"version": "~8.15.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ const migrationTestRunner = new SchematicTestRunner(
|
|||||||
join(__dirname, '../../migrations.json')
|
join(__dirname, '../../migrations.json')
|
||||||
);
|
);
|
||||||
|
|
||||||
export function runMigration<T = any>(
|
export function runMigration<T extends object = any>(
|
||||||
migrationName: string,
|
migrationName: string,
|
||||||
options: T,
|
options: T,
|
||||||
tree: Tree
|
tree: Tree
|
||||||
|
|||||||
@ -2,8 +2,8 @@ export const nxVersion = require('../../package.json').version;
|
|||||||
|
|
||||||
export const tslintVersion = '~6.1.0';
|
export const tslintVersion = '~6.1.0';
|
||||||
export const tslintToEslintConfigVersion = '^2.4.0';
|
export const tslintToEslintConfigVersion = '^2.4.0';
|
||||||
export const buildAngularVersion = '~13.3.0';
|
export const buildAngularVersion = '~14.0.0-rc.2';
|
||||||
|
|
||||||
export const typescriptESLintVersion = '~5.18.0';
|
export const typescriptESLintVersion = '~5.24.0';
|
||||||
export const eslintVersion = '~8.12.0';
|
export const eslintVersion = '~8.15.0';
|
||||||
export const eslintConfigPrettierVersion = '8.1.0';
|
export const eslintConfigPrettierVersion = '8.1.0';
|
||||||
|
|||||||
@ -6,9 +6,9 @@ Object {
|
|||||||
"devDependencies": Object {
|
"devDependencies": Object {
|
||||||
"@nrwl/eslint-plugin-nx": "0.0.1",
|
"@nrwl/eslint-plugin-nx": "0.0.1",
|
||||||
"@nrwl/linter": "0.0.1",
|
"@nrwl/linter": "0.0.1",
|
||||||
"@typescript-eslint/eslint-plugin": "~5.18.0",
|
"@typescript-eslint/eslint-plugin": "~5.24.0",
|
||||||
"@typescript-eslint/parser": "~5.18.0",
|
"@typescript-eslint/parser": "~5.24.0",
|
||||||
"eslint": "~8.12.0",
|
"eslint": "~8.15.0",
|
||||||
"eslint-config-prettier": "8.1.0",
|
"eslint-config-prettier": "8.1.0",
|
||||||
"eslint-plugin-import": "latest",
|
"eslint-plugin-import": "latest",
|
||||||
},
|
},
|
||||||
@ -299,9 +299,9 @@ Object {
|
|||||||
"devDependencies": Object {
|
"devDependencies": Object {
|
||||||
"@nrwl/eslint-plugin-nx": "0.0.1",
|
"@nrwl/eslint-plugin-nx": "0.0.1",
|
||||||
"@nrwl/linter": "0.0.1",
|
"@nrwl/linter": "0.0.1",
|
||||||
"@typescript-eslint/eslint-plugin": "~5.18.0",
|
"@typescript-eslint/eslint-plugin": "~5.24.0",
|
||||||
"@typescript-eslint/parser": "~5.18.0",
|
"@typescript-eslint/parser": "~5.24.0",
|
||||||
"eslint": "~8.12.0",
|
"eslint": "~8.15.0",
|
||||||
"eslint-config-prettier": "8.1.0",
|
"eslint-config-prettier": "8.1.0",
|
||||||
"eslint-plugin-import": "latest",
|
"eslint-plugin-import": "latest",
|
||||||
},
|
},
|
||||||
|
|||||||
@ -71,8 +71,6 @@ function getProjects(projectGraph: ProjectGraph, project: string): any {
|
|||||||
const targetAliases = {
|
const targetAliases = {
|
||||||
b: 'build',
|
b: 'build',
|
||||||
e: 'e2e',
|
e: 'e2e',
|
||||||
'i18n-extract': 'extract-i18n',
|
|
||||||
xi18n: 'extract-i18n',
|
|
||||||
l: 'lint',
|
l: 'lint',
|
||||||
s: 'serve',
|
s: 'serve',
|
||||||
t: 'test',
|
t: 'test',
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
export const nxVersion = require('../../package.json').version;
|
export const nxVersion = require('../../package.json').version;
|
||||||
|
|
||||||
export const angularCliVersion = '~13.2.0';
|
export const angularCliVersion = '~14.0.0-rc.2';
|
||||||
export const typescriptVersion = '~4.5.2';
|
export const typescriptVersion = '~4.6.2';
|
||||||
export const prettierVersion = '^2.5.1';
|
export const prettierVersion = '^2.5.1';
|
||||||
export const tslintVersion = '~6.1.0';
|
export const tslintVersion = '~6.1.0';
|
||||||
export const typescriptESLintVersion = '~5.18.0';
|
export const typescriptESLintVersion = '~5.24.0';
|
||||||
export const eslintVersion = '~8.12.0';
|
export const eslintVersion = '~8.15.0';
|
||||||
export const eslintConfigPrettierVersion = '8.1.0';
|
export const eslintConfigPrettierVersion = '8.1.0';
|
||||||
export const swcNodeVersion = '^1.4.2';
|
export const swcNodeVersion = '^1.4.2';
|
||||||
export const swcCoreVersion = '^1.2.173';
|
export const swcCoreVersion = '^1.2.173';
|
||||||
|
|||||||
@ -63,7 +63,7 @@ const migrationTestRunner = new SchematicTestRunner(
|
|||||||
join(__dirname, '../../migrations.json')
|
join(__dirname, '../../migrations.json')
|
||||||
);
|
);
|
||||||
|
|
||||||
export function runExternalSchematic<T = any>(
|
export function runExternalSchematic<T extends object = any>(
|
||||||
collectionName: string,
|
collectionName: string,
|
||||||
schematicName: string,
|
schematicName: string,
|
||||||
options: T,
|
options: T,
|
||||||
@ -74,7 +74,7 @@ export function runExternalSchematic<T = any>(
|
|||||||
.toPromise();
|
.toPromise();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function runSchematic<T = any>(
|
export function runSchematic<T extends object = any>(
|
||||||
schematicName: string,
|
schematicName: string,
|
||||||
options: T,
|
options: T,
|
||||||
tree: Tree
|
tree: Tree
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
export const nxVersion = require('../../package.json').version;
|
export const nxVersion = require('../../package.json').version;
|
||||||
|
|
||||||
export const angularCliVersion = '~13.3.0';
|
export const angularCliVersion = '~14.0.0-rc.2';
|
||||||
export const typescriptVersion = '~4.6.2';
|
export const typescriptVersion = '~4.6.2';
|
||||||
export const prettierVersion = '^2.5.1';
|
export const prettierVersion = '^2.5.1';
|
||||||
export const tslintVersion = '~6.1.0';
|
export const tslintVersion = '~6.1.0';
|
||||||
export const typescriptESLintVersion = '~5.18.0';
|
export const typescriptESLintVersion = '~5.24.0';
|
||||||
export const eslintVersion = '~8.12.0';
|
export const eslintVersion = '~8.15.0';
|
||||||
export const eslintConfigPrettierVersion = '8.1.0';
|
export const eslintConfigPrettierVersion = '8.1.0';
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user