Compare commits

...

65 Commits

Author SHA1 Message Date
Jason Jean fbeb10ca77 Release 12.6.6 2021-08-10 18:24:08 -04:00
Nrwl CI Machine 6cd612094b fix(misc): minor fixes in readme files 2021-08-10 16:05:09 -04:00
amir toole 23d4e07516 docs(nxdev): fix typo in project-graph-plugin guide (#6655) 2021-08-10 16:05:09 -04:00
Leosvel Pérez Espinosa 30cf46b9fe fix(angular): init cypress correctly if needed when creating an app (#6652) 2021-08-10 16:05:09 -04:00
Leosvel Pérez Espinosa 4cdabc4e05 fix(core): fix prompt support for enum definitions (#6651) 2021-08-10 16:05:09 -04:00
Philip Fulcher cc2a9056d5 fix(misc): fix affected:dep-graph file output (#6581) 2021-08-10 16:05:09 -04:00
Jason Jean cfb0ccdf0a fix(angular): fix angular projects not being standalone when all other projects are standalone (#6641) 2021-08-10 16:05:09 -04:00
Leosvel Pérez Espinosa a168ac81af fix(core): default run-many to use provided projects order (#6632) 2021-08-10 16:05:09 -04:00
Nrwl CI Machine 777b7b4331 cleanup(misc): avoid importing rxjs in the core path 2021-08-10 16:05:09 -04:00
Jack Hsu 8093e1ebf9 fix(react): relax babel dependency versions (#6637) 2021-08-10 16:05:09 -04:00
Kirils L ce0548b0eb fix(nextjs): update build and serve schemas (#6553) 2021-08-10 16:03:21 -04:00
Jack Hsu 1eb1fe5c33 fix(nextjs): add missing dependency to @nrwl/devkit (#6633) 2021-08-10 16:03:21 -04:00
Brandon efd432046b docs(core): update deep dive on computation caching (#6622) 2021-08-10 16:03:21 -04:00
Miroslav Jonaš e0fae4a38b chore(repo): enforce fixed version for local packages in e2e tests (#6628) 2021-08-10 16:03:21 -04:00
Miroslav Jonaš 36c466aa84 chore(repo): add isOsx for e2e tests and include macos to nightly (#6627) 2021-08-10 16:03:21 -04:00
Miroslav Jonaš d714e1b7cd chore(angular): enable all e2e tests for npm pm (#6625) 2021-08-10 16:02:35 -04:00
Chau Tran 9785dd12c3 fix(core): ensure to only passthrough verbose if isVerbose is true (#6607)
* fix(core): ensure to only passthrough verbose if isVerbose is true

ISSUES CLOSED: #6606

* fix(core): update applyVerbosity test

Co-authored-by: Chau Tran <ctran@Chaus-MacBook-Pro.local>
2021-08-10 16:02:35 -04:00
Jason Jean 4b9f797724 Release 12.6.5 2021-08-05 12:20:34 -04:00
Jason Jean 9c0180fb0e fix(angular): lock version of angular-devkit to ~12.1.0 (#6620) 2021-08-05 12:17:07 -04:00
Victor Savkin e1c578be01 fix(misc): NxCloud activation link is not displayed (#6619) 2021-08-05 12:17:02 -04:00
Leosvel Pérez Espinosa 237582082d fix(misc): read settings in .editorconfig when formatting files in generators (#6616) 2021-08-05 12:16:58 -04:00
Leosvel Pérez Espinosa 4a992823db fix(core): fix reading nx.json without projects property (#6613) 2021-08-05 12:16:35 -04:00
Leosvel Pérez Espinosa 1f282339e8 fix(testing): handle migrating base jest config without projects (#6601) 2021-08-05 12:16:07 -04:00
Jason Jean c7d13865ec Release 12.6.4 2021-08-04 10:17:00 -04:00
Ian Luca 9ddc072a5d fix(core): define fileExist method for ts host (#6582)
closes #6500
2021-08-03 18:39:24 -04:00
Colum Ferry 770f8b6f98 fix(angular): webpack-server needs to work when there is no defaultConfiguration set (#6588) 2021-08-03 18:39:24 -04:00
Chau Tran 463b9c244d fix(core): apply verbose flag to combined options if the schema allows it (#6593)
`--verbose` flag is spliced from the command args upon invoking nx commands. This PR makes sure to
set the `verbose` property based on `isVerbose` flag if the Schema allows it

ISSUES CLOSED: #6520 #4160

Co-authored-by: Chau Tran <ctran@Chaus-MacBook-Pro.local>
Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
2021-08-03 18:39:24 -04:00
Leosvel Pérez Espinosa 3adfa08da3 fix(core): flush changes using the tree write file options (#6592) 2021-08-03 18:39:24 -04:00
Jason Jean 1308aa7fc9 fix(core): warn for project-graph error while it is experimental (#6562) 2021-08-03 18:39:24 -04:00
Juri Strumpflohner 3ef275cf1d docs(storybook): re-arrange content for a more concise Storybook overview guide (#6555)
* docs(storybook): re-arrange content for a more concise Storybook overview guide

* docs(storybook): re-arrange content to have a more concise Storybook guide
2021-08-03 10:22:55 -04:00
Jason Jean 01ec0ab89c fix(core): add better option validation (#6557) 2021-08-03 10:22:55 -04:00
Jack Hsu 12e337e67d fix(web): remove unnecessary packages from being installed with @nrwl/web (#6554) 2021-08-03 10:22:55 -04:00
Kirils L 28fa04abe9 fix(nextjs): use next.js image types (#6556) 2021-08-03 10:22:55 -04:00
Juri Strumpflohner 81d779d9ad fix(node): change default debug port to 9229 to allow for easy debugging (#6536) 2021-08-03 10:22:55 -04:00
Miroslav Jonaš 010490ee70 fix(core): target project locator should handle tsconfig paths fully (#6528)
* fix(core): target project locator should handle local package versions

* fix(core): improve path matching on target project locator

* chore(core): revert appRootPath change in the typescript file

* fix(repo): normalize module path before comparison
2021-08-03 10:22:55 -04:00
Benjamin Cabanes 2e6dd21160 docs(core): nxdev has smooth scroll behaviour (#6552) 2021-08-03 10:22:55 -04:00
Jack Hsu 4c038b7fcb fix(nextjs): generate nextjs library with "next/babel" preset rather than the default "@nrwl/react/babel" preset (#6545) 2021-08-03 10:22:55 -04:00
Jack Hsu bfa35b5f7f fix(testing): remove installation of babel packages for jest projects (#6546) 2021-08-03 10:22:55 -04:00
Leosvel Pérez Espinosa 2025a86d1d fix(misc): make generated schemas compliant with json schema spec (#6548) 2021-08-03 10:22:55 -04:00
Jason Jean f2f8440d78 Release 12.6.3 2021-07-29 19:12:39 -04:00
Phillip Barta b7fb7f2ce5 feat(core): updated dotenv and switched to import 'dotenv/config' (#5615) 2021-07-29 18:21:03 -04:00
Edouard Bozon 15ea35da52 feat(devkit): make nx.json optional (#6398)
* feat(devkit): make nx.json optional (#5678)

Allow project configuration functions to work without nx.json configuration file, this is particulary handy for regular Angular CLI projects.

* docs(devkit): make `NxJsonConfiguration` partial

Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
2021-07-29 18:20:58 -04:00
erikagiroux 395df05a32 fix(devkit): add font file extensions to binaryExts in generate-files.ts (#6439)
Add font file extensions to the list of extensions that should not be rendered with ejs

ISSUES CLOSED: #5213

Co-authored-by: egiroux <erika.giroux@ubisoft.com>
2021-07-29 18:20:41 -04:00
James Henry 4f23692eac chore(core): refactor executors to always read from cached project graph (#6446) 2021-07-29 18:20:35 -04:00
Jack Hsu 749c640478 feat(react): add fast refresh support for webpack 5 (#6529) 2021-07-29 18:20:21 -04:00
Jason Jean b1eca69733 cleanup(devkit): rename all variable names of host to tree 2021-07-29 18:19:55 -04:00
Leosvel Pérez Espinosa 5fd0ad27b9 fix(misc): fix moving projects with standalone configuration (#6521) 2021-07-29 18:19:43 -04:00
Leosvel Pérez Espinosa 90c56aa574 fix(core): do not override process.env with variables in dotenv files (#6540) 2021-07-29 18:19:30 -04:00
Miroslav Jonaš 58f9fcd320 cleanup(core): use isNpmProject and cleanup project graph utils (#6522)
* cleanup(core): use isNpmProject and cleanup project graph utils

* chore(core): mark utils/buildable-libs-utils as deprecated
2021-07-29 18:19:25 -04:00
Juri Strumpflohner 863cb475ab fix(react): align component and e2e test generation (#6535) 2021-07-29 18:19:19 -04:00
Miroslav Jonaš a312a5ae4f chore(repo): add missing members of the nx core team (#6530) 2021-07-29 18:19:09 -04:00
Miroslav Jonaš 38ba9fd65e cleanup(core): remove last references to workspace appRootPath (#6527)
* cleanup(core): remove last references to local appRootPath

* chore(core): add deprecation comment to appRootPath

* chore(node): fix failing test due to typescript change
2021-07-29 18:18:53 -04:00
Jason Jean 8040ef7858 fix(angular): add eslint to protractor apps (#6524) 2021-07-29 18:18:40 -04:00
Brandon 736037186b docs(core): update migration docs for adding to monorepo (#6432) 2021-07-29 18:18:29 -04:00
vsavkin 2c38967390 chore(repo): update @nrwl/nx-cloud 2021-07-29 18:18:24 -04:00
Juri Strumpflohner d04cc8ee83 docs(core): adjust typo in workspace generator docs (#6508) 2021-07-29 18:18:17 -04:00
Jack Hsu 8a93d39ba0 docs(nextjs): updated Next.js link from React intro page (#6510) 2021-07-29 18:18:04 -04:00
Miroslav Jonaš eba3acb3d5 chore(repo): switch to using nx orb on circleci workflows (#6505)
* chore(repo): switch to using nx orb on circleci workflows

* chore(repo): set proper name of the main branch
2021-07-29 18:17:05 -04:00
Jason Jean 99af8f8f07 chore(repo): remove dependency from dep-graph to workspace and run-co… (#6497)
* chore(repo): remove dependency from dep-graph to workspace and run-command

* chore(repo): change default build config for dep-graph

Co-authored-by: Philip Fulcher <philip@nrwl.io>
2021-07-29 18:16:44 -04:00
Leosvel Pérez Espinosa 3f3541846f fix(misc): handle moving to a subfolder which results in the same project name and normalize import path (#6507) 2021-07-29 18:16:15 -04:00
Kirils L a7e76b6e43 docs(nextjs): add vercel deployment affected section (#6495) 2021-07-29 18:14:45 -04:00
Jack Hsu c31ae42821 docs(core): fix 500 error when directing from framework specific pages to intro page (#6492) 2021-07-29 18:14:37 -04:00
Leosvel Pérez Espinosa 5a1105aa27 fix(misc): allow run-commands to accept readyWhen for a single command (#6496) 2021-07-29 18:14:24 -04:00
Jason Jean cc02bba571 Release 12.6.2 2021-07-23 10:38:04 -04:00
Jason Jean 4742f60053 Release 12.6.1 2021-07-23 10:31:11 -04:00
237 changed files with 3720 additions and 2302 deletions
+15 -18
View File
@@ -11,6 +11,9 @@ dependencies:
cache_directories:
- ~/.cache/yarn
orbs:
nx: nrwl/nx@1.0.0
executors:
linux:
working_directory: *working_directory
@@ -126,27 +129,24 @@ jobs:
- run:
name: Check Package dependencies
command: yarn depcheck
- run:
name: Get Last Sucessful Workflow Run
command: |
source ./scripts/circleci/get-successful-run.sh << pipeline.project.type >> $CIRCLE_PROJECT_USERNAME $CIRCLE_PROJECT_REPONAME $CIRCLE_BRANCH master false
echo "export BASE_SHA=\"$BASE_SHA\";" >> $BASH_ENV
- nx/set-shas:
main-branch-name: 'master'
- run:
name: Run Builds
command: |
npx nx affected --target=build --base=$BASE_SHA --parallel --max-parallel=3
npx nx affected --target=build --base=$NX_BASE --parallel --max-parallel=3
- run:
name: Run Unit Tests
command: |
npx nx affected --target=test --base=$BASE_SHA --parallel --max-parallel=2
npx nx affected --target=test --base=$NX_BASE --parallel --max-parallel=2
- run:
name: Run Linting
command: |
npx nx affected --target=lint --base=$BASE_SHA --parallel --max-parallel=4
npx nx affected --target=lint --base=$NX_BASE --parallel --max-parallel=4
- run:
name: Run E2E Tests
command: |
npx nx affected --target=e2e --base=$BASE_SHA
npx nx affected --target=e2e --base=$NX_BASE
no_output_timeout: 45m
- run:
name: Stop All Running Agents for This CI Run
@@ -171,23 +171,20 @@ jobs:
steps:
- setup:
os: << parameters.os >>
- run:
name: Get Last Sucessful Workflow Run
command: |
source ./scripts/circleci/get-successful-run.sh << pipeline.project.type >> $CIRCLE_PROJECT_USERNAME $CIRCLE_PROJECT_REPONAME $CIRCLE_BRANCH master false
echo "export BASE_SHA=\"$BASE_SHA\";" >> $BASH_ENV
- nx/set-shas:
main-branch-name: 'master'
- run:
name: Run Builds
command: npx nx affected --target=build --base=$BASE_SHA --parallel --max-parallel=3
command: npx nx affected --target=build --base=$NX_BASE --parallel --max-parallel=3
- run:
name: Run Unit Tests
command: npx nx affected --target=test --base=$BASE_SHA --parallel --max-parallel=2
command: npx nx affected --target=test --base=$NX_BASE --parallel --max-parallel=2
- run:
name: Run Linting
command: npx nx affected --target=lint --base=$BASE_SHA --parallel --max-parallel=4
command: npx nx affected --target=lint --base=$NX_BASE --parallel --max-parallel=4
- run:
name: Run E2E Tests
command: npx nx affected --target=e2e --base=$BASE_SHA
command: npx nx affected --target=e2e --base=$NX_BASE
no_output_timeout: 45m
- run:
name: Stop All Running Agents for This CI Run
+8 -1
View File
@@ -17,13 +17,20 @@ jobs:
matrix:
os:
- ubuntu-latest
- macos-latest
# - windows-latest
include:
- os: ubuntu-latest
os-name: ubuntu
- os: macos-latest
os-name: mac
# - os: windows-latest
# os-name: windows
# exclude:
exclude:
- os: macos-latest
package_manager: npm
- os: macos-latest
package_manager: pnpm
# - os: windows-latest
# package_manager: npm
# - os: windows-latest
+17 -12
View File
@@ -128,17 +128,22 @@ help you get started.
| ![Victor Savkin](https://avatars1.githubusercontent.com/u/35996?s=150) | ![Jason Jean](https://avatars2.githubusercontent.com/u/8104246?s=150) | ![Benjamin Cabanes](https://avatars2.githubusercontent.com/u/3447705?s=150) | ![Brandon Roberts](https://avatars1.githubusercontent.com/u/42211?s=150) |
| [vsavkin](https://github.com/vsavkin) | [FrozenPandaz](https://github.com/FrozenPandaz) | [bcabanes](https://github.com/bcabanes) | [brandonroberts](https://github.com/brandonroberts) |
| Jack Hsu | Jo Hanna Pearce | Jon Cammisuli | Isaac Mann |
| --------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| ![Jack Hsu](https://avatars0.githubusercontent.com/u/53559?s=150&v=4) | ![Jo Hanna Pearce](https://avatars1.githubusercontent.com/u/439121?s=150&v=4) | ![Jon Cammisuli](https://avatars2.githubusercontent.com/u/4332460?s=150&v=4) | ![Isaac Mann](https://avatars1.githubusercontent.com/u/861504?s=150) |
| [jaysoo](https://github.com/jaysoo) | [jdpearce](https://github.com/jdpearce) | [cammisuli](https://github.com/cammisuli) | [isaacplmann](https://github.com/isaacplmann) |
| Jack Hsu | Jo Hanna Pearce | Jon Cammisuli | Isaac Mann |
| ----------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------ | -------------------------------------------------------------------- |
| ![Jack Hsu](https://avatars0.githubusercontent.com/u/53559?s=150) | ![Jo Hanna Pearce](https://avatars1.githubusercontent.com/u/439121?s=150) | ![Jon Cammisuli](https://avatars2.githubusercontent.com/u/4332460?s=150) | ![Isaac Mann](https://avatars1.githubusercontent.com/u/861504?s=150) |
| [jaysoo](https://github.com/jaysoo) | [jdpearce](https://github.com/jdpearce) | [cammisuli](https://github.com/cammisuli) | [isaacplmann](https://github.com/isaacplmann) |
| Tasos Bekos | Juri Strumpflohner | Philip Fulcher | Katerina Skroumpelou |
| ------------------------------------------------------------------------ | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| ![Tasos Bekos](https://avatars.githubusercontent.com/u/551595?s=150&v=4) | ![Juri Strumpflohner](https://avatars1.githubusercontent.com/u/542458?s=150&v=4) | ![Philip Fulcher](https://avatars1.githubusercontent.com/u/1536471?s=150) | ![Katerina Skroumpelou](https://avatars0.githubusercontent.com/u/6603745?s=150&v=4) |
| [bekos](https://github.com/bekos) | [juristr](https://github.com/juristr) | [philipjfulcher](https://github.com/philipjfulcher) | [mandarini](https://github.com/mandarini) |
| Juri Strumpflohner | Philip Fulcher | Kirils Ladovs | Katerina Skroumpelou |
| ---------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| ![Juri Strumpflohner](https://avatars1.githubusercontent.com/u/542458?s=150) | ![Philip Fulcher](https://avatars1.githubusercontent.com/u/1536471?s=150) | ![Kirils Ladovs](https://avatars.githubusercontent.com/u/9858620?s=150) | ![Katerina Skroumpelou](https://avatars0.githubusercontent.com/u/6603745?s=150) |
| [juristr](https://github.com/juristr) | [philipjfulcher](https://github.com/philipjfulcher) | [kirjai](https://github.com/kirjai) | [mandarini](https://github.com/mandarini) |
| Kirils Ladovs |
| --------------------------------------------------------------------------- |
| ![Kirils Ladovs](https://avatars.githubusercontent.com/u/9858620?s=150&v=4) |
| [kirjai](https://github.com/kirjai) |
| Colum Ferry | Emily Xiong | Miroslav Jonaš | Leosvel Pérez Espinosa |
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| ![Colum Ferry](https://avatars.githubusercontent.com/u/12140467?s=150) | ![Emily Xiong](https://avatars.githubusercontent.com/u/16211801?s=150) | ![Miroslav Jonaš](https://avatars.githubusercontent.com/u/881612?s=150) | ![Leosvel Pérez Espinosa](https://avatars.githubusercontent.com/u/12051310?s=150) |
| [Coly010](https://github.com/Coly010) | [xiongemi](https://github.com/xiongemi) | [meeroslav](https://github.com/meeroslav) | [leosvelperez](https://github.com/leosvelperez) |
| Zachary DeRose | Craigory Coppola |
| ------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
| ![Zachary DeRose](https://avatars.githubusercontent.com/u/3788405?s=150) | ![Craigory Coppola](https://avatars.githubusercontent.com/u/6933928?s=150) |
| [ZackDeRose](https://github.com/ZackDeRose) | [AgentEnder](https://github.com/AgentEnder) |
+27 -16
View File
@@ -12,29 +12,43 @@
"main": "dep-graph/dep-graph/src/main.ts",
"polyfills": "dep-graph/dep-graph/src/polyfills.ts",
"tsConfig": "dep-graph/dep-graph/tsconfig.app.json",
"assets": [
"dep-graph/dep-graph/src/favicon.ico",
"dep-graph/dep-graph/src/assets"
],
"styles": ["dep-graph/dep-graph/src/styles.scss"],
"scripts": []
"scripts": [],
"assets": [],
"optimization": true,
"outputHashing": "none",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
},
"configurations": {
"release": {
"dev": {
"fileReplacements": [
{
"replace": "dep-graph/dep-graph/src/environments/environment.ts",
"with": "dep-graph/dep-graph/src/environments/environment.release.ts"
"with": "dep-graph/dep-graph/src/environments/environment.dev.ts"
}
],
"assets": [],
"optimization": true,
"assets": [
"dep-graph/dep-graph/src/favicon.ico",
"dep-graph/dep-graph/src/assets"
],
"optimization": false,
"outputHashing": "none",
"sourceMap": false,
"sourceMap": true,
"extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"extractLicenses": false,
"vendorChunk": true,
"budgets": [
{
"type": "initial",
@@ -72,12 +86,9 @@
"serve": {
"executor": "@nrwl/web:dev-server",
"options": {
"buildTarget": "dep-graph-dep-graph:build-base"
"buildTarget": "dep-graph-dep-graph:build-base:dev"
},
"configurations": {
"release": {
"buildTarget": "dep-graph-dep-graph:build-base:release"
},
"watch": {
"buildTarget": "dep-graph-dep-graph:build-base:watch"
}
+4 -6
View File
@@ -1,5 +1,6 @@
import { DepGraphClientResponse } from '@nrwl/workspace';
import { ProjectGraph } from '@nrwl/workspace/src/core/project-graph';
// nx-ignore-next-line
import type { DepGraphClientResponse } from '@nrwl/workspace/src/command-line/dep-graph';
import { ProjectGraph } from '@nrwl/devkit';
import { combineLatest, fromEvent, Subject } from 'rxjs';
import { startWith, takeUntil } from 'rxjs/operators';
import { DebuggerPanel } from './debugger-panel';
@@ -55,10 +56,7 @@ export class AppComponent {
dependencies: project.dependencies,
nodes: nodes,
};
window.affected = project.affected;
window.exclude = project.exclude;
window.focusedProject = project.focus;
window.groupByFolder = project.groupByFolder;
window.projectGraphList = this.config.projectGraphs;
window.selectedProjectGraph = projectGraphId;
window.workspaceLayout = workspaceLayout;
@@ -1,4 +1,5 @@
import { DepGraphClientResponse } from '@nrwl/workspace';
// nx-ignore-next-line
import { DepGraphClientResponse } from '@nrwl/workspace/src/command-line/dep-graph';
import { ProjectGraphService } from './models';
export class FetchProjectGraphService implements ProjectGraphService {
@@ -1,4 +1,5 @@
import { DepGraphClientResponse } from '@nrwl/workspace';
// nx-ignore-next-line
import { DepGraphClientResponse } from '@nrwl/workspace/src/command-line/dep-graph';
import { ProjectGraphService } from './models';
export class LocalProjectGraphService implements ProjectGraphService {
@@ -1,5 +1,6 @@
import { ProjectGraphDependency } from '@nrwl/devkit';
import { DepGraphClientProject, DepGraphClientResponse } from '@nrwl/workspace';
import { ProjectGraphDependency, ProjectGraphNode } from '@nrwl/devkit';
// nx-ignore-next-line
import { DepGraphClientResponse } from '@nrwl/workspace/src/command-line/dep-graph';
import { ProjectGraphService } from '../app/models';
export class MockProjectGraphService implements ProjectGraphService {
@@ -58,7 +59,7 @@ export class MockProjectGraphService implements ProjectGraphService {
return new Promise((resolve) => resolve(this.response));
}
private createNewProject(): DepGraphClientProject {
private createNewProject(): ProjectGraphNode {
const type = Math.random() > 0.25 ? 'lib' : 'app';
const name = `${type}-${this.response.projects.length + 1}`;
+2 -1
View File
@@ -1,4 +1,5 @@
import { DepGraphClientResponse } from '@nrwl/workspace';
// nx-ignore-next-line
import { DepGraphClientResponse } from '@nrwl/workspace/src/command-line/dep-graph';
export interface ProjectGraphList {
id: string;
@@ -1,18 +1,13 @@
import { FetchProjectGraphService } from '../app/fetch-project-graph-service';
import { Environment } from '../app/models';
import { projectGraphs } from '../graphs';
export const environment: Environment = {
environment: 'release',
environment: 'dev',
appConfig: {
showDebugger: false,
projectGraphs: [
{
id: 'local',
label: 'local',
url: 'projectGraph.json',
},
],
defaultProjectGraph: 'local',
showDebugger: true,
projectGraphs,
defaultProjectGraph: 'nx',
projectGraphService: new FetchProjectGraphService(),
},
};
@@ -1,13 +1,18 @@
import { FetchProjectGraphService } from '../app/fetch-project-graph-service';
import { Environment } from '../app/models';
import { projectGraphs } from '../graphs';
export const environment: Environment = {
environment: 'dev',
environment: 'release',
appConfig: {
showDebugger: true,
projectGraphs,
defaultProjectGraph: 'nx',
showDebugger: false,
projectGraphs: [
{
id: 'local',
label: 'local',
url: 'projectGraph.json',
},
],
defaultProjectGraph: 'local',
projectGraphService: new FetchProjectGraphService(),
},
};
+3 -6
View File
@@ -1,9 +1,6 @@
import { WorkspaceConfiguration } from '@nrwl/devkit';
import {
DepGraphClientResponse,
ProjectGraph,
ProjectGraphNode,
} from '@nrwl/workspace';
// nx-ignore-next-line
import { DepGraphClientResponse } from '@nrwl/workspace/src/command-line/dep-graph';
import { ProjectGraph, ProjectGraphNode } from '@nrwl/devkit';
import { ProjectGraphList } from './graphs';
export declare global {
-8
View File
@@ -1,14 +1,6 @@
import { AppComponent } from './app/app';
import { LocalProjectGraphService } from './app/local-project-graph-service';
import { environment } from './environments/environment';
import { projectGraphs } from './graphs';
if (environment.environment !== 'release') {
window.affected = [];
window.exclude = [];
window.projectGraphList = projectGraphs;
window.selectedProjectGraph = projectGraphs[0].id;
}
if (environment.environment === 'dev-watch') {
window.watch = true;
-1
View File
@@ -1 +0,0 @@
import 'document-register-element';
@@ -56,6 +56,16 @@ Type: `string`
The new import path to use in the `tsconfig.base.json`.
### skipFormat
Alias(es): skip-format
Default: `false`
Type: `boolean`
Skip formatting files.
### updateImportPath
Default: `true`
+12 -12
View File
@@ -6,6 +6,18 @@ Options can be configured in `angular.json` when defining the executor, or when
## Options
### outputPath (_**required**_)
Type: `string`
The output path of the generated files.
### root (_**required**_)
Type: `string`
The source root
### buildLibsFromSource
Default: `true`
@@ -37,15 +49,3 @@ The file to replace with.
Type: `string`
Path (relative to workspace root) to a function which takes phase, config, and builder options, and returns the resulting config. This is an advanced option and should not be used with a normal Next.js config file (i.e. next.config.js).
### outputPath
Type: `string`
The output path of the generated files.
### root
Type: `string`
The source root
+6 -6
View File
@@ -6,6 +6,12 @@ Options can be configured in `angular.json` when defining the executor, or when
## Options
### buildTarget (_**required**_)
Type: `string`
Target which builds the application
### buildLibsFromSource
Default: `true`
@@ -14,12 +20,6 @@ Type: `boolean`
Read buildable libraries from source instead of building them separately.
### buildTarget
Type: `string`
Target which builds the application
### customServerPath
Type: `string`
+1 -1
View File
@@ -36,7 +36,7 @@ Ensures the app is starting with debugging
### port
Default: `0`
Default: `9229`
Type: `number`
+64 -44
View File
@@ -72,6 +72,7 @@
- [getWorkspaceLayout](../../angular/nx-devkit/index#getworkspacelayout)
- [getWorkspacePath](../../angular/nx-devkit/index#getworkspacepath)
- [installPackagesTask](../../angular/nx-devkit/index#installpackagestask)
- [isStandaloneProject](../../angular/nx-devkit/index#isstandaloneproject)
- [joinPathFragments](../../angular/nx-devkit/index#joinpathfragments)
- [moveFilesToNewDirectory](../../angular/nx-devkit/index#movefilestonewdirectory)
- [names](../../angular/nx-devkit/index#names)
@@ -481,7 +482,7 @@ Implementation of a target of a project that handles multiple projects to be bat
### WorkspaceConfiguration
Ƭ **WorkspaceConfiguration**: `Omit`<[`WorkspaceJsonConfiguration`](../../angular/nx-devkit/index#workspacejsonconfiguration), `"projects"`\> & `Omit`<[`NxJsonConfiguration`](../../angular/nx-devkit/index#nxjsonconfiguration), `"projects"`\>
Ƭ **WorkspaceConfiguration**: `Omit`<[`WorkspaceJsonConfiguration`](../../angular/nx-devkit/index#workspacejsonconfiguration), `"projects"`\> & `Partial`<`Omit`<[`NxJsonConfiguration`](../../angular/nx-devkit/index#nxjsonconfiguration), `"projects"`\>\>
## Variables
@@ -504,14 +505,14 @@ Implementation of a target of a project that handles multiple projects to be bat
### addDependenciesToPackageJson
**addDependenciesToPackageJson**(`host`, `dependencies`, `devDependencies`, `packageJsonPath?`): [`GeneratorCallback`](../../angular/nx-devkit/index#generatorcallback)
**addDependenciesToPackageJson**(`tree`, `dependencies`, `devDependencies`, `packageJsonPath?`): [`GeneratorCallback`](../../angular/nx-devkit/index#generatorcallback)
Add Dependencies and Dev Dependencies to package.json
For example:
```typescript
addDependenciesToPackageJson(host, { react: 'latest' }, { jest: 'latest' });
addDependenciesToPackageJson(tree, { react: 'latest' }, { jest: 'latest' });
```
This will **add** `react` and `jest` to the dependencies and devDependencies sections of package.json respectively.
@@ -520,7 +521,7 @@ This will **add** `react` and `jest` to the dependencies and devDependencies sec
| Name | Type | Default value | Description |
| :---------------- | :------------------------------------------- | :--------------- | :---------------------------------------------------------------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) | `undefined` | Tree representing file system to modify |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) | `undefined` | Tree representing file system to modify |
| `dependencies` | `Record`<`string`, `string`\> | `undefined` | Dependencies to be added to the dependencies section of package.json |
| `devDependencies` | `Record`<`string`, `string`\> | `undefined` | Dependencies to be added to the devDependencies section of package.json |
| `packageJsonPath` | `string` | `'package.json'` | Path to package.json |
@@ -535,7 +536,7 @@ Callback to install dependencies only if necessary. undefined is returned if cha
### addProjectConfiguration
**addProjectConfiguration**(`host`, `projectName`, `projectConfiguration`, `standalone?`): `void`
**addProjectConfiguration**(`tree`, `projectName`, `projectConfiguration`, `standalone?`): `void`
Adds project configuration to the Nx workspace.
@@ -546,7 +547,7 @@ both files.
| Name | Type | Default value | Description |
| :--------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------ | :----------------------------------------------------------------------------------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) | `undefined` | the file system tree |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) | `undefined` | the file system tree |
| `projectName` | `string` | `undefined` | unique name. Often directories are part of the name (e.g., mydir-mylib) |
| `projectConfiguration` | [`ProjectConfiguration`](../../angular/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../angular/nx-devkit/index#nxjsonprojectconfiguration) | `undefined` | project configuration |
| `standalone` | `boolean` | `false` | should the project use package.json? If false, the project config is inside workspace.json |
@@ -693,7 +694,7 @@ Detects which package manager is used in the workspace based on the lock file.
### formatFiles
**formatFiles**(`host`): `Promise`<`void`\>
**formatFiles**(`tree`): `Promise`<`void`\>
Formats all the created or updated files using Prettier
@@ -701,7 +702,7 @@ Formats all the created or updated files using Prettier
| Name | Type | Description |
| :----- | :------------------------------------------- | :------------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) | the file system tree |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) | the file system tree |
#### Returns
@@ -711,7 +712,7 @@ Formats all the created or updated files using Prettier
### generateFiles
**generateFiles**(`host`, `srcFolder`, `target`, `substitutions`): `void`
**generateFiles**(`tree`, `srcFolder`, `target`, `substitutions`): `void`
Generates a folder of files based on provided templates.
@@ -723,7 +724,7 @@ While doing so it performs two substitutions:
Examples:
```typescript
generateFiles(host, path.join(__dirname, 'files'), './tools/scripts', {
generateFiles(tree, path.join(__dirname, 'files'), './tools/scripts', {
tmpl: '',
name: 'myscript',
});
@@ -739,9 +740,9 @@ doesn't get confused about incorrect TypeScript files.
| Name | Type | Description |
| :-------------- | :------------------------------------------- | :-------------------------------------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) | the file system tree |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) | the file system tree |
| `srcFolder` | `string` | the source folder of files (absolute path) |
| `target` | `string` | the target folder (relative to the host root) |
| `target` | `string` | the target folder (relative to the tree root) |
| `substitutions` | `Object` | an object of key-value pairs |
#### Returns
@@ -798,7 +799,7 @@ but it can also be passed in explicitly.
### getProjects
**getProjects**(`host`): `Map`<`string`, [`ProjectConfiguration`](../../angular/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../angular/nx-devkit/index#nxjsonprojectconfiguration)\>
**getProjects**(`tree`): `Map`<`string`, [`ProjectConfiguration`](../../angular/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../angular/nx-devkit/index#nxjsonprojectconfiguration)\>
Get a map of all projects in a workspace.
@@ -808,7 +809,7 @@ Use [readProjectConfiguration](../../angular/nx-devkit/index#readprojectconfigur
| Name | Type |
| :----- | :------------------------------------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) |
#### Returns
@@ -818,7 +819,7 @@ Use [readProjectConfiguration](../../angular/nx-devkit/index#readprojectconfigur
### getWorkspaceLayout
**getWorkspaceLayout**(`host`): `Object`
**getWorkspaceLayout**(`tree`): `Object`
Returns workspace defaults. It includes defaults folders for apps and libs,
and the default scope.
@@ -833,7 +834,7 @@ Example:
| Name | Type | Description |
| :----- | :------------------------------------------- | :--------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) | file system tree |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) | file system tree |
#### Returns
@@ -850,13 +851,13 @@ Example:
### getWorkspacePath
**getWorkspacePath**(`host`): `string`
**getWorkspacePath**(`tree`): `string`
#### Parameters
| Name | Type |
| :----- | :------------------------------------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) |
#### Returns
@@ -866,7 +867,7 @@ Example:
### installPackagesTask
**installPackagesTask**(`host`, `alwaysRun?`, `cwd?`, `packageManager?`): `void`
**installPackagesTask**(`tree`, `alwaysRun?`, `cwd?`, `packageManager?`): `void`
Runs `npm install` or `yarn install`. It will skip running the install if
`package.json` hasn't changed at all or it hasn't changed since the last invocation.
@@ -875,7 +876,7 @@ Runs `npm install` or `yarn install`. It will skip running the install if
| Name | Type | Default value | Description |
| :--------------- | :--------------------------------------------------------------- | :------------ | :------------------------------------------------------------ |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) | `undefined` | the file system tree |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) | `undefined` | the file system tree |
| `alwaysRun` | `boolean` | `false` | always run the command even if `package.json` hasn't changed. |
| `cwd` | `string` | `''` | - |
| `packageManager` | [`PackageManager`](../../angular/nx-devkit/index#packagemanager) | `undefined` | - |
@@ -886,6 +887,25 @@ Runs `npm install` or `yarn install`. It will skip running the install if
---
### isStandaloneProject
**isStandaloneProject**(`tree`, `project`): `boolean`
Returns if a project has a standalone configuration (project.json).
#### Parameters
| Name | Type | Description |
| :-------- | :------------------------------------------- | :------------------- |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) | the file system tree |
| `project` | `string` | the project name |
#### Returns
`boolean`
---
### joinPathFragments
**joinPathFragments**(...`fragments`): `string`
@@ -906,13 +926,13 @@ Normalized path fragments and joins them
### moveFilesToNewDirectory
**moveFilesToNewDirectory**(`host`, `oldDir`, `newDir`): `void`
**moveFilesToNewDirectory**(`tree`, `oldDir`, `newDir`): `void`
#### Parameters
| Name | Type |
| :------- | :------------------------------------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) |
| `oldDir` | `string` |
| `newDir` | `string` |
@@ -1053,9 +1073,9 @@ parseTargetString('proj:test:production'); // returns { project: "proj", target:
### readJson
**readJson**<`T`\>(`host`, `path`, `options?`): `T`
**readJson**<`T`\>(`tree`, `path`, `options?`): `T`
Reads a document for host, removes all comments and parses JSON.
Reads a json file, removes all comments and parses JSON.
#### Type parameters
@@ -1067,7 +1087,7 @@ Reads a document for host, removes all comments and parses JSON.
| Name | Type | Description |
| :--------- | :------------------------------------------------------------------- | :-------------------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) | file system tree |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) | file system tree |
| `path` | `string` | file path |
| `options?` | [`JsonParseOptions`](../../angular/nx-devkit/index#jsonparseoptions) | Optional JSON Parse Options |
@@ -1106,7 +1126,7 @@ Object the JSON content of the file represents
### readProjectConfiguration
**readProjectConfiguration**(`host`, `projectName`): [`ProjectConfiguration`](../../angular/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../angular/nx-devkit/index#nxjsonprojectconfiguration)
**readProjectConfiguration**(`tree`, `projectName`): [`ProjectConfiguration`](../../angular/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../angular/nx-devkit/index#nxjsonprojectconfiguration)
Reads a project configuration.
@@ -1119,7 +1139,7 @@ both files.
| Name | Type | Description |
| :------------ | :------------------------------------------- | :---------------------------------------------------------------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) | the file system tree |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) | the file system tree |
| `projectName` | `string` | unique name. Often directories are part of the name (e.g., mydir-mylib) |
#### Returns
@@ -1157,7 +1177,7 @@ Works as if you invoked the target yourself without passing any command lint ove
### readWorkspaceConfiguration
**readWorkspaceConfiguration**(`host`): [`WorkspaceConfiguration`](../../angular/nx-devkit/index#workspaceconfiguration)
**readWorkspaceConfiguration**(`tree`): [`WorkspaceConfiguration`](../../angular/nx-devkit/index#workspaceconfiguration)
Read general workspace configuration such as the default project or cli settings
@@ -1167,7 +1187,7 @@ This does _not_ provide projects configuration, use [readProjectConfiguration](.
| Name | Type |
| :----- | :------------------------------------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) |
#### Returns
@@ -1177,14 +1197,14 @@ This does _not_ provide projects configuration, use [readProjectConfiguration](.
### removeDependenciesFromPackageJson
**removeDependenciesFromPackageJson**(`host`, `dependencies`, `devDependencies`, `packageJsonPath?`): [`GeneratorCallback`](../../angular/nx-devkit/index#generatorcallback)
**removeDependenciesFromPackageJson**(`tree`, `dependencies`, `devDependencies`, `packageJsonPath?`): [`GeneratorCallback`](../../angular/nx-devkit/index#generatorcallback)
Remove Dependencies and Dev Dependencies from package.json
For example:
```typescript
removeDependenciesFromPackageJson(host, ['react'], ['jest']);
removeDependenciesFromPackageJson(tree, ['react'], ['jest']);
```
This will **remove** `react` and `jest` from the dependencies and devDependencies sections of package.json respectively.
@@ -1193,7 +1213,7 @@ This will **remove** `react` and `jest` from the dependencies and devDependencie
| Name | Type | Default value | Description |
| :---------------- | :------------------------------------------- | :--------------- | :-------------------------------------------------------------------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) | `undefined` | - |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) | `undefined` | - |
| `dependencies` | `string`[] | `undefined` | Dependencies to be removed from the dependencies section of package.json |
| `devDependencies` | `string`[] | `undefined` | Dependencies to be removed from the devDependencies section of package.json |
| `packageJsonPath` | `string` | `'package.json'` | - |
@@ -1208,7 +1228,7 @@ Callback to uninstall dependencies only if necessary. undefined is returned if c
### removeProjectConfiguration
**removeProjectConfiguration**(`host`, `projectName`): `void`
**removeProjectConfiguration**(`tree`, `projectName`): `void`
Removes the configuration of an existing project.
@@ -1219,7 +1239,7 @@ The utility will update both files.
| Name | Type |
| :------------ | :------------------------------------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) |
| `projectName` | `string` |
#### Returns
@@ -1399,7 +1419,7 @@ Rename and transpile any new typescript files created to javascript files
### updateJson
**updateJson**<`T`, `U`\>(`host`, `path`, `updater`, `options?`): `void`
**updateJson**<`T`, `U`\>(`tree`, `path`, `updater`, `options?`): `void`
Updates a JSON value to the file system tree
@@ -1414,7 +1434,7 @@ Updates a JSON value to the file system tree
| Name | Type | Description |
| :--------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) | File system tree |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) | File system tree |
| `path` | `string` | Path of JSON file in the Tree |
| `updater` | (`value`: `T`) => `U` | Function that maps the current value of a JSON document to a new value to be written to the document |
| `options?` | [`JsonParseOptions`](../../angular/nx-devkit/index#jsonparseoptions) & [`JsonSerializeOptions`](../../angular/nx-devkit/index#jsonserializeoptions) | Optional JSON Parse and Serialize Options |
@@ -1427,7 +1447,7 @@ Updates a JSON value to the file system tree
### updateProjectConfiguration
**updateProjectConfiguration**(`host`, `projectName`, `projectConfiguration`): `void`
**updateProjectConfiguration**(`tree`, `projectName`, `projectConfiguration`): `void`
Updates the configuration of an existing project.
@@ -1438,7 +1458,7 @@ both files.
| Name | Type | Description |
| :--------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) | the file system tree |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) | the file system tree |
| `projectName` | `string` | unique name. Often directories are part of the name (e.g., mydir-mylib) |
| `projectConfiguration` | [`ProjectConfiguration`](../../angular/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../angular/nx-devkit/index#nxjsonprojectconfiguration) | project configuration |
@@ -1450,13 +1470,13 @@ both files.
### updateTsConfigsToJs
**updateTsConfigsToJs**(`host`, `options`): `void`
**updateTsConfigsToJs**(`tree`, `options`): `void`
#### Parameters
| Name | Type |
| :-------------------- | :------------------------------------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) |
| `options` | `Object` |
| `options.projectRoot` | `string` |
@@ -1468,7 +1488,7 @@ both files.
### updateWorkspaceConfiguration
**updateWorkspaceConfiguration**(`host`, `workspaceConfig`): `void`
**updateWorkspaceConfiguration**(`tree`, `workspaceConfig`): `void`
Update general workspace configuration such as the default project or cli settings.
@@ -1478,7 +1498,7 @@ This does _not_ update projects configuration, use [updateProjectConfiguration](
| Name | Type |
| :---------------- | :------------------------------------------------------------------------------- |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) |
| `workspaceConfig` | [`WorkspaceConfiguration`](../../angular/nx-devkit/index#workspaceconfiguration) |
#### Returns
@@ -1509,7 +1529,7 @@ Utility to act on all files in a tree that are not ignored by git.
### writeJson
**writeJson**<`T`\>(`host`, `path`, `value`, `options?`): `void`
**writeJson**<`T`\>(`tree`, `path`, `value`, `options?`): `void`
Writes a JSON value to the file system tree
@@ -1523,7 +1543,7 @@ Writes a JSON value to the file system tree
| Name | Type | Description |
| :--------- | :--------------------------------------------------------------------------- | :------------------------------ |
| `host` | [`Tree`](../../angular/nx-devkit/index#tree) | File system tree |
| `tree` | [`Tree`](../../angular/nx-devkit/index#tree) | File system tree |
| `path` | `string` | Path of JSON file in the Tree |
| `value` | `T` | Serializable value to write |
| `options?` | [`JsonSerializeOptions`](../../angular/nx-devkit/index#jsonserializeoptions) | Optional JSON Serialize Options |
@@ -222,4 +222,4 @@ Run commands in parallel
Type: `string`
String to appear in `stdout` or `stderr` that indicates that the task is done. This option can only be used when multiple commands are run and `parallel` is set to `true`. If not specified, the task is done when all the child processes complete.
String to appear in `stdout` or `stderr` that indicates that the task is done. When running multiple commands, this option can only be used when `parallel` is set to `true`. If not specified, the task is done when all the child processes complete.
+7 -219
View File
@@ -173,224 +173,12 @@ To register an [addon](https://storybook.js.org/addons/) for a single storybook
export const decorators = [someDecorator];
```
### More Information
## Migrations
Here's more information on common migration scenarios for Storybook with Nx. For Storybook specific migrations that are not automatically handled by Nx please refer to the [official Storybook page](https://storybook.js.org/)
- [Upgrading to Storybook 6](/angular/storybook/upgrade-storybook-v6)
## More Information
For more on using Storybook, see the [official Storybook documentation](https://storybook.js.org/docs/basics/introduction/).
## From knobs to controls
Storybook v6 moves from "knobs" to args and controls when it comes to defining and manipulating your storybook
component properties. More can be found [on the official Storybook docs](https://storybook.js.org/docs/react/writing-stories/args).
From **Nx v12.5** and on, the `@nrwl/storybook` package will be using `@storybook/addon-controls` instead of `@storybook/addon-knobs` to generate stories.
### For new Nx workspaces
- Generators will generate your Storybook configuration files and your Stories using Controls/args instead of knobs
- The `storybook-configuration` generator will install the [`@storybook/addon-essentials`](https://storybook.js.org/docs/riot/essentials/introduction) package, part of which is `@storybook/addon-controls`. This includes some more "essential" Storybook features (eg. `docs`). You can [disable features you do not need](https://storybook.js.org/docs/riot/essentials/introduction#disabling-addons) anytime in your `main.js`.
- Cypress e2e tests will be generated, [using the args URL](https://storybook.js.org/docs/react/writing-stories/args#setting-args-through-the-url) to set args in the controls.
### For existing Nx workspaces
- If you `nx migrate` to the latest version, your `package.json` will be updated to include the `@storybook/addon-essentials` package. The `@storybook/addon-essentials` addon will be added in your `addons` array in your root `main.js` file. You will need to run `npm/yarn install` to have it installed.
- If you install manually the latest version of `@nrwl/storybook`, `@nrwl/workspace` and `@nrwl/angular` or `@nrwl/react`, you will need to manually do `yarn add -D @storybook/addon-essentials`. You will also need to add the addon manually in your `addons` array in your root `main.js` file.
- All the stories you generate from that moment on will be using controls/args
- Your existing stories will not be touched and will still work
## Upgrading to Storybook 6 (and Nx versions >10.1.x)
Nx now comes with [Storybook version 6](https://storybook.js.org/releases/6.0). Chances are, if you used Nx version `10.1.x` or older with Storybook, you are using [Storybook version 5.3](https://storybook.js.org/releases/5.3) with configuration files of [Storybook version 5.2](https://storybook.js.org/releases/5.2).
Nx version `10.2.x` will continue to support Storybook version `5.2.x`, however newer versions of Nx will only support Storybook version `6` (and on).
When you are running the Nx workspace migration script, your Storybook instances and configurations across your apps and libraries will NOT be migrated automatically. We chose not to migrate your Storybook instances and configurations across your apps and libraries automatically, since there a number of breaking changes that Storybook introduced in versions `5.3` and `6.0`, and making decisions on what to migrate automatically would risk the integrity of your code.
Instead, when you choose to migrate from Nx versions `<10.1.x` to Nx versions `>10.2.x` (using the Nx migration script - `nx migrate`) we will keep your Storybook packages and Storybook instances and configurations intact. We suggest that you do the migration on your own, using the guide below, with all the references to the official Storybook migration guides. Look at the use cases below, and follow the one that matches your case.
### Use cases:
#### Use case 1: Create an Nx workspace from scratch using the latest version of Nx
If you are creating an Nx workspace using the latest version of Nx, the latest version of Storybook (version 6) will be used as well. You do not need to do anything.
#### Use case 2: I already have an Nx workspace that does NOT use Storybook and I want to migrate to the latest Nx
If you already have an Nx workspace with a previous version of Nx that does NOT use Storybook, and you migrate to the latest Nx using the migrate scripts provided by Nx, and then, after the migration to the latest Nx, you choose to add Storybook, the latest version of Storybook will be used. You do not need to do anything.
#### Use case 3: I already have an Nx workspace with Storybook and I want to migrate to the latest Nx
In that case, when you run the Nx migration scripts, the scripts will ignore the Storybook packages, the Storybook configuration files, the Storybook instances in your apps and libraries, and all the generated stories. If you continue to add Storybook configurations and Storybook instances to new libraries and applications, then the version of Storybook that you already have will be used (most probably, if you have not changed anything manually, that version will be `5.3.9` using, however, the configuration files of `5.2`). You will have to do the [upgrade to the latest Storybook on your own, manually](#upgrading-to-storybook-6-manually). After that, Nx will use that version, and configure all new Storybook instances using the new version.
### Upgrading to Storybook 6 using the Nx migration generator
#### Some info about the generator
The `@nrwl/angular:storybook-migrate-defaults-5-to-6` generator will not exactly do a migration. It will perform the following actions:
- It will generate new Storybook configuration files using the new (`>6.x`) Storybook way. The way it will do that is, it will look into `workspace.json` and it will find all the projects that have a `Storybook` configuration. Using the `configFolder` path provided there, it will go and generate new Storybook instances in all these paths. Finally, it will generate a new Storybook instance at the root directory.
- If you choose to `keepOld`, then it will add all your existing Storybook configuration files into another folder labeled `.old_storybook`.
- It will update all the Storybook-related (`@storybook/*`) packages in your `package.json`.
#### How to use the generator
That way, you can have working Storybook instances for all your projects just by running
```bash
nx g @nrwl/angular:storybook-migrate-defaults-5-to-6
```
#### What if I had made changes to the defaults?
In case you had made customizations to the default Storybook configurations, you can then manually change each of your Storybook instance configuration files using the official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) to make sure you use the new syntax. Your old configuration files are available to you to use as a reference.
Please check out this official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).
#### What if I am not ready to change everything at once?
The generator gives you the option to migrate one project at a time. You can provide the `--name=PROJECT_NAME` flag, and then the generator will **only** generate new files for the specified project.
Please note that this option will NOT update all the Storybook-related (`@storybook/*`) packages in your `package.json`, or the root Storybook folder. The reason is that if you want to do the migration gradually, one project at a time, you want your old, existing, projects, to still work. That way, you will still be able to run your old, non-migrated Storybook projects. However, you will not be able to run any migrated Storbook projects. Once you have migrated all your Storybook projects, you can run `nx g @nrwl/angular:storybook-migrate-defaults-5-to-6` once again, and the generator will take care of updating all the Storybook-related (`@storybook/*`) packages in your `package.json` and it will also generate the new Storybook files for the root Storybook directory.
#### General tip:
**Commit any changes you have locally**. We would suggest that you start the migration with a clean git history, in case anything goes wrong.
### Upgrading to Storybook 6 manually
There is really no great reason for doing the migration completely manually. The `@nrwl/angular:storybook-migrate-defaults-5-to-6` generator [will take care of Steps 1, 2 and 3](#upgrading-to-storybook-6-using-the-nx-migration-generator). What you will need to do after running the generator is that you have to manually migrate any custom changes you had done to the default Storybook configuration files that were automatically generated by Nx when you first used Nx Storybook. To do the manual migration you should use the official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).
However, if you still want to do everything manually, these are the steps you should follow:
#### Step 0:
**Commit any changes you have locally**. We would suggest that you start the migration with a clean git history, in case anything goes wrong.
#### Step 1: Changing the configuration files from version 5.2 to 5.3
The most noticeable change in Storybook versions newer than `5.2` is that the configuration files have changed names and content.
Quoting from the [official Storybook migration guide](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-52x-to-53x):
- `presets.js` has been renamed to `main.js`. `main.js` is the main point of configuration for storybook.
- `config.js` has been renamed to `preview.js`. `preview.js` configures the "preview" iframe that renders your components.
- `addons.js` has been renamed to `manager.js`. `manager.js` configures Storybook's "manager" UI that wraps the preview, and also configures addons panel.
Please follow the [official Storybook version 5.2.x to 5.3.x migration guide](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-52x-to-53x) to change your files accordingly.
If you are using Storybook using only the generated files after running the `storybook-configuration` generator, things might be easier for you. Please check the [sample files for a manual upgrade](#sample-files-for-manual-upgrade).
#### Step 2: Going from version 5.3 to 6.0
Please check out this official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).
- One big change in Storybook version `6` is that it has **built-in Typescript support**. This means that you can remove Typescript configurations from your configuration files.
- Please also **check that your stories match any differences in syntax** introduced in versions `5.3` and `6.0`.
#### Step 3: Upgrade all `@storybook/*` packages in your project
Check your `package.json` file for all `@storybook` packages. Install the latest versions of these, using `yarn`:
For example:
```bash
yarn add --dev @storybook/angular@latest
```
#### Step 4: Check that everything works as expected
Check that everything works as expected. If you are still having trouble, you can submit you issue in the [GitHub Nx repo](https://github.com/nrwl/nx). We wish you luck!
### Sample files for manual upgrade
If you have not changed the content of the files which the `storybook-configuration` generator produced, you can use the following samples to migrate to Storybook `6`:
#### Configuring the root `./storybook` directory
- In the root `./storybook` directory, create a new file named `main.js` with the following content:
```typescript
module.exports = {
stories: [],
addons: ['@storybook/addon-essentials'],
};
```
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. If you are using the default generated files without any changes, you should not have any addons. You can now delete the `addons.js` file.
- The other two files remain unchanged.
#### Configuring the Storybook instances across apps and libraries - the library-specific `./storybook` directories
- In the library `./storybook` directory, create a new file named `main.js` with the following content:
```typescript
const lib_main_module = require('../../.storybook/main');
lib_main_module.stories.push('../src/lib/**/*.stories.mdx');
lib_main_module.stories.push('../src/lib/**/*.stories.@(js|jsx|ts|tsx)');
module.exports = lib_main_module;
```
Please take extra care making sure that the path to the root `./storybook` directory provided in the first line is correct.
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. You can add any addons in the `addons` module array using the following syntax:
```typescript
lib_main_module.addons.push('<YOUR_ADDON_HERE>');
```
After you add any addons in the `main.js` file, you can safely delete the `addons.js` file. If you are using the default generated files without any changes, your `addons.js` file should be empty (but an import line, referencing the root `addons.js` file).
- Rename the file `config.js` to `preview.js` and remove the last line where your stories paths are configured. Now, the contents of the `preview.js` file will look like this:
```typescript
import { addDecorator } from '@storybook/angular';
import { YourDecorator } from '@storybook/<something>';
addDecorator(YourDecorator);
```
- Modify the contents of `webpack.config.js`. Remove the following lines, which are the TypeScript configuration, which is not needed by Storybook any more:
```typescript
config.resolve.extensions.push('.ts', '.tsx');
config.module.rules.push({
test: /\.(ts|tsx)$/,
loader: require.resolve('babel-loader'),
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript',
],
},
});
```
#### Check final folder structure
Your folder structure should now look like this:
```treeview
<workspace name>/
├── .storybook/
│ ├── main.js
│ ├── tsconfig.json
│ └── webpack.config.js
├── apps/
├── libs/
│ └── <library name>/
│ ├── .storybook/
│ │ ├── main.js
│ │ ├── tsconfig.json
│ │ └── webpack.config.js
│ ├── src/
│ ├── README.md
│ ├── tsconfig.json
│ └── etc...
├── nx.json
├── package.json
├── README.md
└── etc...
```
@@ -0,0 +1,197 @@
# Upgrading to Storybook 6 (and Nx versions >10.1.x)
Nx now comes with [Storybook version 6](https://storybook.js.org/releases/6.0). Chances are, if you used Nx version `10.1.x` or older with Storybook, you are using [Storybook version 5.3](https://storybook.js.org/releases/5.3) with configuration files of [Storybook version 5.2](https://storybook.js.org/releases/5.2).
Nx version `10.2.x` will continue to support Storybook version `5.2.x`, however newer versions of Nx will only support Storybook version `6` (and on).
When you are running the Nx workspace migration script, your Storybook instances and configurations across your apps and libraries will NOT be migrated automatically. We chose not to migrate your Storybook instances and configurations across your apps and libraries automatically, since there a number of breaking changes that Storybook introduced in versions `5.3` and `6.0`, and making decisions on what to migrate automatically would risk the integrity of your code.
Instead, when you choose to migrate from Nx versions `<10.1.x` to Nx versions `>10.2.x` (using the Nx migration script - `nx migrate`) we will keep your Storybook packages and Storybook instances and configurations intact. We suggest that you do the migration on your own, using the guide below, with all the references to the official Storybook migration guides. Look at the use cases below, and follow the one that matches your case.
## Use Cases
### Use case 1: Create an Nx workspace from scratch using the latest version of Nx
If you are creating an Nx workspace using the latest version of Nx, the latest version of Storybook (version 6) will be used as well. You do not need to do anything.
### Use case 2: I already have an Nx workspace that does NOT use Storybook and I want to migrate to the latest Nx
If you already have an Nx workspace with a previous version of Nx that does NOT use Storybook, and you migrate to the latest Nx using the migrate scripts provided by Nx, and then, after the migration to the latest Nx, you choose to add Storybook, the latest version of Storybook will be used. You do not need to do anything.
### Use case 3: I already have an Nx workspace with Storybook and I want to migrate to the latest Nx
In that case, when you run the Nx migration scripts, the scripts will ignore the Storybook packages, the Storybook configuration files, the Storybook instances in your apps and libraries, and all the generated stories. If you continue to add Storybook configurations and Storybook instances to new libraries and applications, then the version of Storybook that you already have will be used (most probably, if you have not changed anything manually, that version will be `5.3.9` using, however, the configuration files of `5.2`). You will have to do the [upgrade to the latest Storybook on your own, manually](#upgrading-to-storybook-6-manually). After that, Nx will use that version, and configure all new Storybook instances using the new version.
## Upgrading to Storybook 6 using the Nx migration generator
### Some info about the generator
The `@nrwl/angular:storybook-migrate-defaults-5-to-6` generator will not exactly do a migration. It will perform the following actions:
- It will generate new Storybook configuration files using the new (`>6.x`) Storybook way. The way it will do that is, it will look into `workspace.json` and it will find all the projects that have a `Storybook` configuration. Using the `configFolder` path provided there, it will go and generate new Storybook instances in all these paths. Finally, it will generate a new Storybook instance at the root directory.
- If you choose to `keepOld`, then it will add all your existing Storybook configuration files into another folder labeled `.old_storybook`.
- It will update all the Storybook-related (`@storybook/*`) packages in your `package.json`.
### How to use the generator
That way, you can have working Storybook instances for all your projects just by running
```bash
nx g @nrwl/angular:storybook-migrate-defaults-5-to-6
```
### What if I had made changes to the defaults?
In case you had made customizations to the default Storybook configurations, you can then manually change each of your Storybook instance configuration files using the official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) to make sure you use the new syntax. Your old configuration files are available to you to use as a reference.
Please check out this official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).
### What if I am not ready to change everything at once?
The generator gives you the option to migrate one project at a time. You can provide the `--name=PROJECT_NAME` flag, and then the generator will **only** generate new files for the specified project.
Please note that this option will NOT update all the Storybook-related (`@storybook/*`) packages in your `package.json`, or the root Storybook folder. The reason is that if you want to do the migration gradually, one project at a time, you want your old, existing, projects, to still work. That way, you will still be able to run your old, non-migrated Storybook projects. However, you will not be able to run any migrated Storbook projects. Once you have migrated all your Storybook projects, you can run `nx g @nrwl/angular:storybook-migrate-defaults-5-to-6` once again, and the generator will take care of updating all the Storybook-related (`@storybook/*`) packages in your `package.json` and it will also generate the new Storybook files for the root Storybook directory.
### General tip:
**Commit any changes you have locally**. We would suggest that you start the migration with a clean git history, in case anything goes wrong.
## Upgrading to Storybook 6 manually
There is really no great reason for doing the migration completely manually. The `@nrwl/angular:storybook-migrate-defaults-5-to-6` generator [will take care of Steps 1, 2 and 3](#upgrading-to-storybook-6-using-the-nx-migration-generator). What you will need to do after running the generator is that you have to manually migrate any custom changes you had done to the default Storybook configuration files that were automatically generated by Nx when you first used Nx Storybook. To do the manual migration you should use the official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).
However, if you still want to do everything manually, these are the steps you should follow:
### Step 0:
**Commit any changes you have locally**. We would suggest that you start the migration with a clean git history, in case anything goes wrong.
### Step 1: Changing the configuration files from version 5.2 to 5.3
The most noticeable change in Storybook versions newer than `5.2` is that the configuration files have changed names and content.
Quoting from the [official Storybook migration guide](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-52x-to-53x):
- `presets.js` has been renamed to `main.js`. `main.js` is the main point of configuration for storybook.
- `config.js` has been renamed to `preview.js`. `preview.js` configures the "preview" iframe that renders your components.
- `addons.js` has been renamed to `manager.js`. `manager.js` configures Storybook's "manager" UI that wraps the preview, and also configures addons panel.
Please follow the [official Storybook version 5.2.x to 5.3.x migration guide](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-52x-to-53x) to change your files accordingly.
If you are using Storybook using only the generated files after running the `storybook-configuration` generator, things might be easier for you. Please check the [sample files for a manual upgrade](#sample-files-for-manual-upgrade).
### Step 2: Going from version 5.3 to 6.0
Please check out this official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).
- One big change in Storybook version `6` is that it has **built-in Typescript support**. This means that you can remove Typescript configurations from your configuration files.
- Please also **check that your stories match any differences in syntax** introduced in versions `5.3` and `6.0`.
### Step 3: Upgrade all `@storybook/*` packages in your project
Check your `package.json` file for all `@storybook` packages. Install the latest versions of these, using `yarn`:
For example:
```bash
yarn add --dev @storybook/angular@latest
```
### Step 4: Check that everything works as expected
Check that everything works as expected. If you are still having trouble, you can submit you issue in the [GitHub Nx repo](https://github.com/nrwl/nx). We wish you luck!
## Sample files for manual upgrade
If you have not changed the content of the files which the `storybook-configuration` generator produced, you can use the following samples to migrate to Storybook `6`:
### Configuring the root `./storybook` directory
- In the root `./storybook` directory, create a new file named `main.js` with the following content:
```typescript
module.exports = {
stories: [],
addons: ['@storybook/addon-essentials'],
};
```
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. If you are using the default generated files without any changes, you should not have any addons. You can now delete the `addons.js` file.
- The other two files remain unchanged.
### Configuring the Storybook instances across apps and libraries - the library-specific `./storybook` directories
- In the library `./storybook` directory, create a new file named `main.js` with the following content:
```typescript
const lib_main_module = require('../../.storybook/main');
lib_main_module.stories.push('../src/lib/**/*.stories.mdx');
lib_main_module.stories.push('../src/lib/**/*.stories.@(js|jsx|ts|tsx)');
module.exports = lib_main_module;
```
Please take extra care making sure that the path to the root `./storybook` directory provided in the first line is correct.
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. You can add any addons in the `addons` module array using the following syntax:
```typescript
lib_main_module.addons.push('<YOUR_ADDON_HERE>');
```
After you add any addons in the `main.js` file, you can safely delete the `addons.js` file. If you are using the default generated files without any changes, your `addons.js` file should be empty (but an import line, referencing the root `addons.js` file).
- Rename the file `config.js` to `preview.js` and remove the last line where your stories paths are configured. Now, the contents of the `preview.js` file will look like this:
```typescript
import { addDecorator } from '@storybook/angular';
import { YourDecorator } from '@storybook/<something>';
addDecorator(YourDecorator);
```
- Modify the contents of `webpack.config.js`. Remove the following lines, which are the TypeScript configuration, which is not needed by Storybook any more:
```typescript
config.resolve.extensions.push('.ts', '.tsx');
config.module.rules.push({
test: /\.(ts|tsx)$/,
loader: require.resolve('babel-loader'),
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript',
],
},
});
```
### Check final folder structure
Your folder structure should now look like this:
```treeview
<workspace name>/
├── .storybook/
│ ├── main.js
│ ├── tsconfig.json
│ └── webpack.config.js
├── apps/
├── libs/
│ └── <library name>/
│ ├── .storybook/
│ │ ├── main.js
│ │ ├── tsconfig.json
│ │ └── webpack.config.js
│ ├── src/
│ ├── README.md
│ ├── tsconfig.json
│ └── etc...
├── nx.json
├── package.json
├── README.md
└── etc...
```
+10
View File
@@ -595,6 +595,11 @@
"searchResultsName": "@nrwl/storybook Overview",
"file": "angular/guides/storybook-plugin"
},
{
"id": "upgrade-storybook-v6",
"name": "Upgrading to Storybook 6",
"file": "angular/guides/storybook/storybook-v6"
},
{
"name": "configuration generator",
"id": "configuration",
@@ -1766,6 +1771,11 @@
"searchResultsName": "@nrwl/storybook Overview",
"file": "react/guides/storybook-plugin"
},
{
"id": "upgrade-storybook-v6",
"name": "Upgrading to Storybook 6",
"file": "react/guides/storybook/storybook-v6"
},
{
"name": "configuration generator",
"id": "configuration",
+10
View File
@@ -56,6 +56,16 @@ Type: `string`
The new import path to use in the `tsconfig.base.json`.
### skipFormat
Alias(es): skip-format
Default: `false`
Type: `boolean`
Skip formatting files.
### updateImportPath
Default: `true`
+12 -12
View File
@@ -7,6 +7,18 @@ Read more about how to use executors and the CLI here: https://nx.dev/getting-st
## Options
### outputPath (_**required**_)
Type: `string`
The output path of the generated files.
### root (_**required**_)
Type: `string`
The source root
### buildLibsFromSource
Default: `true`
@@ -38,15 +50,3 @@ The file to replace with.
Type: `string`
Path (relative to workspace root) to a function which takes phase, config, and builder options, and returns the resulting config. This is an advanced option and should not be used with a normal Next.js config file (i.e. next.config.js).
### outputPath
Type: `string`
The output path of the generated files.
### root
Type: `string`
The source root
+6 -6
View File
@@ -7,6 +7,12 @@ Read more about how to use executors and the CLI here: https://nx.dev/getting-st
## Options
### buildTarget (_**required**_)
Type: `string`
Target which builds the application
### buildLibsFromSource
Default: `true`
@@ -15,12 +21,6 @@ Type: `boolean`
Read buildable libraries from source instead of building them separately.
### buildTarget
Type: `string`
Target which builds the application
### customServerPath
Type: `string`
+1 -1
View File
@@ -37,7 +37,7 @@ Ensures the app is starting with debugging
### port
Default: `0`
Default: `9229`
Type: `number`
+64 -44
View File
@@ -72,6 +72,7 @@
- [getWorkspaceLayout](../../node/nx-devkit/index#getworkspacelayout)
- [getWorkspacePath](../../node/nx-devkit/index#getworkspacepath)
- [installPackagesTask](../../node/nx-devkit/index#installpackagestask)
- [isStandaloneProject](../../node/nx-devkit/index#isstandaloneproject)
- [joinPathFragments](../../node/nx-devkit/index#joinpathfragments)
- [moveFilesToNewDirectory](../../node/nx-devkit/index#movefilestonewdirectory)
- [names](../../node/nx-devkit/index#names)
@@ -481,7 +482,7 @@ Implementation of a target of a project that handles multiple projects to be bat
### WorkspaceConfiguration
Ƭ **WorkspaceConfiguration**: `Omit`<[`WorkspaceJsonConfiguration`](../../node/nx-devkit/index#workspacejsonconfiguration), `"projects"`\> & `Omit`<[`NxJsonConfiguration`](../../node/nx-devkit/index#nxjsonconfiguration), `"projects"`\>
Ƭ **WorkspaceConfiguration**: `Omit`<[`WorkspaceJsonConfiguration`](../../node/nx-devkit/index#workspacejsonconfiguration), `"projects"`\> & `Partial`<`Omit`<[`NxJsonConfiguration`](../../node/nx-devkit/index#nxjsonconfiguration), `"projects"`\>\>
## Variables
@@ -504,14 +505,14 @@ Implementation of a target of a project that handles multiple projects to be bat
### addDependenciesToPackageJson
**addDependenciesToPackageJson**(`host`, `dependencies`, `devDependencies`, `packageJsonPath?`): [`GeneratorCallback`](../../node/nx-devkit/index#generatorcallback)
**addDependenciesToPackageJson**(`tree`, `dependencies`, `devDependencies`, `packageJsonPath?`): [`GeneratorCallback`](../../node/nx-devkit/index#generatorcallback)
Add Dependencies and Dev Dependencies to package.json
For example:
```typescript
addDependenciesToPackageJson(host, { react: 'latest' }, { jest: 'latest' });
addDependenciesToPackageJson(tree, { react: 'latest' }, { jest: 'latest' });
```
This will **add** `react` and `jest` to the dependencies and devDependencies sections of package.json respectively.
@@ -520,7 +521,7 @@ This will **add** `react` and `jest` to the dependencies and devDependencies sec
| Name | Type | Default value | Description |
| :---------------- | :---------------------------------------- | :--------------- | :---------------------------------------------------------------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) | `undefined` | Tree representing file system to modify |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) | `undefined` | Tree representing file system to modify |
| `dependencies` | `Record`<`string`, `string`\> | `undefined` | Dependencies to be added to the dependencies section of package.json |
| `devDependencies` | `Record`<`string`, `string`\> | `undefined` | Dependencies to be added to the devDependencies section of package.json |
| `packageJsonPath` | `string` | `'package.json'` | Path to package.json |
@@ -535,7 +536,7 @@ Callback to install dependencies only if necessary. undefined is returned if cha
### addProjectConfiguration
**addProjectConfiguration**(`host`, `projectName`, `projectConfiguration`, `standalone?`): `void`
**addProjectConfiguration**(`tree`, `projectName`, `projectConfiguration`, `standalone?`): `void`
Adds project configuration to the Nx workspace.
@@ -546,7 +547,7 @@ both files.
| Name | Type | Default value | Description |
| :--------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------ | :----------------------------------------------------------------------------------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) | `undefined` | the file system tree |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) | `undefined` | the file system tree |
| `projectName` | `string` | `undefined` | unique name. Often directories are part of the name (e.g., mydir-mylib) |
| `projectConfiguration` | [`ProjectConfiguration`](../../node/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../node/nx-devkit/index#nxjsonprojectconfiguration) | `undefined` | project configuration |
| `standalone` | `boolean` | `false` | should the project use package.json? If false, the project config is inside workspace.json |
@@ -693,7 +694,7 @@ Detects which package manager is used in the workspace based on the lock file.
### formatFiles
**formatFiles**(`host`): `Promise`<`void`\>
**formatFiles**(`tree`): `Promise`<`void`\>
Formats all the created or updated files using Prettier
@@ -701,7 +702,7 @@ Formats all the created or updated files using Prettier
| Name | Type | Description |
| :----- | :---------------------------------------- | :------------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) | the file system tree |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) | the file system tree |
#### Returns
@@ -711,7 +712,7 @@ Formats all the created or updated files using Prettier
### generateFiles
**generateFiles**(`host`, `srcFolder`, `target`, `substitutions`): `void`
**generateFiles**(`tree`, `srcFolder`, `target`, `substitutions`): `void`
Generates a folder of files based on provided templates.
@@ -723,7 +724,7 @@ While doing so it performs two substitutions:
Examples:
```typescript
generateFiles(host, path.join(__dirname, 'files'), './tools/scripts', {
generateFiles(tree, path.join(__dirname, 'files'), './tools/scripts', {
tmpl: '',
name: 'myscript',
});
@@ -739,9 +740,9 @@ doesn't get confused about incorrect TypeScript files.
| Name | Type | Description |
| :-------------- | :---------------------------------------- | :-------------------------------------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) | the file system tree |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) | the file system tree |
| `srcFolder` | `string` | the source folder of files (absolute path) |
| `target` | `string` | the target folder (relative to the host root) |
| `target` | `string` | the target folder (relative to the tree root) |
| `substitutions` | `Object` | an object of key-value pairs |
#### Returns
@@ -798,7 +799,7 @@ but it can also be passed in explicitly.
### getProjects
**getProjects**(`host`): `Map`<`string`, [`ProjectConfiguration`](../../node/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../node/nx-devkit/index#nxjsonprojectconfiguration)\>
**getProjects**(`tree`): `Map`<`string`, [`ProjectConfiguration`](../../node/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../node/nx-devkit/index#nxjsonprojectconfiguration)\>
Get a map of all projects in a workspace.
@@ -808,7 +809,7 @@ Use [readProjectConfiguration](../../node/nx-devkit/index#readprojectconfigurati
| Name | Type |
| :----- | :---------------------------------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) |
#### Returns
@@ -818,7 +819,7 @@ Use [readProjectConfiguration](../../node/nx-devkit/index#readprojectconfigurati
### getWorkspaceLayout
**getWorkspaceLayout**(`host`): `Object`
**getWorkspaceLayout**(`tree`): `Object`
Returns workspace defaults. It includes defaults folders for apps and libs,
and the default scope.
@@ -833,7 +834,7 @@ Example:
| Name | Type | Description |
| :----- | :---------------------------------------- | :--------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) | file system tree |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) | file system tree |
#### Returns
@@ -850,13 +851,13 @@ Example:
### getWorkspacePath
**getWorkspacePath**(`host`): `string`
**getWorkspacePath**(`tree`): `string`
#### Parameters
| Name | Type |
| :----- | :---------------------------------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) |
#### Returns
@@ -866,7 +867,7 @@ Example:
### installPackagesTask
**installPackagesTask**(`host`, `alwaysRun?`, `cwd?`, `packageManager?`): `void`
**installPackagesTask**(`tree`, `alwaysRun?`, `cwd?`, `packageManager?`): `void`
Runs `npm install` or `yarn install`. It will skip running the install if
`package.json` hasn't changed at all or it hasn't changed since the last invocation.
@@ -875,7 +876,7 @@ Runs `npm install` or `yarn install`. It will skip running the install if
| Name | Type | Default value | Description |
| :--------------- | :------------------------------------------------------------ | :------------ | :------------------------------------------------------------ |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) | `undefined` | the file system tree |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) | `undefined` | the file system tree |
| `alwaysRun` | `boolean` | `false` | always run the command even if `package.json` hasn't changed. |
| `cwd` | `string` | `''` | - |
| `packageManager` | [`PackageManager`](../../node/nx-devkit/index#packagemanager) | `undefined` | - |
@@ -886,6 +887,25 @@ Runs `npm install` or `yarn install`. It will skip running the install if
---
### isStandaloneProject
**isStandaloneProject**(`tree`, `project`): `boolean`
Returns if a project has a standalone configuration (project.json).
#### Parameters
| Name | Type | Description |
| :-------- | :---------------------------------------- | :------------------- |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) | the file system tree |
| `project` | `string` | the project name |
#### Returns
`boolean`
---
### joinPathFragments
**joinPathFragments**(...`fragments`): `string`
@@ -906,13 +926,13 @@ Normalized path fragments and joins them
### moveFilesToNewDirectory
**moveFilesToNewDirectory**(`host`, `oldDir`, `newDir`): `void`
**moveFilesToNewDirectory**(`tree`, `oldDir`, `newDir`): `void`
#### Parameters
| Name | Type |
| :------- | :---------------------------------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) |
| `oldDir` | `string` |
| `newDir` | `string` |
@@ -1053,9 +1073,9 @@ parseTargetString('proj:test:production'); // returns { project: "proj", target:
### readJson
**readJson**<`T`\>(`host`, `path`, `options?`): `T`
**readJson**<`T`\>(`tree`, `path`, `options?`): `T`
Reads a document for host, removes all comments and parses JSON.
Reads a json file, removes all comments and parses JSON.
#### Type parameters
@@ -1067,7 +1087,7 @@ Reads a document for host, removes all comments and parses JSON.
| Name | Type | Description |
| :--------- | :---------------------------------------------------------------- | :-------------------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) | file system tree |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) | file system tree |
| `path` | `string` | file path |
| `options?` | [`JsonParseOptions`](../../node/nx-devkit/index#jsonparseoptions) | Optional JSON Parse Options |
@@ -1106,7 +1126,7 @@ Object the JSON content of the file represents
### readProjectConfiguration
**readProjectConfiguration**(`host`, `projectName`): [`ProjectConfiguration`](../../node/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../node/nx-devkit/index#nxjsonprojectconfiguration)
**readProjectConfiguration**(`tree`, `projectName`): [`ProjectConfiguration`](../../node/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../node/nx-devkit/index#nxjsonprojectconfiguration)
Reads a project configuration.
@@ -1119,7 +1139,7 @@ both files.
| Name | Type | Description |
| :------------ | :---------------------------------------- | :---------------------------------------------------------------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) | the file system tree |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) | the file system tree |
| `projectName` | `string` | unique name. Often directories are part of the name (e.g., mydir-mylib) |
#### Returns
@@ -1157,7 +1177,7 @@ Works as if you invoked the target yourself without passing any command lint ove
### readWorkspaceConfiguration
**readWorkspaceConfiguration**(`host`): [`WorkspaceConfiguration`](../../node/nx-devkit/index#workspaceconfiguration)
**readWorkspaceConfiguration**(`tree`): [`WorkspaceConfiguration`](../../node/nx-devkit/index#workspaceconfiguration)
Read general workspace configuration such as the default project or cli settings
@@ -1167,7 +1187,7 @@ This does _not_ provide projects configuration, use [readProjectConfiguration](.
| Name | Type |
| :----- | :---------------------------------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) |
#### Returns
@@ -1177,14 +1197,14 @@ This does _not_ provide projects configuration, use [readProjectConfiguration](.
### removeDependenciesFromPackageJson
**removeDependenciesFromPackageJson**(`host`, `dependencies`, `devDependencies`, `packageJsonPath?`): [`GeneratorCallback`](../../node/nx-devkit/index#generatorcallback)
**removeDependenciesFromPackageJson**(`tree`, `dependencies`, `devDependencies`, `packageJsonPath?`): [`GeneratorCallback`](../../node/nx-devkit/index#generatorcallback)
Remove Dependencies and Dev Dependencies from package.json
For example:
```typescript
removeDependenciesFromPackageJson(host, ['react'], ['jest']);
removeDependenciesFromPackageJson(tree, ['react'], ['jest']);
```
This will **remove** `react` and `jest` from the dependencies and devDependencies sections of package.json respectively.
@@ -1193,7 +1213,7 @@ This will **remove** `react` and `jest` from the dependencies and devDependencie
| Name | Type | Default value | Description |
| :---------------- | :---------------------------------------- | :--------------- | :-------------------------------------------------------------------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) | `undefined` | - |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) | `undefined` | - |
| `dependencies` | `string`[] | `undefined` | Dependencies to be removed from the dependencies section of package.json |
| `devDependencies` | `string`[] | `undefined` | Dependencies to be removed from the devDependencies section of package.json |
| `packageJsonPath` | `string` | `'package.json'` | - |
@@ -1208,7 +1228,7 @@ Callback to uninstall dependencies only if necessary. undefined is returned if c
### removeProjectConfiguration
**removeProjectConfiguration**(`host`, `projectName`): `void`
**removeProjectConfiguration**(`tree`, `projectName`): `void`
Removes the configuration of an existing project.
@@ -1219,7 +1239,7 @@ The utility will update both files.
| Name | Type |
| :------------ | :---------------------------------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) |
| `projectName` | `string` |
#### Returns
@@ -1399,7 +1419,7 @@ Rename and transpile any new typescript files created to javascript files
### updateJson
**updateJson**<`T`, `U`\>(`host`, `path`, `updater`, `options?`): `void`
**updateJson**<`T`, `U`\>(`tree`, `path`, `updater`, `options?`): `void`
Updates a JSON value to the file system tree
@@ -1414,7 +1434,7 @@ Updates a JSON value to the file system tree
| Name | Type | Description |
| :--------- | :-------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) | File system tree |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) | File system tree |
| `path` | `string` | Path of JSON file in the Tree |
| `updater` | (`value`: `T`) => `U` | Function that maps the current value of a JSON document to a new value to be written to the document |
| `options?` | [`JsonParseOptions`](../../node/nx-devkit/index#jsonparseoptions) & [`JsonSerializeOptions`](../../node/nx-devkit/index#jsonserializeoptions) | Optional JSON Parse and Serialize Options |
@@ -1427,7 +1447,7 @@ Updates a JSON value to the file system tree
### updateProjectConfiguration
**updateProjectConfiguration**(`host`, `projectName`, `projectConfiguration`): `void`
**updateProjectConfiguration**(`tree`, `projectName`, `projectConfiguration`): `void`
Updates the configuration of an existing project.
@@ -1438,7 +1458,7 @@ both files.
| Name | Type | Description |
| :--------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) | the file system tree |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) | the file system tree |
| `projectName` | `string` | unique name. Often directories are part of the name (e.g., mydir-mylib) |
| `projectConfiguration` | [`ProjectConfiguration`](../../node/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../node/nx-devkit/index#nxjsonprojectconfiguration) | project configuration |
@@ -1450,13 +1470,13 @@ both files.
### updateTsConfigsToJs
**updateTsConfigsToJs**(`host`, `options`): `void`
**updateTsConfigsToJs**(`tree`, `options`): `void`
#### Parameters
| Name | Type |
| :-------------------- | :---------------------------------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) |
| `options` | `Object` |
| `options.projectRoot` | `string` |
@@ -1468,7 +1488,7 @@ both files.
### updateWorkspaceConfiguration
**updateWorkspaceConfiguration**(`host`, `workspaceConfig`): `void`
**updateWorkspaceConfiguration**(`tree`, `workspaceConfig`): `void`
Update general workspace configuration such as the default project or cli settings.
@@ -1478,7 +1498,7 @@ This does _not_ update projects configuration, use [updateProjectConfiguration](
| Name | Type |
| :---------------- | :---------------------------------------------------------------------------- |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) |
| `workspaceConfig` | [`WorkspaceConfiguration`](../../node/nx-devkit/index#workspaceconfiguration) |
#### Returns
@@ -1509,7 +1529,7 @@ Utility to act on all files in a tree that are not ignored by git.
### writeJson
**writeJson**<`T`\>(`host`, `path`, `value`, `options?`): `void`
**writeJson**<`T`\>(`tree`, `path`, `value`, `options?`): `void`
Writes a JSON value to the file system tree
@@ -1523,7 +1543,7 @@ Writes a JSON value to the file system tree
| Name | Type | Description |
| :--------- | :------------------------------------------------------------------------ | :------------------------------ |
| `host` | [`Tree`](../../node/nx-devkit/index#tree) | File system tree |
| `tree` | [`Tree`](../../node/nx-devkit/index#tree) | File system tree |
| `path` | `string` | Path of JSON file in the Tree |
| `value` | `T` | Serializable value to write |
| `options?` | [`JsonSerializeOptions`](../../node/nx-devkit/index#jsonserializeoptions) | Optional JSON Serialize Options |
@@ -223,4 +223,4 @@ Run commands in parallel
Type: `string`
String to appear in `stdout` or `stderr` that indicates that the task is done. This option can only be used when multiple commands are run and `parallel` is set to `true`. If not specified, the task is done when all the child processes complete.
String to appear in `stdout` or `stderr` that indicates that the task is done. When running multiple commands, this option can only be used when `parallel` is set to `true`. If not specified, the task is done when all the child processes complete.
+10
View File
@@ -56,6 +56,16 @@ Type: `string`
The new import path to use in the `tsconfig.base.json`.
### skipFormat
Alias(es): skip-format
Default: `false`
Type: `boolean`
Skip formatting files.
### updateImportPath
Default: `true`
+12 -12
View File
@@ -7,6 +7,18 @@ Read more about how to use executors and the CLI here: https://nx.dev/getting-st
## Options
### outputPath (_**required**_)
Type: `string`
The output path of the generated files.
### root (_**required**_)
Type: `string`
The source root
### buildLibsFromSource
Default: `true`
@@ -38,15 +50,3 @@ The file to replace with.
Type: `string`
Path (relative to workspace root) to a function which takes phase, config, and builder options, and returns the resulting config. This is an advanced option and should not be used with a normal Next.js config file (i.e. next.config.js).
### outputPath
Type: `string`
The output path of the generated files.
### root
Type: `string`
The source root
+6 -6
View File
@@ -7,6 +7,12 @@ Read more about how to use executors and the CLI here: https://nx.dev/getting-st
## Options
### buildTarget (_**required**_)
Type: `string`
Target which builds the application
### buildLibsFromSource
Default: `true`
@@ -15,12 +21,6 @@ Type: `boolean`
Read buildable libraries from source instead of building them separately.
### buildTarget
Type: `string`
Target which builds the application
### customServerPath
Type: `string`
+1 -1
View File
@@ -37,7 +37,7 @@ Ensures the app is starting with debugging
### port
Default: `0`
Default: `9229`
Type: `number`
+64 -44
View File
@@ -72,6 +72,7 @@
- [getWorkspaceLayout](../../react/nx-devkit/index#getworkspacelayout)
- [getWorkspacePath](../../react/nx-devkit/index#getworkspacepath)
- [installPackagesTask](../../react/nx-devkit/index#installpackagestask)
- [isStandaloneProject](../../react/nx-devkit/index#isstandaloneproject)
- [joinPathFragments](../../react/nx-devkit/index#joinpathfragments)
- [moveFilesToNewDirectory](../../react/nx-devkit/index#movefilestonewdirectory)
- [names](../../react/nx-devkit/index#names)
@@ -481,7 +482,7 @@ Implementation of a target of a project that handles multiple projects to be bat
### WorkspaceConfiguration
Ƭ **WorkspaceConfiguration**: `Omit`<[`WorkspaceJsonConfiguration`](../../react/nx-devkit/index#workspacejsonconfiguration), `"projects"`\> & `Omit`<[`NxJsonConfiguration`](../../react/nx-devkit/index#nxjsonconfiguration), `"projects"`\>
Ƭ **WorkspaceConfiguration**: `Omit`<[`WorkspaceJsonConfiguration`](../../react/nx-devkit/index#workspacejsonconfiguration), `"projects"`\> & `Partial`<`Omit`<[`NxJsonConfiguration`](../../react/nx-devkit/index#nxjsonconfiguration), `"projects"`\>\>
## Variables
@@ -504,14 +505,14 @@ Implementation of a target of a project that handles multiple projects to be bat
### addDependenciesToPackageJson
**addDependenciesToPackageJson**(`host`, `dependencies`, `devDependencies`, `packageJsonPath?`): [`GeneratorCallback`](../../react/nx-devkit/index#generatorcallback)
**addDependenciesToPackageJson**(`tree`, `dependencies`, `devDependencies`, `packageJsonPath?`): [`GeneratorCallback`](../../react/nx-devkit/index#generatorcallback)
Add Dependencies and Dev Dependencies to package.json
For example:
```typescript
addDependenciesToPackageJson(host, { react: 'latest' }, { jest: 'latest' });
addDependenciesToPackageJson(tree, { react: 'latest' }, { jest: 'latest' });
```
This will **add** `react` and `jest` to the dependencies and devDependencies sections of package.json respectively.
@@ -520,7 +521,7 @@ This will **add** `react` and `jest` to the dependencies and devDependencies sec
| Name | Type | Default value | Description |
| :---------------- | :----------------------------------------- | :--------------- | :---------------------------------------------------------------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) | `undefined` | Tree representing file system to modify |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) | `undefined` | Tree representing file system to modify |
| `dependencies` | `Record`<`string`, `string`\> | `undefined` | Dependencies to be added to the dependencies section of package.json |
| `devDependencies` | `Record`<`string`, `string`\> | `undefined` | Dependencies to be added to the devDependencies section of package.json |
| `packageJsonPath` | `string` | `'package.json'` | Path to package.json |
@@ -535,7 +536,7 @@ Callback to install dependencies only if necessary. undefined is returned if cha
### addProjectConfiguration
**addProjectConfiguration**(`host`, `projectName`, `projectConfiguration`, `standalone?`): `void`
**addProjectConfiguration**(`tree`, `projectName`, `projectConfiguration`, `standalone?`): `void`
Adds project configuration to the Nx workspace.
@@ -546,7 +547,7 @@ both files.
| Name | Type | Default value | Description |
| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :------------ | :----------------------------------------------------------------------------------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) | `undefined` | the file system tree |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) | `undefined` | the file system tree |
| `projectName` | `string` | `undefined` | unique name. Often directories are part of the name (e.g., mydir-mylib) |
| `projectConfiguration` | [`ProjectConfiguration`](../../react/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../react/nx-devkit/index#nxjsonprojectconfiguration) | `undefined` | project configuration |
| `standalone` | `boolean` | `false` | should the project use package.json? If false, the project config is inside workspace.json |
@@ -693,7 +694,7 @@ Detects which package manager is used in the workspace based on the lock file.
### formatFiles
**formatFiles**(`host`): `Promise`<`void`\>
**formatFiles**(`tree`): `Promise`<`void`\>
Formats all the created or updated files using Prettier
@@ -701,7 +702,7 @@ Formats all the created or updated files using Prettier
| Name | Type | Description |
| :----- | :----------------------------------------- | :------------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) | the file system tree |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) | the file system tree |
#### Returns
@@ -711,7 +712,7 @@ Formats all the created or updated files using Prettier
### generateFiles
**generateFiles**(`host`, `srcFolder`, `target`, `substitutions`): `void`
**generateFiles**(`tree`, `srcFolder`, `target`, `substitutions`): `void`
Generates a folder of files based on provided templates.
@@ -723,7 +724,7 @@ While doing so it performs two substitutions:
Examples:
```typescript
generateFiles(host, path.join(__dirname, 'files'), './tools/scripts', {
generateFiles(tree, path.join(__dirname, 'files'), './tools/scripts', {
tmpl: '',
name: 'myscript',
});
@@ -739,9 +740,9 @@ doesn't get confused about incorrect TypeScript files.
| Name | Type | Description |
| :-------------- | :----------------------------------------- | :-------------------------------------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) | the file system tree |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) | the file system tree |
| `srcFolder` | `string` | the source folder of files (absolute path) |
| `target` | `string` | the target folder (relative to the host root) |
| `target` | `string` | the target folder (relative to the tree root) |
| `substitutions` | `Object` | an object of key-value pairs |
#### Returns
@@ -798,7 +799,7 @@ but it can also be passed in explicitly.
### getProjects
**getProjects**(`host`): `Map`<`string`, [`ProjectConfiguration`](../../react/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../react/nx-devkit/index#nxjsonprojectconfiguration)\>
**getProjects**(`tree`): `Map`<`string`, [`ProjectConfiguration`](../../react/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../react/nx-devkit/index#nxjsonprojectconfiguration)\>
Get a map of all projects in a workspace.
@@ -808,7 +809,7 @@ Use [readProjectConfiguration](../../react/nx-devkit/index#readprojectconfigurat
| Name | Type |
| :----- | :----------------------------------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) |
#### Returns
@@ -818,7 +819,7 @@ Use [readProjectConfiguration](../../react/nx-devkit/index#readprojectconfigurat
### getWorkspaceLayout
**getWorkspaceLayout**(`host`): `Object`
**getWorkspaceLayout**(`tree`): `Object`
Returns workspace defaults. It includes defaults folders for apps and libs,
and the default scope.
@@ -833,7 +834,7 @@ Example:
| Name | Type | Description |
| :----- | :----------------------------------------- | :--------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) | file system tree |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) | file system tree |
#### Returns
@@ -850,13 +851,13 @@ Example:
### getWorkspacePath
**getWorkspacePath**(`host`): `string`
**getWorkspacePath**(`tree`): `string`
#### Parameters
| Name | Type |
| :----- | :----------------------------------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) |
#### Returns
@@ -866,7 +867,7 @@ Example:
### installPackagesTask
**installPackagesTask**(`host`, `alwaysRun?`, `cwd?`, `packageManager?`): `void`
**installPackagesTask**(`tree`, `alwaysRun?`, `cwd?`, `packageManager?`): `void`
Runs `npm install` or `yarn install`. It will skip running the install if
`package.json` hasn't changed at all or it hasn't changed since the last invocation.
@@ -875,7 +876,7 @@ Runs `npm install` or `yarn install`. It will skip running the install if
| Name | Type | Default value | Description |
| :--------------- | :------------------------------------------------------------- | :------------ | :------------------------------------------------------------ |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) | `undefined` | the file system tree |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) | `undefined` | the file system tree |
| `alwaysRun` | `boolean` | `false` | always run the command even if `package.json` hasn't changed. |
| `cwd` | `string` | `''` | - |
| `packageManager` | [`PackageManager`](../../react/nx-devkit/index#packagemanager) | `undefined` | - |
@@ -886,6 +887,25 @@ Runs `npm install` or `yarn install`. It will skip running the install if
---
### isStandaloneProject
**isStandaloneProject**(`tree`, `project`): `boolean`
Returns if a project has a standalone configuration (project.json).
#### Parameters
| Name | Type | Description |
| :-------- | :----------------------------------------- | :------------------- |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) | the file system tree |
| `project` | `string` | the project name |
#### Returns
`boolean`
---
### joinPathFragments
**joinPathFragments**(...`fragments`): `string`
@@ -906,13 +926,13 @@ Normalized path fragments and joins them
### moveFilesToNewDirectory
**moveFilesToNewDirectory**(`host`, `oldDir`, `newDir`): `void`
**moveFilesToNewDirectory**(`tree`, `oldDir`, `newDir`): `void`
#### Parameters
| Name | Type |
| :------- | :----------------------------------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) |
| `oldDir` | `string` |
| `newDir` | `string` |
@@ -1053,9 +1073,9 @@ parseTargetString('proj:test:production'); // returns { project: "proj", target:
### readJson
**readJson**<`T`\>(`host`, `path`, `options?`): `T`
**readJson**<`T`\>(`tree`, `path`, `options?`): `T`
Reads a document for host, removes all comments and parses JSON.
Reads a json file, removes all comments and parses JSON.
#### Type parameters
@@ -1067,7 +1087,7 @@ Reads a document for host, removes all comments and parses JSON.
| Name | Type | Description |
| :--------- | :----------------------------------------------------------------- | :-------------------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) | file system tree |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) | file system tree |
| `path` | `string` | file path |
| `options?` | [`JsonParseOptions`](../../react/nx-devkit/index#jsonparseoptions) | Optional JSON Parse Options |
@@ -1106,7 +1126,7 @@ Object the JSON content of the file represents
### readProjectConfiguration
**readProjectConfiguration**(`host`, `projectName`): [`ProjectConfiguration`](../../react/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../react/nx-devkit/index#nxjsonprojectconfiguration)
**readProjectConfiguration**(`tree`, `projectName`): [`ProjectConfiguration`](../../react/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../react/nx-devkit/index#nxjsonprojectconfiguration)
Reads a project configuration.
@@ -1119,7 +1139,7 @@ both files.
| Name | Type | Description |
| :------------ | :----------------------------------------- | :---------------------------------------------------------------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) | the file system tree |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) | the file system tree |
| `projectName` | `string` | unique name. Often directories are part of the name (e.g., mydir-mylib) |
#### Returns
@@ -1157,7 +1177,7 @@ Works as if you invoked the target yourself without passing any command lint ove
### readWorkspaceConfiguration
**readWorkspaceConfiguration**(`host`): [`WorkspaceConfiguration`](../../react/nx-devkit/index#workspaceconfiguration)
**readWorkspaceConfiguration**(`tree`): [`WorkspaceConfiguration`](../../react/nx-devkit/index#workspaceconfiguration)
Read general workspace configuration such as the default project or cli settings
@@ -1167,7 +1187,7 @@ This does _not_ provide projects configuration, use [readProjectConfiguration](.
| Name | Type |
| :----- | :----------------------------------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) |
#### Returns
@@ -1177,14 +1197,14 @@ This does _not_ provide projects configuration, use [readProjectConfiguration](.
### removeDependenciesFromPackageJson
**removeDependenciesFromPackageJson**(`host`, `dependencies`, `devDependencies`, `packageJsonPath?`): [`GeneratorCallback`](../../react/nx-devkit/index#generatorcallback)
**removeDependenciesFromPackageJson**(`tree`, `dependencies`, `devDependencies`, `packageJsonPath?`): [`GeneratorCallback`](../../react/nx-devkit/index#generatorcallback)
Remove Dependencies and Dev Dependencies from package.json
For example:
```typescript
removeDependenciesFromPackageJson(host, ['react'], ['jest']);
removeDependenciesFromPackageJson(tree, ['react'], ['jest']);
```
This will **remove** `react` and `jest` from the dependencies and devDependencies sections of package.json respectively.
@@ -1193,7 +1213,7 @@ This will **remove** `react` and `jest` from the dependencies and devDependencie
| Name | Type | Default value | Description |
| :---------------- | :----------------------------------------- | :--------------- | :-------------------------------------------------------------------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) | `undefined` | - |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) | `undefined` | - |
| `dependencies` | `string`[] | `undefined` | Dependencies to be removed from the dependencies section of package.json |
| `devDependencies` | `string`[] | `undefined` | Dependencies to be removed from the devDependencies section of package.json |
| `packageJsonPath` | `string` | `'package.json'` | - |
@@ -1208,7 +1228,7 @@ Callback to uninstall dependencies only if necessary. undefined is returned if c
### removeProjectConfiguration
**removeProjectConfiguration**(`host`, `projectName`): `void`
**removeProjectConfiguration**(`tree`, `projectName`): `void`
Removes the configuration of an existing project.
@@ -1219,7 +1239,7 @@ The utility will update both files.
| Name | Type |
| :------------ | :----------------------------------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) |
| `projectName` | `string` |
#### Returns
@@ -1399,7 +1419,7 @@ Rename and transpile any new typescript files created to javascript files
### updateJson
**updateJson**<`T`, `U`\>(`host`, `path`, `updater`, `options?`): `void`
**updateJson**<`T`, `U`\>(`tree`, `path`, `updater`, `options?`): `void`
Updates a JSON value to the file system tree
@@ -1414,7 +1434,7 @@ Updates a JSON value to the file system tree
| Name | Type | Description |
| :--------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) | File system tree |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) | File system tree |
| `path` | `string` | Path of JSON file in the Tree |
| `updater` | (`value`: `T`) => `U` | Function that maps the current value of a JSON document to a new value to be written to the document |
| `options?` | [`JsonParseOptions`](../../react/nx-devkit/index#jsonparseoptions) & [`JsonSerializeOptions`](../../react/nx-devkit/index#jsonserializeoptions) | Optional JSON Parse and Serialize Options |
@@ -1427,7 +1447,7 @@ Updates a JSON value to the file system tree
### updateProjectConfiguration
**updateProjectConfiguration**(`host`, `projectName`, `projectConfiguration`): `void`
**updateProjectConfiguration**(`tree`, `projectName`, `projectConfiguration`): `void`
Updates the configuration of an existing project.
@@ -1438,7 +1458,7 @@ both files.
| Name | Type | Description |
| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :---------------------------------------------------------------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) | the file system tree |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) | the file system tree |
| `projectName` | `string` | unique name. Often directories are part of the name (e.g., mydir-mylib) |
| `projectConfiguration` | [`ProjectConfiguration`](../../react/nx-devkit/index#projectconfiguration) & [`NxJsonProjectConfiguration`](../../react/nx-devkit/index#nxjsonprojectconfiguration) | project configuration |
@@ -1450,13 +1470,13 @@ both files.
### updateTsConfigsToJs
**updateTsConfigsToJs**(`host`, `options`): `void`
**updateTsConfigsToJs**(`tree`, `options`): `void`
#### Parameters
| Name | Type |
| :-------------------- | :----------------------------------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) |
| `options` | `Object` |
| `options.projectRoot` | `string` |
@@ -1468,7 +1488,7 @@ both files.
### updateWorkspaceConfiguration
**updateWorkspaceConfiguration**(`host`, `workspaceConfig`): `void`
**updateWorkspaceConfiguration**(`tree`, `workspaceConfig`): `void`
Update general workspace configuration such as the default project or cli settings.
@@ -1478,7 +1498,7 @@ This does _not_ update projects configuration, use [updateProjectConfiguration](
| Name | Type |
| :---------------- | :----------------------------------------------------------------------------- |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) |
| `workspaceConfig` | [`WorkspaceConfiguration`](../../react/nx-devkit/index#workspaceconfiguration) |
#### Returns
@@ -1509,7 +1529,7 @@ Utility to act on all files in a tree that are not ignored by git.
### writeJson
**writeJson**<`T`\>(`host`, `path`, `value`, `options?`): `void`
**writeJson**<`T`\>(`tree`, `path`, `value`, `options?`): `void`
Writes a JSON value to the file system tree
@@ -1523,7 +1543,7 @@ Writes a JSON value to the file system tree
| Name | Type | Description |
| :--------- | :------------------------------------------------------------------------- | :------------------------------ |
| `host` | [`Tree`](../../react/nx-devkit/index#tree) | File system tree |
| `tree` | [`Tree`](../../react/nx-devkit/index#tree) | File system tree |
| `path` | `string` | Path of JSON file in the Tree |
| `value` | `T` | Serializable value to write |
| `options?` | [`JsonSerializeOptions`](../../react/nx-devkit/index#jsonserializeoptions) | Optional JSON Serialize Options |
@@ -223,4 +223,4 @@ Run commands in parallel
Type: `string`
String to appear in `stdout` or `stderr` that indicates that the task is done. This option can only be used when multiple commands are run and `parallel` is set to `true`. If not specified, the task is done when all the child processes complete.
String to appear in `stdout` or `stderr` that indicates that the task is done. When running multiple commands, this option can only be used when `parallel` is set to `true`. If not specified, the task is done when all the child processes complete.
+1 -1
View File
@@ -2,7 +2,7 @@
Nx is a smart and extensible build framework to help you architect, test, and build at any scale — integrating seamlessly with modern technologies and frameworks while providing a distributed graph-based task execution, computation caching, smart rebuilds of affected projects, powerful code generators, editor support, GitHub apps, and more
Nx helps you develop [React](/{{framework}}/react/overview) applications with fully integrated support for modern tools and libraries like [Jest](/{{framework}}/jest/overview), [Cypress](/{{framework}}/cypress/overview), [Storybook](/{{framework}}/storybook/overview), [ESLint](/{{framework}}/linter/eslint), and more. Nx also supports React frameworks like [Gatsby](/{{framework}}/gatsby/overview) and [Next.js](/{{framework}}/next/overview).
Nx helps you develop [React](/{{framework}}/react/overview) applications with fully integrated support for modern tools and libraries like [Jest](/{{framework}}/jest/overview), [Cypress](/{{framework}}/cypress/overview), [Storybook](/{{framework}}/storybook/overview), [ESLint](/{{framework}}/linter/eslint), and more. Nx also supports React frameworks like [Gatsby](/{{framework}}/gatsby/overview) and [Next.js](/{{version}}/react/guides/nextjs).
## 10-Minute Nx Overview
@@ -32,4 +32,45 @@ When everything is updated appropriately, for our `tuskdesk` example we would se
![image](./next-deploy-vercel-2.png)
## Skipping build if the application is not affected
One of the core features of Nx is to run code quality checks and builds only for projects that are affected by recent code changes. We can use [Vercel's ignored build step feature](https://vercel.com/docs/platform/projects#ignored-build-step) to only build our application if it is affected.
We are going to achieve this by creating a shell script in our Nx workspace that will be invoked by Vercel.
```sh
# Name of the app to check. Change this to your application name!
APP=tuskdesk
# Determine version of Nx installed
NX_VERSION=$(node -e "console.log(require('./package.json').devDependencies['@nrwl/workspace'])")
# Install @nrwl/workspace in order to run the affected command
npm install -D @nrwl/workspace@$NX_VERSION --prefer-offline
# Run the affected command, comparing latest commit to the one before that
npx nx affected:apps --plain --base HEAD~1 --head HEAD | grep $APP -q
# Store result of the previous command (grep)
IS_AFFECTED=$?
if [ $IS_AFFECTED -eq 1 ]; then
echo "🛑 - Build cancelled"
exit 0
elif [ $IS_AFFECTED -eq 0 ]; then
echo "✅ - Build can proceed"
exit 1
fi
```
There are a few points worth noting about this script.
Firstly, you might have noticed that we are running `npm install` (feel free to use `yarn add` instead) in this script, as a result running it will take some time. Having said that, it is usually still much faster than installing all dependencies and running the build of your application unconditionally.
Secondly, this script only compares changes introduced in a single latest commit. So if you push multiple new commits - the script will only check if your application is affected by changes in the latest commit. In the future, there should be an environment variable in Vercel to determine what the base for the affected comparison should be.
Once you've saved this script in your Nx workspace, for example in `tools/ignore-vercel-build.sh`, we need to point Vercel to use this script.
![image](./next-deploy-vercel-3.png)
Naturally, you can continue on and set any additional Environment Variables etc that may be appropriate for your projects, but we have now covered the key points needed to deploy Next.js projects from Nx workspaces on Vercel!
+1 -1
View File
@@ -61,7 +61,7 @@ For example:
2. `workspaceRoot/apps/my-app/.env` contains `AUTH_URL=https://prod-url.com/auth`
3. Nx will first load the variables from `apps/my-app/.env.local` into the process. When it tries to load the variables from `apps/my-app/.env`, it will notice that `AUTH_URL` already exists, so it will ignore it.
We recommend nesting your **app** specific `env` files in `apps/your-app`, and creating workspace/root level `env` files for workspace-specific settings (like the [Nx Cloud token](/{{framework}}/core-extended/computation-caching#nx-cloud-and-distributed-computation-caching)).
We recommend nesting your **app** specific `env` files in `apps/your-app`, and creating workspace/root level `env` files for workspace-specific settings (like the [Nx Cloud token](/{{framework}}/core-extended/computation-caching#distributed-computation-caching)).
### Pointing to custom env files
Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

+16 -225
View File
@@ -27,7 +27,6 @@ If there's no `.storybook` folder at the root of the workspace, one is created.
├── .storybook/
│ ├── main.js
│ ├── tsconfig.json
│ └── webpack.config.js
├── apps/
├── libs/
├── nx.json
@@ -42,9 +41,8 @@ Also, a project-specific `.storybook` folder is added in the root of the project
<project root>/
├── .storybook/
│ ├── main.js
│ ├── config.js
│ ├── preview.js
│ ├── tsconfig.json
│ └── webpack.config.js
├── src/
├── README.md
├── tsconfig.json
@@ -125,9 +123,7 @@ To register an [addon](https://storybook.js.org/addons/) for all storybook insta
1. In `/.storybook/main.js`, in the `addons` array of the `module.exports` object, add the new addon:
```typescript
module.exports = {
stories: [...],
...,
addons: [..., '@storybook/addon-essentials'],
addons: [..., '@storybook/addon-essentials'],
};
```
2. If a decorator is required, in each project's `<project-path>/.storybook/preview.js`, you can export an array called `decorators`.
@@ -144,9 +140,13 @@ To register an [addon](https://storybook.js.org/addons/) for a single storybook
1. In `main.js`, in the `addons` array of the `module.exports` object, add the new addon:
```typescript
module.exports = {
stories: [...],
...,
addons: [..., '@storybook/addon-essentials'],
stories: [...],
addons: [
...,
'@nrwl/react/plugins/storybook',
'@storybook/addon-essentials'
],
...
};
```
2. If a decorator is required, in `preview.js` you can export an array called `decorators`.
@@ -156,221 +156,12 @@ To register an [addon](https://storybook.js.org/addons/) for a single storybook
export const decorators = [someDecorator];
```
### More Information
## Migrations
Here's more information on common migration scenarios for Storybook with Nx. For Storybook specific migrations that are not automatically handled by Nx please refer to the [official Storybook page](https://storybook.js.org/)
- [Upgrading to Storybook 6](/react/storybook/upgrade-storybook-v6)
## More Information
For more on using Storybook, see the [official Storybook documentation](https://storybook.js.org/docs/basics/introduction/).
## From knobs to controls
Storybook v6 moves from "knobs" to args and controls when it comes to defining and manipulating your storybook
component properties. More can be found [on the official Storybook docs](https://storybook.js.org/docs/react/writing-stories/args).
From **Nx v12.5** and on, the `@nrwl/storybook` package will be using `@storybook/addon-controls` instead of `@storybook/addon-knobs` to generate stories.
### For new Nx workspaces
- Generators will generate your Storybook configuration files and your Stories using Controls/args instead of knobs
- The `storybook-configuration` generator will install the [`@storybook/addon-essentials`](https://storybook.js.org/docs/riot/essentials/introduction) package, part of which is `@storybook/addon-controls`. This includes some more "essential" Storybook features (eg. `docs`). You can [disable features you do not need](https://storybook.js.org/docs/riot/essentials/introduction#disabling-addons) anytime in your `main.js`.
- Cypress e2e tests will be generated, [using the args URL](https://storybook.js.org/docs/react/writing-stories/args#setting-args-through-the-url) to set args in the controls.
### For existing Nx workspaces
- If you `nx migrate` to the latest version, your `package.json` will be updated to include the `@storybook/addon-essentials` package. The `@storybook/addon-essentials` addon will be added in your `addons` array in your root `main.js` file. You will need to run `npm/yarn install` to have it installed.
- If you install manually the latest version of `@nrwl/storybook`, `@nrwl/workspace` and `@nrwl/angular` or `@nrwl/react`, you will need to manually do `yarn add -D @storybook/addon-essentials`. You will also need to add the addon manually in your `addons` array in your root `main.js` file.
- All the stories you generate from that moment on will be using controls/args
- Your existing stories will not be touched and will still work
## Upgrading to Storybook 6 (and Nx versions >10.1.x)
Nx now comes with [Storybook version 6](https://storybook.js.org/releases/6.0). Chances are, if you used Nx version `10.1.x` or older with Storybook, you are using [Storybook version 5.3](https://storybook.js.org/releases/5.3) with configuration files of [Storybook version 5.2](https://storybook.js.org/releases/5.2).
Nx version `10.2.x` will continue to support Storybook version `5.2.x`, however newer versions of Nx will only support Storybook version `6` (and on).
When you are running the Nx workspace migration script, your Storybook instances and configurations across your apps and libraries will NOT be migrated automatically. We chose not to migrate your Storybook instances and configurations across your apps and libraries automatically, since there a number of breaking changes that Storybook introduced in versions `5.3` and `6.0`, and making decisions on what to migrate automatically would risk the integrity of your code.
Instead, when you choose to migrate from Nx versions `<10.1.x` to Nx versions `>10.2.x` (using the Nx migration script - `nx migrate`) we will keep your Storybook packages and Storybook instances and configurations intact. We suggest that you do the migration on your own, using the guide below, with all the references to the official Storybook migration guides. Look at the use cases below, and follow the one that matches your case.
### Use cases:
#### Use case 1: Create an Nx workspace from scratch using the latest version of Nx
If you are creating an Nx workspace using the latest version of Nx, the latest version of Storybook (version 6) will be used as well. You do not need to do anything.
#### Use case 2: I already have an Nx workspace that does NOT use Storybook and I want to migrate to the latest Nx
If you already have an Nx workspace with a previous version of Nx that does NOT use Storybook, and you migrate to the latest Nx using the migrate scripts provided by Nx, and then, after the migration to the latest Nx, you choose to add Storybook, the latest version of Storybook will be used. You do not need to do anything.
#### Use case 3: I already have an Nx workspace with Storybook and I want to migrate to the latest Nx
In that case, when you run the Nx migration scripts, the scripts will ignore the Storybook packages, the Storybook configuration files, the Storybook instances in your apps and libraries, and all the generated stories. If you continue to add Storybook configurations and Storybook instances to new libraries and applications, then the version of Storybook that you already have will be used (most probably, if you have not changed anything manually, that version will be `5.3.9` using, however, the configuration files of `5.2`). You will have to do the [upgrade to the latest Storybook on your own, manually](#upgrading-to-storybook-6-manually). After that, Nx will use that version, and configure all new Storybook instances using the new version.
### Upgrading to Storybook 6 using the Nx migration generator
#### Some info about the generator
The `@nrwl/react:storybook-migrate-defaults-5-to-6` generator will not exactly do a migration. It will perform the following actions:
- It will generate new Storybook configuration files using the new (`>6.x`) Storybook way. The way it will do that is, it will look into `workspace.json` and it will find all the projects that have a `Storybook` configuration. Using the `configFolder` path provided there, it will go and generate new Storybook instances in all these paths. Finally, it will generate a new Storybook instance at the root directory.
- If you choose to `keepOld`, then it will add all your existing Storybook configuration files into another folder labeled `.old_storybook`.
- It will update all the Storybook-related (`@storybook/*`) packages in your `package.json`.
#### How to use the generator
That way, you can have working Storybook instances for all your projects just by running
```
nx g @nrwl/react:storybook-migrate-defaults-5-to-6
```
#### What if I had made changes to the defaults?
In case you had made customizations to the default Storybook configurations, you can then manually change each of your Storybook instance configuration files using the official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) to make sure you use the new syntax. Your old configuration files are available to you to use as a reference.
Please check out this official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).
#### What if I am not ready to change everything at once?
The generator gives you the option to migrate one project at a time. You can provide the `--name=PROJECT_NAME` flag, and then the generator will **only** generate new files for the specified project.
Please note that this option will NOT update all the Storybook-related (`@storybook/*`) packages in your `package.json`, or the root Storybook folder. The reason is that if you want to do the migration gradually, one project at a time, you want your old, existing, projects, to still work. That way, you will still be able to run your old, non-migrated Storybook projects. However, you will not be able to run any migrated Storbook projects. Once you have migrated all your Storybook projects, you can run `nx g @nrwl/react:storybook-migrate-defaults-5-to-6` once again, and the generator will take care of updating all the Storybook-related (`@storybook/*`) packages in your `package.json` and it will also generate the new Storybook files for the root Storybook directory.
#### General tip:
**Commit any changes you have locally**. We would suggest that you start the migration with a clean git history, in case anything goes wrong.
### Upgrading to Storybook 6 manually
There is really no great reason for doing the migration completely manually. The `@nrwl/react:storybook-migrate-defaults-5-to-6` generator [will take care of Steps 1, 2 and 3](#upgrading-to-storybook-6-using-the-nx-migration-generator). What you will need to do after running the generator is that you have to manually migrate any custom changes you had done to the default Storybook configuration files that were automatically generated by Nx when you first used Nx Storybook. To do the manual migration you should use the official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).
However, if you still want to do everything manually, these are the steps you should follow:
#### Step 0:
**Commit any changes you have locally**. We would suggest that you start the migration with a clean git history, in case anything goes wrong.
#### Step 1: Changing the configuration files from version 5.2 to 5.3
The most noticeable change in Storybook versions newer than `5.2` is that the configuration files have changed names and content.
Quoting from the [official Storybook migration guide](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-52x-to-53x):
- `presets.js` has been renamed to `main.js`. `main.js` is the main point of configuration for storybook.
- `config.js` has been renamed to `preview.js`. `preview.js` configures the "preview" iframe that renders your components.
- `addons.js` has been renamed to `manager.js`. `manager.js` configures Storybook's "manager" UI that wraps the preview, and also configures addons panel.
Please follow the [official Storybook version 5.2.x to 5.3.x migration guide](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-52x-to-53x) to change your files accordingly.
#### Step 2: Going from version 5.3 to 6.0
Please check out this official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).
- One big change in Storybook version `6` is that it has **built-in Typescript support**. This means that you can remove Typescript configurations from your configuration files.
- Please also **check that your stories match any differences in syntax** introduced in versions `5.3` and `6.0`.
#### Step 3: Upgrade all `@storybook/*` packages in your project
Check your `package.json` file for all `@storybook` packages. Install the latest versions of these, using `yarn`:
For example:
```bash
yarn add --dev @storybook/react@latest
```
#### Step 4: Check that everything works as expected
Check that everything works as expected. If you are still having trouble, you can submit you issue in the [GitHub Nx repo](https://github.com/nrwl/nx). We wish you luck!
### Sample files for manual upgrade
If you have not changed the content of the files which the `storybook-configuration` generator produced, you can use the following samples to migrate to Storybook `6`:
#### Configuring the root `./storybook` directory
- In the root `./storybook` directory, create a new file named `main.js` with the following content:
```typescript
module.exports = {
stories: [],
addons: ['@storybook/addon-essentials'],
};
```
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. If you are using the default generated files without any changes, you should not have any addons. You can now delete the `addons.js` file.
- The other two files remain unchanged.
#### Configuring the Storybook instances across apps and libraries - the library-specific `./storybook` directories
- In the library `./storybook` directory, create a new file named `main.js` with the following content:
```typescript
const lib_main_module = require('../../.storybook/main');
lib_main_module.stories.push('../src/lib/**/*.stories.mdx');
lib_main_module.stories.push('../src/lib/**/*.stories.@(js|jsx|ts|tsx)');
module.exports = lib_main_module;
```
Please take extra care making sure that the path to the root `./storybook` directory provided in the first line is correct.
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. You can add any addons in the `addons` module array using the following syntax:
```typescript
lib_main_module.addons.push('<YOUR_ADDON_HERE>');
```
After you add any addons in the `main.js` file, you can safely delete the `addons.js` file. If you are using the default generated files without any changes, your `addons.js` file should be empty (but an import line, referencing the root `addons.js` file).
- Rename the file `config.js` to `preview.js` and remove the last line where your stories paths are configured. Now, the contents of the `preview.js` file will look like this:
```typescript
import { addDecorator } from '@storybook/react';
addDecorator(<YourDecorator>);
```
- Modify the contents of `webpack.config.js`. Remove the following lines, which are the TypeScript configuration, which is not needed by Storybook any more:
```typescript
config.resolve.extensions.push('.ts', '.tsx');
config.module.rules.push({
test: /\.(ts|tsx)$/,
loader: require.resolve('babel-loader'),
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript',
],
},
});
```
#### Check final folder structure
Your folder structure should now look like this:
```treeview
<workspace name>/
├── .storybook/
│ ├── main.js
│ ├── tsconfig.json
│ └── webpack.config.js
├── apps/
├── libs/
│ └── <library name>/
│ ├── .storybook/
│ │ ├── main.js
│ │ ├── tsconfig.json
│ │ └── webpack.config.js
│ ├── src/
│ ├── README.md
│ ├── tsconfig.json
│ └── etc...
├── nx.json
├── package.json
├── README.md
└── etc...
```
+194
View File
@@ -0,0 +1,194 @@
# Upgrading to Storybook 6 (and Nx versions >10.1.x)
Nx now comes with [Storybook version 6](https://storybook.js.org/releases/6.0). Chances are, if you used Nx version `10.1.x` or older with Storybook, you are using [Storybook version 5.3](https://storybook.js.org/releases/5.3) with configuration files of [Storybook version 5.2](https://storybook.js.org/releases/5.2).
Nx version `10.2.x` will continue to support Storybook version `5.2.x`, however newer versions of Nx will only support Storybook version `6` (and on).
When you are running the Nx workspace migration script, your Storybook instances and configurations across your apps and libraries will NOT be migrated automatically. We chose not to migrate your Storybook instances and configurations across your apps and libraries automatically, since there a number of breaking changes that Storybook introduced in versions `5.3` and `6.0`, and making decisions on what to migrate automatically would risk the integrity of your code.
Instead, when you choose to migrate from Nx versions `<10.1.x` to Nx versions `>10.2.x` (using the Nx migration script - `nx migrate`) we will keep your Storybook packages and Storybook instances and configurations intact. We suggest that you do the migration on your own, using the guide below, with all the references to the official Storybook migration guides. Look at the use cases below, and follow the one that matches your case.
## Use Cases
### Use case 1: Create an Nx workspace from scratch using the latest version of Nx
If you are creating an Nx workspace using the latest version of Nx, the latest version of Storybook (version 6) will be used as well. You do not need to do anything.
### Use case 2: I already have an Nx workspace that does NOT use Storybook and I want to migrate to the latest Nx
If you already have an Nx workspace with a previous version of Nx that does NOT use Storybook, and you migrate to the latest Nx using the migrate scripts provided by Nx, and then, after the migration to the latest Nx, you choose to add Storybook, the latest version of Storybook will be used. You do not need to do anything.
### Use case 3: I already have an Nx workspace with Storybook and I want to migrate to the latest Nx
In that case, when you run the Nx migration scripts, the scripts will ignore the Storybook packages, the Storybook configuration files, the Storybook instances in your apps and libraries, and all the generated stories. If you continue to add Storybook configurations and Storybook instances to new libraries and applications, then the version of Storybook that you already have will be used (most probably, if you have not changed anything manually, that version will be `5.3.9` using, however, the configuration files of `5.2`). You will have to do the [upgrade to the latest Storybook on your own, manually](#upgrading-to-storybook-6-manually). After that, Nx will use that version, and configure all new Storybook instances using the new version.
## Upgrading to Storybook 6 using the Nx migration generator
### Some info about the generator
The `@nrwl/react:storybook-migrate-defaults-5-to-6` generator will not exactly do a migration. It will perform the following actions:
- It will generate new Storybook configuration files using the new (`>6.x`) Storybook way. The way it will do that is, it will look into `workspace.json` and it will find all the projects that have a `Storybook` configuration. Using the `configFolder` path provided there, it will go and generate new Storybook instances in all these paths. Finally, it will generate a new Storybook instance at the root directory.
- If you choose to `keepOld`, then it will add all your existing Storybook configuration files into another folder labeled `.old_storybook`.
- It will update all the Storybook-related (`@storybook/*`) packages in your `package.json`.
### How to use the generator
That way, you can have working Storybook instances for all your projects just by running
```
nx g @nrwl/react:storybook-migrate-defaults-5-to-6
```
### What if I had made changes to the defaults?
In case you had made customizations to the default Storybook configurations, you can then manually change each of your Storybook instance configuration files using the official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) to make sure you use the new syntax. Your old configuration files are available to you to use as a reference.
Please check out this official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).
### What if I am not ready to change everything at once?
The generator gives you the option to migrate one project at a time. You can provide the `--name=PROJECT_NAME` flag, and then the generator will **only** generate new files for the specified project.
Please note that this option will NOT update all the Storybook-related (`@storybook/*`) packages in your `package.json`, or the root Storybook folder. The reason is that if you want to do the migration gradually, one project at a time, you want your old, existing, projects, to still work. That way, you will still be able to run your old, non-migrated Storybook projects. However, you will not be able to run any migrated Storbook projects. Once you have migrated all your Storybook projects, you can run `nx g @nrwl/react:storybook-migrate-defaults-5-to-6` once again, and the generator will take care of updating all the Storybook-related (`@storybook/*`) packages in your `package.json` and it will also generate the new Storybook files for the root Storybook directory.
### General tip:
**Commit any changes you have locally**. We would suggest that you start the migration with a clean git history, in case anything goes wrong.
## Upgrading to Storybook 6 manually
There is really no great reason for doing the migration completely manually. The `@nrwl/react:storybook-migrate-defaults-5-to-6` generator [will take care of Steps 1, 2 and 3](#upgrading-to-storybook-6-using-the-nx-migration-generator). What you will need to do after running the generator is that you have to manually migrate any custom changes you had done to the default Storybook configuration files that were automatically generated by Nx when you first used Nx Storybook. To do the manual migration you should use the official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).
However, if you still want to do everything manually, these are the steps you should follow:
### Step 0:
**Commit any changes you have locally**. We would suggest that you start the migration with a clean git history, in case anything goes wrong.
### Step 1: Changing the configuration files from version 5.2 to 5.3
The most noticeable change in Storybook versions newer than `5.2` is that the configuration files have changed names and content.
Quoting from the [official Storybook migration guide](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-52x-to-53x):
- `presets.js` has been renamed to `main.js`. `main.js` is the main point of configuration for storybook.
- `config.js` has been renamed to `preview.js`. `preview.js` configures the "preview" iframe that renders your components.
- `addons.js` has been renamed to `manager.js`. `manager.js` configures Storybook's "manager" UI that wraps the preview, and also configures addons panel.
Please follow the [official Storybook version 5.2.x to 5.3.x migration guide](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-52x-to-53x) to change your files accordingly.
### Step 2: Going from version 5.3 to 6.0
Please check out this official [Storybook 6 Migration Guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) article, as well as the [detailed guides here](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#from-version-53x-to-60x).
- One big change in Storybook version `6` is that it has **built-in Typescript support**. This means that you can remove Typescript configurations from your configuration files.
- Please also **check that your stories match any differences in syntax** introduced in versions `5.3` and `6.0`.
### Step 3: Upgrade all `@storybook/*` packages in your project
Check your `package.json` file for all `@storybook` packages. Install the latest versions of these, using `yarn`:
For example:
```bash
yarn add --dev @storybook/react@latest
```
### Step 4: Check that everything works as expected
Check that everything works as expected. If you are still having trouble, you can submit you issue in the [GitHub Nx repo](https://github.com/nrwl/nx). We wish you luck!
### Sample files for manual upgrade
If you have not changed the content of the files which the `storybook-configuration` generator produced, you can use the following samples to migrate to Storybook `6`:
### Configuring the root `./storybook` directory
- In the root `./storybook` directory, create a new file named `main.js` with the following content:
```typescript
module.exports = {
stories: [],
addons: ['@storybook/addon-essentials'],
};
```
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. If you are using the default generated files without any changes, you should not have any addons. You can now delete the `addons.js` file.
- The other two files remain unchanged.
### Configuring the Storybook instances across apps and libraries - the library-specific `./storybook` directories
- In the library `./storybook` directory, create a new file named `main.js` with the following content:
```typescript
const lib_main_module = require('../../.storybook/main');
lib_main_module.stories.push('../src/lib/**/*.stories.mdx');
lib_main_module.stories.push('../src/lib/**/*.stories.@(js|jsx|ts|tsx)');
module.exports = lib_main_module;
```
Please take extra care making sure that the path to the root `./storybook` directory provided in the first line is correct.
- If you have any addons in the `addons.js` file, add them in the `addons` array in the `main.js` file. You can add any addons in the `addons` module array using the following syntax:
```typescript
lib_main_module.addons.push('<YOUR_ADDON_HERE>');
```
After you add any addons in the `main.js` file, you can safely delete the `addons.js` file. If you are using the default generated files without any changes, your `addons.js` file should be empty (but an import line, referencing the root `addons.js` file).
- Rename the file `config.js` to `preview.js` and remove the last line where your stories paths are configured. Now, the contents of the `preview.js` file will look like this:
```typescript
import { addDecorator } from '@storybook/react';
addDecorator(<YourDecorator>);
```
- Modify the contents of `webpack.config.js`. Remove the following lines, which are the TypeScript configuration, which is not needed by Storybook any more:
```typescript
config.resolve.extensions.push('.ts', '.tsx');
config.module.rules.push({
test: /\.(ts|tsx)$/,
loader: require.resolve('babel-loader'),
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript',
],
},
});
```
### Check final folder structure
Your folder structure should now look like this:
```treeview
<workspace name>/
├── .storybook/
│ ├── main.js
│ ├── tsconfig.json
│ └── webpack.config.js
├── apps/
├── libs/
│ └── <library name>/
│ ├── .storybook/
│ │ ├── main.js
│ │ ├── tsconfig.json
│ │ └── webpack.config.js
│ ├── src/
│ ├── README.md
│ ├── tsconfig.json
│ └── etc...
├── nx.json
├── package.json
├── README.md
└── etc...
```
+45 -43
View File
@@ -1,11 +1,11 @@
# Computation Caching
It's costly to rebuild and retest the same code over and over again. Nx uses a computation cache to never rebuild the same code twice. When connected to Nx cloud, you can share the computation cache with everyone working on the same project.
It's costly to rebuild and retest the same code over and over again. Nx uses a computation cache to never rebuild the same code twice.
**In order not to recompute something twice, we need two things:**
**In order not to recompute something twice, Nx needs two things:**
1. We need to store the results of the computation.
2. We need to know when we are about to compute something we already computed before.
1. To store the results of the computation.
2. To know when you've computed something you've already computed before.
There are three things that tell Nx if something has been computed before:
@@ -15,7 +15,7 @@ There are three things that tell Nx if something has been computed before:
## Source Code Cache Inputs
The result of building/testing an application or a library depends on the source code of that project and all the source codes of all the libraries it depends on (directly or indirectly). It also depends on the configuration files like `package.json`, `workspace.json`, `nx.json`, `tsconfig.base.json`, and `package-lock.json`. The list of these files isn't arbitrary. Nx can deduce most of them by analyzing our codebase. Few will have to be listed manually in the `implicitDependencies` property of `nx.json`.
The result of building/testing an application or a library depends on the source code of that project and all the source codes of all the libraries it depends on (directly or indirectly). It also depends on the configuration files like `package.json`, `workspace.json`, `nx.json`, `tsconfig.base.json`, and `package-lock.json`. The list of these files isn't arbitrary. Nx can deduce most of them by analyzing our codebase. Few have to be listed manually in the `implicitDependencies` property of `nx.json`.
```json
{
@@ -36,7 +36,7 @@ The result of building/testing an application or a library depends on the source
## Runtime Cache Inputs
Things like the version of NodeJS, whether we are running Windows or not, can affect the results of the computation but cannot be deduced statically. Those will have to be configured manually too.
Things like the version of NodeJS, whether you are running Windows or not, can affect the results of the computation but cannot be deduced statically. Those have to be configured manually too.
```json
{
@@ -56,7 +56,7 @@ Things like the version of NodeJS, whether we are running Windows or not, can af
## Args Cache Inputs
Finally, in addition to Source Code Cache Inputs and Runtime Cache Inputs, Nx needs to consider the arguments. I.e., `nx build shop` and `nx build shop --prod` produce different results.
Finally, in addition to Source Code Cache Inputs and Runtime Cache Inputs, Nx needs to consider the arguments: For example, `nx build shop` and `nx build shop --prod` produce different results.
Note, only the flags passed to the builder itself affect results of the computation. For instance, the following commands are identical from the caching perspective.
@@ -70,7 +70,7 @@ nx affected:build # given that myapp is affected
In other words, Nx does not cache what the developer types into the terminal. The args cache inputs consist of: Project Name, Target, Configuration + Args Passed to Builders.
If you build/test/lint… multiple projects, each individual build will have its own cache value and will either be retrieved from cache or run. This means that from the caching point of view, the following command:
If you build/test/lint… multiple projects, each individual build has its own cache value and is either be retrieved from cache or run. This means that from the caching point of view, the following command:
```bash
nx run-many --target=build --projects=myapp1,myapp2
@@ -85,17 +85,17 @@ nx build myapp2
## All Cache Inputs
So the combination of Source Code Cache Inputs, Runtime Cache Inputs, and Args Cache Inputs determine the result of the computation. If anything in the source changes, Nx needs to recompute. If anything in runtime changes, Nx needs to recompute. But if we have already computed the results, we can simply use the stored artifacts.
So the combination of Source Code Cache Inputs, Runtime Cache Inputs, and Args Cache Inputs determine the result of the computation. If anything in the source changes, Nx needs to recompute. If anything in runtime changes, Nx needs to recompute. But if you have already computed the results, the stored artifacts are used.
![all cache inputs](/shared/all-cache-inputs.png)
## What is Cached
Nx works on the process level. Regardless of the tools used to build/test/lint/etc.. your project, the results will be cached.
Nx works on the process level. Regardless of the tools used to build/test/lint/etc.. your project, the results is cached.
Nx sets up hooks to collect stdout/stderr before running the command. All the output will be cached and then replayed during a cache hit.
Nx sets up hooks to collect stdout/stderr before running the command. All the output is cached and then replayed during a cache hit.
Nx will also cache the files generated by a command. The list of folders is listed in the outputs property in `workspace.json`.
Nx also caches the files generated by a command. The list of folders is listed in the outputs property in `workspace.json`.
```json
{
@@ -118,13 +118,30 @@ Nx will also cache the files generated by a command. The list of folders is list
}
```
If the outputs property is missing, Nx will default to caching the appropriate folder in the dist (`dist/apps/myapp` for `myapp` and `dist/libs/somelib` for `somelib`).
If the outputs property is missing, Nx defaults to caching the appropriate folder in the dist (`dist/apps/myapp` for `myapp` and `dist/libs/somelib` for `somelib`).
## Local Computation Caching
**Because the word "cache" appears in the description, the phrase "artifact caching" comes to mind. But this isn't the right way to think about it. What Nx does is really computation memoization.** We can't choose to use or not use the cached value. There are no versions. It is transparent: Nx will skip the computation only when running the computation would have produced the same result.
By default, Nx uses a local computation cache. **Because the word "cache" appears in the description, the phrase "artifact caching" comes to mind. But this isn't the right way to think about it. What Nx does is really computation memoization.** Nx doesn't choose to use or not use the cached value. There are no versions. It is transparent: Nx skips the computation only when running the computation would have produced the same result.
By default, Nx uses a local computation cache. The cache is stored in `node_modules/.cache/nx`. You can change the directory as follows:
Nx stores the cached values only for a week, after which they are deleted. To clear the cache, delete the [cache directory](#customizing-the-cache-directory), and Nx creates a new one the next time it tries to access it.
## Distributed Computation Caching
The computation cache provided by Nx can be distributed across multiple machines. Nx Cloud is a SAAS product that allows you to share the results of running build/test with everyone else working in the same workspace. Learn more at [https://nx.app](https://nx.app). You can also distribute the cache manually using your own storage mechanisms.
## Skipping Cache
Sometimes you want to skip the cache, such as if you are measuring the performance of a command. Use the `--skip-nx-cache` flag to skip checking the computation cache.
```bash
nx build myapp --skip-nx-cache
nx affected:build --skip-nx-cache
```
## Customizing the cache location
The cache is stored in `node_modules/.cache/nx` by default. To change the cache location, update the `cacheDirectory` option for the task runner:
```json
{
@@ -142,51 +159,36 @@ By default, Nx uses a local computation cache. The cache is stored in `node_modu
}
```
Nx stores the cached values only for a week, after which they are deleted. To clear the cache, delete the cache directory, and Nx will create a new one next time it tries to access it.
## Skipping Cache
Sometimes you will want to skip the cache (e.g., if you are measuring the performance of a command). You can do it as follows
```bash
nx build myapp --skip-nx-cache
nx affected:build --skip-nx-cache
```
## Nx Cloud and Distributed Computation Caching
Nx Cloud is a SAAS product that allows you to share the results of running build/test with everyone else working in the same workspace. Learn more at [https://nx.app](https://nx.app).
## Example
Say we are the first ones building some shop app.
Say you are the first one building some shop app.
The `nx build` shop command will build the app by invoking webpack under the hood. It will create a hash key using the combination of `Source Code Cache Inputs`, `Runtime Cache Inputs`, and `Args Cache Inputs`. Nx then will check its local cache to see if this combination has already been built on this machine. If the answer is "no", it will check the Nx Cloud cache (if the workspace is connected to it) to see if someone else has already built it. If the answer is "no", it will run the build.
The `nx build` shop command builds the app by invoking Webpack under the hood. It creates a hash key using the combination of `Source Code Cache Inputs`, `Runtime Cache Inputs`, and `Args Cache Inputs`. Nx then checks its local cache to see if this combination has already been built on this machine. If the answer is "no", it checks the Nx Cloud cache (if the workspace is connected to it) to see if someone else has already built it. If the answer is "no", it runs the build.
It will set up hooks to collect stdout/stderr, and once the build is complete, it will store the command line output into a file in the local cache. It will also copy the produced files there as well. After that it will spawn a separate process to upload the artifacts to the Nx Cloud cache.
It sets up hooks to collect stdout/stderr, and after the build is complete, it stores the command line output into a file in the local cache. It also copies the produced files there. After that it spawns a separate process to upload the artifacts to the Nx Cloud cache.
If we rerun the same command, Nx will find the artifact in the local cache and will replay the output from it and will restore the necessary files.
If you rerun the same command, Nx finds the artifact in the local cache and replays the output from it and restores the necessary files.
Imagine someone else on the team is trying to build `nx build shop`. As before Nx will use `Source Code Cache Inputs`, `Runtime Cache Inputs`, and `Args Cache Inputs` to get the computation hash key. It will then check the local cache. The result won't be there, so it will check the remote cache. **It will find the record there, so it will download it into its local cache first and then print the stored stdout/stderr and copy the files to the place where they would normally be created. The terminal output and the created files are exactly the same as if the person ran the computation themselves.**
Someone else on the team check outs the changes, and is trying to build `nx build shop`. As before Nx uses `Source Code Cache Inputs`, `Runtime Cache Inputs`, and `Args Cache Inputs` to get the computation hash key. It then checks the local cache. The results won't be there, so it checks the remote cache. **It finds the record there, so it downloads it into its local cache first, prints the stored stdout/stderr, and copies the files to the place where they would normally be created. The terminal output and the created files are exactly the same as if the person ran the computation themselves.**
The "someone else" in this scenario doesn't have to be a real person. For instance, every CI run will likely use a different agent. When the agents can all access the same remote cache, the CI time goes down drastically.
The "someone else" in this scenario doesn't have to be a real person. For instance, every CI run likely use a different agent. When the agents can all access the same remote cache, the CI time goes down drastically.
![cache example](/shared/caching-example.png)
The `nx test shop` command, which in this case uses Jest, works similarly. The combination of `Source Code Cache Inputs`, `Runtime Cache Inputs`, and `Args Cache Inputs` determines the computation. The command won't emit any files, but the terminal output will be captured and stored.
The `nx test shop` command, which in this case uses Jest, works similarly. The combination of `Source Code Cache Inputs`, `Runtime Cache Inputs`, and `Args Cache Inputs` determines the computation. The command won't emit any files, but the terminal output bes captured and stored.
## Caching and Affected
In addition to the caching, which works against the current state of the codebase and the environment, Nx also is able to look at the code change itself (e.g., PR), and figure out what can be broken by it, and only rebuild and retest what is affected. Why use both?
In addition to the caching, which works against the current state of the codebase and the environment, Nx also looks at the code change itself, and figures out what can be broken by it, and only rebuilds and retests what is affected. Why use both?
Affected and caching are used to solve the same problem: minimize the computation. But they do it differently, and the combination provides better results than one or the other.
The affected command looks at the before and after states of the workspaces and figures out what can be broken by a change. Because it knows the two states, it can deduce the nature of the change. For instance, this repository uses React and Angular. If a PR updates the version of React in the root package.json, Nx will know that only half of the projects in the workspace can be affected. It knows what was changed--the version of React was bumped up.
The affected command looks at the before and after states of the workspaces and figures out what can be broken by a change. Because it knows the two states, it can deduce the nature of the change. For instance, this repository uses React and Angular. If a PR updates the version of React in the root package.json, Nx knows that only half of the projects in the workspace can be affected. It knows what was changed--the version of React was bumped up.
Caching simply looks at the current state of the workspace and the environment (e.g., version of Node) and checks if somebody already ran the command against this state. Caching knows that something changed, but because there is no before and after states, it doesn't know the nature of the change. In other words, caching is a lot more conservative.
Caching simply looks at the current state of the workspace and the environment (such as the version of Node) and checks if somebody already ran the command against this state. Caching knows that something changed, but because there is no before and after states, it doesn't know the nature of the change. In other words, caching is a lot more conservative.
If we only use affected, the list of projects that will be retested is small, but if we test the PR twice, we will run all the tests twice.
If you only use affected, the list of projects that are be retested is small, but if you test the PR twice, all the tests are run twice.
If we only use caching, the list of projects that will be retested is larger, but if we test the PR twice, we will only run tests the first time.
If you only use caching, the list of projects that are be retested is larger, but if you test the PR twice, the tests are only run the first time.
Using both allows us to get the best of both worlds. The list of affected projects is as small as it can be, and we never run anything twice.
Using both allows you to get the best of both worlds. The list of affected projects is as small as it can be, and you never run anything twice.
+2 -2
View File
@@ -101,7 +101,7 @@ If you want the generated file or folder name to contain variable values, use `_
## EJS Syntax Quickstart
The EJS syntax can do much more than replace variable names with values. Here are some common techniques.
The [EJS syntax](https://ejs.co/) can do much more than replace variable names with values. Here are some common techniques.
1. Pass a function into the template:
@@ -140,7 +140,7 @@ This is the short version.
```typescript
// typescript file
generateFiles(tree, joinPathFragments(__dirname, './files'), libraryRoot, {
shortVerstion: false,
shortVersion: false,
numRepetitions: 3,
});
```
+24 -23
View File
@@ -1,55 +1,56 @@
# Adding Nx to Lerna/Yarn/PNPM Workspace
If you have a monorepo that is powered by Lerna, Yarn, PNPM, or NPM, you can transform it into an Nx workspace by
running this command: `npx add-nx-to-monorepo`.
If you have a monorepo that is powered by Lerna, Yarn, PNPM, or NPM workpsaces, you can transform it into an Nx workspace by
running this command:
```bash
npx add-nx-to-monorepo
```
See it in action (3-minute video):
<iframe width="560" height="315" src="https://www.youtube.com/embed/jkPeUFhH5h4" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
`npx add-nx-to-monorepo` will do the following:
`npx add-nx-to-monorepo` does the following:
1. Add Nx to your package.json
2. Create `workspace.json` and `nx.json` listing all the projects in the workspace
3. Set up a `tsconfig` file mapping all projects in there
4. Set up Nx Cloud (if you say "yes")
1. Add Nx to your package.json.
2. Create `workspace.json` and `nx.json` listing all the projects in the workspace.
3. Set up a `tsconfig` file mapping all projects in there.
4. Set up Nx Cloud (if you chose "yes").
> If you are familiar with Lerna or Yarn workspaces, check out [this guide](/{{framework}}/guides/lerna-and-nx) (with a 10-min video) showing how to add Nx to a Lerna/Yarn workspace, what the difference is, when to use both and when to use just Nx
## What You Get Right Away
After you run the command above, you can any npm script using Nx. For instance, if `myproj` has a `build` script, you can invoke it using `npx nx build myproj`. If you pass any flags, they will be forwarded to the underlying script.
After you run the command above, you can run any npm script using Nx. For instance, if `myproj` has a `build` script, you can invoke it using `npx nx build myproj`. If you pass any flags, they are forwarded to the underlying script.
### Caching Works
### Computating Caching
Nx supports computation caching. If it has seen the computation you are trying to perform, it's going extract the result from its cache instead of running it. An easy way to see it in action is to run the same command
twice: `npx nx build myproj` and then again `npx nx build myproj`. In addition to restoring all the files, Nx will
replay the terminal output as well, so you don't lose any information when running a cached command.
Nx supports computation caching. If it has seen the computation you are trying to perform, it's going extract the result from its cache instead of running it. To see it in action, run the same command twice: `npx nx build myproj` and then again `npx nx build myproj`. In addition to restoring all the files, Nx replays the terminal output as well, so you don't lose any information when running a cached command.
### Distributed Caching Works
### Distributed Caching
If you said "yes" to Nx Cloud, you can now clone the repo on a different machine (e.g., CI) and run the same command against the same commit and the results will be retrieved from cache. Never compute the same thing twice in your org or CI.
If you said "yes" to Nx Cloud, you can now clone the repo on a different machine such as your Continuous Integration(CI) environment and run the same command against the same commit and the results are retrieved from cache. Never compute the same thing twice in your org or CI.
### Affected Works
### Affected Commands
Nx will automatically analyze your workspace to know what projects are affected by your commit. Simply run: `npx nx affected --target=test --base=main` to see it in action. Often, Nx is able to do a better job detecting
affected than other tools because it looks not just at the changed files but also at the nature of the changes.
Nx automatically analyzes your workspace to know what projects are affected by your commit. Simply run: `npx nx affected --target=test --base=main` to see it in action. Often, Nx is able to do a better job detecting affected than other tools because it looks not just at the changed files but also at the nature of the changes.
### Workspace Visualization
Run `npx nx dep-graph` to see a visualization of your workspace. `npx nx affected:dep-graph` will show what is affected
by your commit. `npx nx dep-graph --watch` will watch your workspace for changes and update the the visualization.
Run `npx nx dep-graph` to see a visualization of your workspace. `npx nx affected:dep-graph` shows what is affected
by your commit. `npx nx dep-graph --watch` watches your workspace for changes and updates the the visualization.
<iframe width="560" height="315" src="https://www.youtube.com/embed/cMZ-ReC-jWU" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
### Github Integration Works
### Github Integration
If you said "yes" to Nx Cloud, you can enable Nx Cloud - Github integration to get a much better overview of what
happens in your PRs.
![Nx Console screenshot](/shared/github.png)
### VS Code Plugin Works
### VS Code Plugin
![Nx Console screenshot](/shared/nx-console-screenshot.png)
@@ -74,7 +75,7 @@ If you want to explore what it feels like to develop with Nx, check out:
## Troubleshooting
The `add-nx-to-monorepo` command will do its best to figure out what projects you have in the repo, but you can always update the list yourself.
The `add-nx-to-monorepo` command does its best to figure out what projects you have in the repo, but you can always update the list yourself.
For instance, you can add/remove/update projects in `workspace.json`.
@@ -88,7 +89,7 @@ For instance, you can add/remove/update projects in `workspace.json`.
}
```
Nx will add a root tsconfig to your repo with something like this:
Nx adds a root tsconfig to your repo with something like this:
```json
{
@@ -76,7 +76,7 @@ builder.addNode({
## Adding New Dependencies to the Project Graph
It's more common for plugins to create new dependencies. First-party code contained in the workspace is registered in `workpspace.json` and is added to the project graph automatically. Whether your project contains TypeScript or say Java, both projects will be created in the same way. However, Nx does not know how to analyze Java sources, and that's what plugins can do.
It's more common for plugins to create new dependencies. First-party code contained in the workspace is registered in `workspace.json` and is added to the project graph automatically. Whether your project contains TypeScript or say Java, both projects will be created in the same way. However, Nx does not know how to analyze Java sources, and that's what plugins can do.
You can create 2 types of dependencies.
+52 -64
View File
@@ -24,21 +24,18 @@ describe('Angular Package', () => {
afterEach(() => removeProject({ onlyOnCI: true }));
it('should work', async () => {
// TODO: npm build is failing for Angular because of webpack 4
// remove this condition once `node` is migrated to webpack 5
if (getSelectedPackageManager() !== 'npm') {
const myapp = uniq('myapp');
const mylib = uniq('mylib');
runCLI(
`generate @nrwl/angular:app ${myapp} --directory=myDir --no-interactive`
);
runCLI(
`generate @nrwl/angular:lib ${mylib} --directory=myDir --add-module-spec --no-interactive`
);
const myapp = uniq('myapp');
const mylib = uniq('mylib');
runCLI(
`generate @nrwl/angular:app ${myapp} --directory=myDir --no-interactive`
);
runCLI(
`generate @nrwl/angular:lib ${mylib} --directory=myDir --add-module-spec --no-interactive`
);
updateFile(
`apps/my-dir/${myapp}/src/app/app.module.ts`,
`
updateFile(
`apps/my-dir/${myapp}/src/app/app.module.ts`,
`
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { MyDir${
@@ -53,66 +50,57 @@ describe('Angular Package', () => {
})
export class AppModule {}
`
);
runCLI(`build my-dir-${myapp} --prod --output-hashing none`);
checkFilesExist(`dist/apps/my-dir/${myapp}/main.js`);
// This is a loose requirement because there are a lot of
// influences external from this project that affect this.
const es2015BundleSize = getSize(
tmpProjPath(`dist/apps/my-dir/${myapp}/main.js`)
);
console.log(
`The current es2015 bundle size is ${es2015BundleSize / 1000} KB`
);
expect(es2015BundleSize).toBeLessThanOrEqual(160000);
// running tests for the app
expectTestsPass(await runCLIAsync(`test my-dir-${myapp} --no-watch`));
// running tests for the lib
expectTestsPass(await runCLIAsync(`test my-dir-${mylib} --no-watch`));
if (runCypressTests()) {
const e2eResults = runCLI(
`e2e my-dir-${myapp}-e2e --headless --no-watch`
);
runCLI(`build my-dir-${myapp} --prod --output-hashing none`);
checkFilesExist(`dist/apps/my-dir/${myapp}/main.js`);
// This is a loose requirement because there are a lot of
// influences external from this project that affect this.
const es2015BundleSize = getSize(
tmpProjPath(`dist/apps/my-dir/${myapp}/main.js`)
);
console.log(
`The current es2015 bundle size is ${es2015BundleSize / 1000} KB`
);
expect(es2015BundleSize).toBeLessThanOrEqual(160000);
// running tests for the app
expectTestsPass(await runCLIAsync(`test my-dir-${myapp} --no-watch`));
// running tests for the lib
expectTestsPass(await runCLIAsync(`test my-dir-${mylib} --no-watch`));
if (runCypressTests()) {
const e2eResults = runCLI(
`e2e my-dir-${myapp}-e2e --headless --no-watch`
);
expect(e2eResults).toContain('All specs passed!');
expect(await killPorts()).toBeTruthy();
}
expect(e2eResults).toContain('All specs passed!');
expect(await killPorts()).toBeTruthy();
}
}, 1000000);
it('should support building in parallel', () => {
// TODO: npm build is failing for Angular because of webpack 4
// remove this condition once `node` is migrated to webpack 5
if (getSelectedPackageManager() !== 'npm') {
if (getSelectedPackageManager() === 'pnpm') {
// TODO: This tests fails with pnpm but we should still enable this for other package managers
return;
}
const myapp = uniq('myapp');
const myapp2 = uniq('myapp');
runCLI(`generate @nrwl/angular:app ${myapp}`);
runCLI(`generate @nrwl/angular:app ${myapp2}`);
runCLI('run-many --target build --all --parallel');
if (getSelectedPackageManager() === 'pnpm') {
// TODO: This tests fails with pnpm but we should still enable this for other package managers
return;
}
const myapp = uniq('myapp');
const myapp2 = uniq('myapp');
runCLI(`generate @nrwl/angular:app ${myapp}`);
runCLI(`generate @nrwl/angular:app ${myapp2}`);
runCLI('run-many --target build --all --parallel');
});
it('should support Ivy', async () => {
// TODO: npm build is failing for Angular because of webpack 4
// remove this condition once `node` is migrated to webpack 5
if (getSelectedPackageManager() !== 'npm') {
const myapp = uniq('myapp');
runCLI(
`generate @nrwl/angular:app ${myapp} --directory=myDir --routing --enable-ivy`
);
const myapp = uniq('myapp');
runCLI(
`generate @nrwl/angular:app ${myapp} --directory=myDir --routing --enable-ivy`
);
runCLI(`build my-dir-${myapp} --aot`);
expectTestsPass(await runCLIAsync(`test my-dir-${myapp} --no-watch`));
}
runCLI(`build my-dir-${myapp} --aot`);
expectTestsPass(await runCLIAsync(`test my-dir-${myapp} --no-watch`));
}, 1000000);
});
});
+12 -4
View File
@@ -45,6 +45,7 @@ export const e2eCwd = `${e2eRoot}/${currentCli()}`;
ensureDirSync(e2eCwd);
let projName: string;
const publishedVersion = `9999.0.2`;
export function uniq(prefix: string) {
return `${prefix}${Math.floor(Math.random() * 10000000)}`;
@@ -116,10 +117,14 @@ export function runCreateWorkspace(
return create ? create.toString() : '';
}
export function packageInstall(pkg: string, projName?: string) {
export function packageInstall(
pkg: string,
projName?: string,
version = publishedVersion
) {
const cwd = projName ? `${e2eCwd}/${projName}` : tmpProjPath();
const pm = getPackageManagerCommand({ path: cwd });
const install = execSync(`${pm.addDev} ${pkg}`, {
const install = execSync(`${pm.addDev} ${pkg}@${version}`, {
cwd,
stdio: [0, 1, 2],
env: process.env,
@@ -166,6 +171,7 @@ export function newProject({ name = uniq('proj') } = {}): string {
const packages = [
`@nrwl/angular`,
`@nrwl/eslint-plugin-nx`,
`@nrwl/cypress`,
`@nrwl/express`,
`@nrwl/gatsby`,
`@nrwl/jest`,
@@ -243,6 +249,10 @@ export function isNotWindows() {
return !isWindows();
}
export function isOSX() {
return process.platform === 'darwin';
}
export function runCommandAsync(
command: string,
opts: RunCmdOpts = {
@@ -607,8 +617,6 @@ export function getPackageManagerCommand({
? ' --scripts-prepend-node-path '
: '';
const publishedVersion = `9999.0.2`;
const [npmMajorVersion] = execSync(`npm -v`).toString().split('.');
return {
@@ -715,7 +715,7 @@ describe('Move Angular Project', () => {
const lib2FilePath = `libs/${lib2}/src/lib/${lib2}.module.ts`;
const lib2File = readFile(lib2FilePath);
expect(lib2File).toContain(
`import { ${newModule} } from '@${proj}/shared/${lib1}';`
`import { ${newModule} } from '@${proj}/shared-${lib1}';`
);
expect(lib2File).toContain(`extends ${newModule}`);
});
@@ -834,7 +834,7 @@ describe('Move Project', () => {
rootTsConfig.compilerOptions.paths[`@${proj}/${lib1}/data-access`]
).toBeUndefined();
expect(
rootTsConfig.compilerOptions.paths[`@${proj}/shared/${lib1}/data-access`]
rootTsConfig.compilerOptions.paths[`@${proj}/shared-${lib1}-data-access`]
).toEqual([`libs/shared/${lib1}/data-access/src/index.ts`]);
expect(moveOutput).toContain(`UPDATE workspace.json`);
@@ -854,7 +854,7 @@ describe('Move Project', () => {
const lib2FilePath = `libs/${lib2}/ui/src/lib/${lib2}-ui.ts`;
const lib2File = readFile(lib2FilePath);
expect(lib2File).toContain(
`import { fromLibOne } from '@${proj}/shared/${lib1}/data-access';`
`import { fromLibOne } from '@${proj}/shared-${lib1}-data-access';`
);
});
@@ -970,7 +970,7 @@ describe('Move Project', () => {
rootTsConfig.compilerOptions.paths[`@${proj}/${lib1}/data-access`]
).toBeUndefined();
expect(
rootTsConfig.compilerOptions.paths[`@${proj}/shared/${lib1}/data-access`]
rootTsConfig.compilerOptions.paths[`@${proj}/shared-${lib1}-data-access`]
).toEqual([`libs/shared/${lib1}/data-access/src/index.ts`]);
expect(moveOutput).toContain(`UPDATE workspace.json`);
@@ -991,7 +991,7 @@ describe('Move Project', () => {
const lib2FilePath = `libs/${lib2}/ui/src/lib/${lib2}-ui.ts`;
const lib2File = readFile(lib2FilePath);
expect(lib2File).toContain(
`import { fromLibOne } from '@${proj}/shared/${lib1}/data-access';`
`import { fromLibOne } from '@${proj}/shared-${lib1}-data-access';`
);
});
@@ -1109,7 +1109,7 @@ describe('Move Project', () => {
rootTsConfig.compilerOptions.paths[`@${proj}/${lib1}/data-access`]
).toBeUndefined();
expect(
rootTsConfig.compilerOptions.paths[`@${proj}/shared/${lib1}/data-access`]
rootTsConfig.compilerOptions.paths[`@${proj}/shared-${lib1}-data-access`]
).toEqual([`packages/shared/${lib1}/data-access/src/index.ts`]);
expect(moveOutput).toContain(`UPDATE workspace.json`);
@@ -1129,7 +1129,7 @@ describe('Move Project', () => {
const lib2FilePath = `packages/${lib2}/ui/src/lib/${lib2}-ui.ts`;
const lib2File = readFile(lib2FilePath);
expect(lib2File).toContain(
`import { fromLibOne } from '@${proj}/shared/${lib1}/data-access';`
`import { fromLibOne } from '@${proj}/shared-${lib1}-data-access';`
);
nxJson = readJson('nx.json');
@@ -8,6 +8,10 @@ import {
VersionMetadata,
} from './documents.models';
export interface StaticDocumentPaths {
params: { segments: string[] };
}
export const flavorList: {
label: string;
value: string;
@@ -26,10 +30,16 @@ export class DocumentsApi {
versions: VersionMetadata[];
documentsMap: Map<string, DocumentMetadata[]>;
}
) {}
) {
if (!options.archiveRoot || !options.previewRoot) {
throw new Error('archive and preview roots cannot be undefined');
}
}
getDefaultVersion(): VersionMetadata {
return this.options.versions.find((v) => v.default);
const found = this.options.versions.find((v) => v.default);
if (found) return found;
throw new Error('Cannot find default version');
}
getVersions(): VersionMetadata[] {
@@ -72,8 +82,8 @@ export class DocumentsApi {
}
}
getStaticDocumentPaths(version: string) {
const paths = [];
getStaticDocumentPaths(version: string): StaticDocumentPaths[] {
const paths: StaticDocumentPaths[] = [];
const defaultVersion = this.getDefaultVersion();
function recur(curr, acc) {
@@ -111,11 +121,12 @@ export class DocumentsApi {
return this.options.previewRoot;
}
if (version === 'latest' || version === 'previous') {
return join(
this.options.archiveRoot,
this.options.versions.find((x) => x.id === version).path
);
const versionPath = this.options.versions.find(
(x) => x.id === version
)?.path;
if (versionPath) {
return join(this.options.archiveRoot, versionPath);
}
throw new Error(`Cannot find root for ${version}`);
@@ -132,7 +143,7 @@ export class DocumentsApi {
let found;
for (const part of path) {
found = items.find((item) => item.id === part);
found = items?.find((item) => item.id === part);
if (found) {
items = found.itemList;
} else {
@@ -1,5 +1,5 @@
export function extractTitle(markdownContent: string): string | null {
return (
/^\s*#\s+(?<title>.+)[\n.]+/.exec(markdownContent)?.groups.title ?? null
/^\s*#\s+(?<title>.+)[\n.]+/.exec(markdownContent)?.groups?.title ?? null
);
}
@@ -29,7 +29,7 @@ describe('MenuApi', () => {
// first basic section item should have prefix by version and flavor
// e.g. "latest/react/getting-started/intro"
expect(menu.sections[0].itemList[0].itemList[0].path).toMatch(
expect(menu?.sections?.[0]?.itemList?.[0]?.itemList?.[0].path).toMatch(
/latest\/react/
);
});
@@ -23,12 +23,14 @@ export function createMenuItems(
return pathData;
};
return items.map((item) => {
return {
...item,
itemList: item.itemList?.map((ii) => createPathMetadata(ii, item.id)),
};
});
return (
items?.map((item) => {
return {
...item,
itemList: item.itemList?.map((ii) => createPathMetadata(ii, item.id)),
};
}) ?? []
);
}
export function getBasicSection(items: MenuItem[]): MenuSection {
@@ -73,7 +75,7 @@ export function getDeepDiveSection(items: MenuItem[]): MenuSection {
.map((m) => ({
...m,
disableCollapsible: true,
itemList: m.itemList.map((item) => ({
itemList: m.itemList?.map((item) => ({
...item,
disableCollapsible: true,
})),
@@ -1,5 +1,8 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"strictNullChecks": true
},
"files": [],
"include": [],
"references": [
+1
View File
@@ -4,6 +4,7 @@
"jsx": "react-jsx",
"allowJs": true,
"esModuleInterop": true,
"strictNullChecks": true,
"allowSyntheticDefaultImports": true
},
"files": [],
@@ -7,6 +7,8 @@ describe('Content', () => {
it('should render successfully', () => {
const { baseElement } = render(
<Content
versionList={[]}
flavorList={[]}
version="1.0.0"
flavor="react"
document={{
@@ -17,7 +17,7 @@ export interface DocumentationFeatureDocViewerProps {
menu: Menu;
document: DocumentData;
toc: any;
navIsOpen: boolean;
navIsOpen?: boolean;
}
export function DocViewer({
@@ -16,7 +16,7 @@ export interface SidebarProps {
versionList: VersionMetadata[];
flavorList: any[];
flavor: any;
navIsOpen: boolean;
navIsOpen?: boolean;
}
// Exported for testing
+1
View File
@@ -4,6 +4,7 @@
"jsx": "react",
"allowJs": true,
"esModuleInterop": true,
"strictNullChecks": true,
"allowSyntheticDefaultImports": true
},
"files": [],
@@ -26,7 +26,7 @@ export function AlgoliaSearch({ flavorId, versionId }: AlgoliaSearchProps) {
const router = useRouter();
const [isOpen, setIsOpen] = useState(false);
const searchButtonRef = useRef();
const searchButtonRef = useRef<HTMLButtonElement>(null);
const [initialQuery, setInitialQuery] = useState(null);
const [browserDetected, setBrowserDetected] = useState(false);
const [actionKey, setActionKey] = useState(ACTION_KEY_DEFAULT);
+1
View File
@@ -4,6 +4,7 @@
"jsx": "react-jsx",
"allowJs": true,
"esModuleInterop": true,
"strictNullChecks": true,
"allowSyntheticDefaultImports": true
},
"files": [],
+1 -1
View File
@@ -5,7 +5,7 @@ const isServer = typeof window === 'undefined';
export function useStorage(key: string) {
const initialValue = isServer ? undefined : window.localStorage.getItem(key);
const [value, _setValue] = useState<string>(initialValue);
const [value, _setValue] = useState<string>(initialValue ?? '');
const setValue = (newValue: string) => {
if (newValue !== value && !isServer) {
+12 -5
View File
@@ -17,8 +17,11 @@ import { documentsApi, menuApi } from '../lib/api';
import { useStorage } from '../lib/use-storage';
const versionList = documentsApi.getVersions();
const defaultVersion = versionList.find((v) => v.default);
const defaultFlavor = flavorList.find((f) => f.default);
const defaultVersion = versionList.find((v) => v.default) as VersionMetadata;
const defaultFlavor = flavorList.find((f) => f.default) as {
value: string;
label: string;
};
interface DocumentationPageProps {
version: VersionMetadata;
@@ -277,12 +280,16 @@ function findDocumentAndMenu(
version: VersionMetadata,
flavor: { label: string; value: string },
segments: string[]
): { menu?: Menu; document?: DocumentData; isFallback?: boolean } {
): {
menu: undefined | Menu;
document: undefined | DocumentData;
isFallback?: boolean;
} {
const isFallback = segments[0] !== version.id;
const path = isFallback ? segments : segments.slice(2);
let menu: Menu;
let document: DocumentData;
let menu: undefined | Menu = undefined;
let document: undefined | DocumentData = undefined;
try {
menu = menuApi.getMenu(version.id, flavor.value);
@@ -76,7 +76,7 @@ builder.addNode({
## Adding New Dependencies to the Project Graph
It's more common for plugins to create new dependencies. First-party code contained in the workspace is registered in `workpspace.json` and is added to the project graph automatically. Whether your project contains TypeScript or say Java, both projects will be created in the same way. However, Nx does not know how to analyze Java sources, and that's what plugins can do.
It's more common for plugins to create new dependencies. First-party code contained in the workspace is registered in `workspace.json` and is added to the project graph automatically. Whether your project contains TypeScript or say Java, both projects will be created in the same way. However, Nx does not know how to analyze Java sources, and that's what plugins can do.
You can create 2 types of dependencies.
+4
View File
@@ -12,6 +12,10 @@
@import './constellation-wobble.animation.css';
/*! purgecss end ignore */
html {
scroll-behavior: smooth;
}
svg {
shape-rendering: auto;
text-rendering: optimizeLegibility;
+2 -1
View File
@@ -9,7 +9,8 @@
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"resolveJsonModule": true,
"isolatedModules": true
"isolatedModules": true,
"strictNullChecks": true
},
"files": [],
"include": [],
+1 -1
View File
@@ -2,7 +2,7 @@ import cx from 'classnames';
import Link from 'next/link';
export interface FooterProps {
useDarkBackground: boolean;
useDarkBackground?: boolean;
}
export function Footer({ useDarkBackground }: FooterProps) {
return (
+2 -2
View File
@@ -4,12 +4,12 @@ import { AlgoliaSearch } from '@nrwl/nx-dev/feature-search';
interface HeaderPropsWithoutFlavorAndVersion {
showSearch: false;
useDarkBackground: boolean;
useDarkBackground?: boolean;
}
interface HeaderPropsWithFlavorAndVersion {
showSearch: boolean;
useDarkBackground: boolean;
useDarkBackground?: boolean;
flavor: { name: string; value: string };
version: { name: string; value: string };
}
+1
View File
@@ -4,6 +4,7 @@
"jsx": "react-jsx",
"allowJs": true,
"esModuleInterop": true,
"strictNullChecks": true,
"allowSyntheticDefaultImports": true
},
"files": [],
+3 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@nrwl/nx-source",
"version": "12.6.0",
"version": "12.6.6",
"description": "Smart, Extensible Build Framework",
"homepage": "https://nx.dev",
"private": true,
@@ -67,7 +67,7 @@
"@nrwl/linter": "12.6.0-beta.10",
"@nrwl/next": "12.6.0-beta.10",
"@nrwl/node": "12.6.0-beta.10",
"@nrwl/nx-cloud": "12.2.7",
"@nrwl/nx-cloud": "12.3.1",
"@nrwl/tao": "12.6.0-beta.10",
"@nrwl/web": "12.6.0-beta.10",
"@nrwl/workspace": "12.6.0-beta.10",
@@ -129,8 +129,7 @@
"cz-conventional-changelog": "^3.0.2",
"cz-customizable": "^6.2.0",
"depcheck": "^1.3.1",
"document-register-element": "^1.13.1",
"dotenv": "8.2.0",
"dotenv": "~10.0.0",
"ejs": "^3.1.5",
"eslint": "7.10.0",
"eslint-config-next": "^11.0.1",
@@ -263,7 +262,6 @@
"@testing-library/react-hooks": "^7.0.0",
"classnames": "^2.3.1",
"core-js": "^3.6.5",
"document-register-element": "^1.13.1",
"glob": "7.1.4",
"gray-matter": "^4.0.2",
"react": "17.0.2",
@@ -13,7 +13,7 @@ import {
} from '@nrwl/workspace/src/utils/buildable-libs-utils';
import { joinPathFragments } from '@nrwl/devkit';
import { join } from 'path';
import { createProjectGraphAsync } from '@nrwl/workspace/src/core/project-graph';
import { readCachedProjectGraph } from '@nrwl/workspace/src/core/project-graph';
import { Schema } from '@angular-devkit/build-angular/src/browser/schema';
import { switchMap } from 'rxjs/operators';
import { existsSync } from 'fs';
@@ -80,32 +80,26 @@ function run(
options: BrowserBuilderSchema,
context: BuilderContext
): Observable<BuilderOutput> {
return from(createProjectGraphAsync()).pipe(
switchMap((projGraph) => {
const { target, dependencies } = calculateProjectDependencies(
projGraph,
context
);
const { target, dependencies } = calculateProjectDependencies(
readCachedProjectGraph(),
context
);
options.tsConfig = createTmpTsConfig(
join(context.workspaceRoot, options.tsConfig),
context.workspaceRoot,
target.data.root,
dependencies
);
options.tsConfig = createTmpTsConfig(
join(context.workspaceRoot, options.tsConfig),
context.workspaceRoot,
target.data.root,
dependencies
);
return of(
checkDependentProjectsHaveBeenBuilt(context, dependencies)
).pipe(
switchMap((result) => {
if (result) {
return buildApp(options, context);
} else {
// just pass on the result
return of({ success: false });
}
})
);
return of(checkDependentProjectsHaveBeenBuilt(context, dependencies)).pipe(
switchMap((result) => {
if (result) {
return buildApp(options, context);
} else {
// just pass on the result
return of({ success: false });
}
})
);
}
@@ -26,7 +26,9 @@ export function webpackServer(schema: Schema, context: BuilderContext) {
const selectedConfiguration = parsedBrowserTarget.configuration
? buildTarget.configurations[parsedBrowserTarget.configuration]
: buildTarget.configurations[buildTarget.defaultConfiguration];
: buildTarget.defaultConfiguration
? buildTarget.configurations[buildTarget.defaultConfiguration]
: buildTarget.options;
const customWebpackConfig: { path: string } =
selectedConfiguration.customWebpackConfig ??
@@ -4,7 +4,7 @@ import {
parseTargetString,
runExecutor,
} from '@nrwl/devkit';
import { createProjectGraphAsync } from '@nrwl/workspace/src/core/project-graph';
import { readCachedProjectGraph } from '@nrwl/workspace/src/core/project-graph';
import {
calculateProjectDependencies,
checkDependentProjectsHaveBeenBuilt,
@@ -16,10 +16,8 @@ export async function* delegateBuildExecutor(
options: DelegateBuildExecutorSchema,
context: ExecutorContext
) {
const projGraph = await createProjectGraphAsync();
const { target, dependencies } = calculateProjectDependencies(
projGraph,
readCachedProjectGraph(),
context.root,
context.projectName,
context.targetName,
@@ -1,6 +1,6 @@
import * as ng from '@angular/compiler-cli';
import type { ExecutorContext } from '@nrwl/devkit';
import { createProjectGraphAsync } from '@nrwl/workspace/src/core/project-graph';
import { readCachedProjectGraph } from '@nrwl/workspace/src/core/project-graph';
import type { DependentBuildableProjectNode } from '@nrwl/workspace/src/utilities/buildable-libs-utils';
import {
calculateProjectDependencies,
@@ -50,9 +50,8 @@ export function createLibraryExecutor(
options: BuildAngularLibraryExecutorOptions,
context: ExecutorContext
) {
const projGraph = await createProjectGraphAsync();
const { target, dependencies } = calculateProjectDependencies(
projGraph,
readCachedProjectGraph(),
context.root,
context.projectName,
context.targetName,
@@ -1,21 +1,19 @@
import type { Tree } from '@nrwl/devkit';
import type { Schema } from './schema';
import * as devkit from '@nrwl/devkit';
import {
readJson,
updateJson,
NxJsonConfiguration,
readProjectConfiguration,
parseJson,
readJson,
readProjectConfiguration,
updateJson,
} from '@nrwl/devkit';
import type { Schema } from './schema';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { Linter } from '@nrwl/linter';
import { E2eTestRunner, UnitTestRunner } from '../../utils/test-runners';
import { applicationGenerator } from './application';
import * as devkit from '@nrwl/devkit';
describe('app', () => {
let appTree: Tree;
@@ -366,6 +364,38 @@ describe('app', () => {
`);
});
it('should add a lint target when e2e test runner is protractor', async () => {
await generateApp(appTree, 'myApp', {
linter: Linter.EsLint,
e2eTestRunner: E2eTestRunner.Protractor,
});
const workspaceJson = readJson(appTree, 'workspace.json');
expect(workspaceJson.projects['my-app'].architect.lint)
.toMatchInlineSnapshot(`
Object {
"builder": "@nrwl/linter:eslint",
"options": Object {
"lintFilePatterns": Array [
"apps/my-app/src/**/*.ts",
"apps/my-app/src/**/*.html",
],
},
}
`);
expect(appTree.exists('apps/my-app-e2e/.eslintrc.json')).toBeTruthy();
expect(workspaceJson.projects['my-app-e2e'].architect.lint)
.toMatchInlineSnapshot(`
Object {
"builder": "@nrwl/linter:eslint",
"options": Object {
"lintFilePatterns": Array [
"apps/my-app-e2e/**/*.ts",
],
},
}
`);
});
it('should add valid eslint JSON configuration which extends from Nx presets', async () => {
await generateApp(appTree, 'myApp', { linter: Linter.EsLint });
@@ -426,6 +456,21 @@ describe('app', () => {
await generateApp(appTree, 'myApp', { linter: Linter.None });
const workspaceJson = readJson(appTree, 'workspace.json');
expect(workspaceJson.projects['my-app'].architect.lint).toBeUndefined();
expect(
workspaceJson.projects['my-app-e2e'].architect.lint
).toBeUndefined();
});
it('should not add an architect target for lint when e2e test runner is protractor', async () => {
await generateApp(appTree, 'myApp', {
linter: Linter.None,
e2eTestRunner: E2eTestRunner.Protractor,
});
const workspaceJson = readJson(appTree, 'workspace.json');
expect(workspaceJson.projects['my-app'].architect.lint).toBeUndefined();
expect(
workspaceJson.projects['my-app-e2e'].architect.lint
).toBeUndefined();
});
});
});
@@ -101,10 +101,7 @@ export async function applicationGenerator(
setApplicationStrictDefault(host, false);
}
if (
options.standaloneConfig ||
getWorkspaceLayout(host).standaloneAsDefault
) {
if (options.standaloneConfig) {
await convertToNxProjectGenerator(host, {
project: options.name,
all: false,
@@ -9,29 +9,31 @@ import { addProtractor } from './add-protractor';
import { removeScaffoldedE2e } from './remove-scaffolded-e2e';
import { updateE2eProject } from './update-e2e-project';
import { convertToNxProjectGenerator } from '@nrwl/workspace';
import { Linter, lintProjectGenerator } from '@nrwl/linter';
import { joinPathFragments } from '@nrwl/devkit';
/**
* Add E2E Config
*
* @param host Nx Devkit Virtual Tree
* @param tree Nx Devkit Virtual Tree
* @param options Normalized Schema
* @param e2eProjectRoot Raw E2E Project Root that Angular tries to write to
*
* @returns Function to run to add Cypres config after intial app files have been moved to correct location
*/
export async function addE2e(
host: Tree,
tree: Tree,
options: NormalizedSchema,
e2eProjectRoot: string
) {
if (options.e2eTestRunner === E2eTestRunner.Protractor) {
await addProtractor(host, options);
await addProtractor(tree, options);
} else {
removeScaffoldedE2e(host, options, e2eProjectRoot);
removeScaffoldedE2e(tree, options, e2eProjectRoot);
}
if (options.e2eTestRunner === 'cypress') {
await cypressProjectGenerator(host, {
await cypressProjectGenerator(tree, {
name: options.e2eProjectName,
directory: options.directory,
project: options.name,
@@ -42,11 +44,21 @@ export async function addE2e(
}
if (options.e2eTestRunner === E2eTestRunner.Protractor) {
updateE2eProject(host, options);
updateE2eProject(tree, options);
if (options.standaloneConfig) {
convertToNxProjectGenerator(host, {
convertToNxProjectGenerator(tree, {
project: `${options.e2eProjectName}`,
});
}
if (options.linter === Linter.EsLint) {
await lintProjectGenerator(tree, {
project: options.e2eProjectName,
linter: options.linter,
eslintFilePatterns: [
joinPathFragments(options.e2eProjectRoot, '**/*.ts'),
],
skipFormat: true,
});
}
}
}
@@ -10,7 +10,7 @@ export function normalizeOptions(
host: Tree,
options: Partial<Schema>
): NormalizedSchema {
const { appsDir, npmScope } = getWorkspaceLayout(host);
const { appsDir, npmScope, standaloneAsDefault } = getWorkspaceLayout(host);
const appDirectory = options.directory
? `${names(options.directory).fileName}/${names(options.name).fileName}`
@@ -31,6 +31,8 @@ export function normalizeOptions(
const defaultPrefix = npmScope;
options.standaloneConfig = options.standaloneConfig || standaloneAsDefault;
// Set defaults and then overwrite with user options
return {
style: 'css',
@@ -1,15 +1,12 @@
import type { ProjectConfiguration, Tree } from '@nrwl/devkit';
import type { NormalizedSchema } from './normalized-schema';
import {
offsetFromRoot,
updateJson,
addProjectConfiguration,
offsetFromRoot,
readProjectConfiguration,
updateJson,
updateProjectConfiguration,
ProjectType,
} from '@nrwl/devkit';
import { Linter } from '@nrwl/linter';
import type { NormalizedSchema } from './normalized-schema';
export function updateE2eProject(tree: Tree, options: NormalizedSchema) {
const spec = `${options.e2eProjectRoot}/src/app.e2e-spec.ts`;
@@ -32,15 +29,6 @@ export function updateE2eProject(tree: Tree, options: NormalizedSchema) {
projectType: 'application',
targets: {
e2e: proj.targets.e2e,
lint:
options.linter === Linter.None
? undefined
: {
executor: '@nrwl/linter:eslint',
options: {
lintFilePatterns: [`${options.e2eProjectRoot}/**/*.ts`],
},
},
},
};
project.targets.e2e.options.protractorConfig = `${options.e2eProjectRoot}/protractor.conf.js`;
+35 -36
View File
@@ -1,36 +1,41 @@
import { cypressInitGenerator } from '@nrwl/cypress';
import type { Tree } from '@nrwl/devkit';
import type { GeneratorCallback, Tree } from '@nrwl/devkit';
import {
addDependenciesToPackageJson,
formatFiles,
readJson,
readWorkspaceConfiguration,
updateJson,
updateWorkspaceConfiguration,
} from '@nrwl/devkit';
import { jestInitGenerator } from '@nrwl/jest';
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
import { setDefaultCollection } from '@nrwl/workspace/src/utilities/set-default-collection';
import { E2eTestRunner, UnitTestRunner } from '../../utils/test-runners';
import {
angularVersion,
angularDevkitVersion,
jestPresetAngularVersion,
rxjsVersion,
} from '../../utils/versions';
import { karmaGenerator } from '../karma/karma';
import { Schema } from './schema';
export default async function (host: Tree, options: Schema) {
export default async function (
host: Tree,
options: Schema
): Promise<GeneratorCallback> {
setDefaults(host, options);
addPostInstall(host);
updateDependencies(host);
addUnitTestRunner(host, options);
addE2ETestRunner(host, options);
const depsTask = updateDependencies(host);
const unitTestTask = addUnitTestRunner(host, options);
const e2eTask = addE2ETestRunner(host, options);
if (!options.skipFormat) {
await formatFiles(host);
}
return runTasksInSerial(depsTask, unitTestTask, e2eTask);
}
function setDefaults(host: Tree, options: Schema) {
@@ -72,7 +77,7 @@ function addPostInstall(host: Tree) {
});
}
function updateDependencies(host: Tree) {
function updateDependencies(host: Tree): GeneratorCallback {
return addDependenciesToPackageJson(
host,
{
@@ -91,7 +96,7 @@ function updateDependencies(host: Tree) {
{
'@angular/compiler-cli': angularVersion,
'@angular/language-service': angularVersion,
'@angular-devkit/build-angular': angularVersion,
'@angular-devkit/build-angular': angularDevkitVersion,
}
);
}
@@ -99,10 +104,10 @@ function updateDependencies(host: Tree) {
function addUnitTestRunner(
host: Tree,
options: Pick<Schema, 'unitTestRunner'>
) {
): GeneratorCallback {
switch (options.unitTestRunner) {
case UnitTestRunner.Karma:
karmaGenerator(host);
return karmaGenerator(host);
case UnitTestRunner.Jest:
addDependenciesToPackageJson(
host,
@@ -111,38 +116,32 @@ function addUnitTestRunner(
'jest-preset-angular': jestPresetAngularVersion,
}
);
const pkgJson = readJson(host, 'package.json');
if (!pkgJson.devDependencies['@nrwl/jest']) {
jestInitGenerator(host, {});
}
return jestInitGenerator(host, {});
default:
return;
return () => {};
}
}
function addE2ETestRunner(host: Tree, options: Pick<Schema, 'e2eTestRunner'>) {
const pkgJson = readJson(host, 'package.json');
function addE2ETestRunner(
host: Tree,
options: Pick<Schema, 'e2eTestRunner'>
): GeneratorCallback {
switch (options.e2eTestRunner) {
case E2eTestRunner.Protractor:
if (!pkgJson.devDependencies['protractor']) {
addDependenciesToPackageJson(
host,
{},
{
protractor: '~7.0.0',
'jasmine-core': '~3.6.0',
'jasmine-spec-reporter': '~5.0.0',
'@types/jasmine': '~3.6.0',
'@types/jasminewd2': '~2.0.3',
}
);
}
return addDependenciesToPackageJson(
host,
{},
{
protractor: '~7.0.0',
'jasmine-core': '~3.6.0',
'jasmine-spec-reporter': '~5.0.0',
'@types/jasmine': '~3.6.0',
'@types/jasminewd2': '~2.0.3',
}
);
case E2eTestRunner.Cypress:
if (!pkgJson.devDependencies['@nrwl/cypress']) {
cypressInitGenerator(host);
}
return cypressInitGenerator(host);
default:
return;
return () => {};
}
}
@@ -13,7 +13,7 @@ export function karmaGenerator(tree: Tree) {
}
generateFiles(tree, joinPathFragments(__dirname, 'files'), '.', { tmpl: '' });
addDependenciesToPackageJson(
return addDependenciesToPackageJson(
tree,
{},
{
@@ -27,7 +27,7 @@ export function normalizeOptions(
? `${names(options.directory).fileName}/${name}`
: name;
const { libsDir, npmScope } = getWorkspaceLayout(host);
const { libsDir, npmScope, standaloneAsDefault } = getWorkspaceLayout(host);
const projectName = projectDirectory.replace(new RegExp('/', 'g'), '-');
const fileName = options.simpleModuleName ? name : projectName;
@@ -40,6 +40,8 @@ export function normalizeOptions(
const modulePath = `${projectRoot}/src/lib/${fileName}.module.ts`;
const defaultPrefix = npmScope;
options.standaloneConfig = options.standaloneConfig || standaloneAsDefault;
const importPath =
options.importPath || `@${defaultPrefix}/${projectDirectory}`;
@@ -69,10 +69,7 @@ export async function libraryGenerator(host: Tree, schema: Partial<Schema>) {
setStrictMode(host, options);
await addLinting(host, options);
if (
options.standaloneConfig ||
getWorkspaceLayout(host).standaloneAsDefault
) {
if (options.standaloneConfig) {
await convertToNxProjectGenerator(host, {
project: options.name,
all: false,
@@ -10,6 +10,30 @@ import { UnitTestRunner } from '../../../utils/test-runners';
describe('updateModuleName Rule', () => {
let tree: Tree;
beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
});
it('should handle nesting resulting in the same project name', async () => {
const updatedModulePath = '/libs/my/first/src/lib/my-first.module.ts';
await libraryGenerator(tree, {
name: 'my-first',
simpleModuleName: true,
});
const schema: Schema = {
projectName: 'my-first',
destination: 'my/first',
updateImportPath: true,
};
await moveGenerator(tree, schema);
updateModuleName(tree, { ...schema, destination: 'my/first' });
expect(tree.exists(updatedModulePath)).toBe(true);
const moduleFile = tree.read(updatedModulePath).toString('utf-8');
expect(moduleFile).toContain(`export class MyFirstModule { }`);
});
describe('move to subfolder', () => {
const updatedModulePath =
'/libs/shared/my-first/src/lib/shared-my-first.module.ts';
@@ -25,8 +49,6 @@ describe('updateModuleName Rule', () => {
};
beforeEach(async () => {
tree = createTreeWithEmptyWorkspace();
await libraryGenerator(tree, {
name: 'my-first',
buildable: false,
@@ -86,7 +108,7 @@ describe('updateModuleName Rule', () => {
});
it('should rename the module files and update the module name', async () => {
await updateModuleName(tree, schema);
updateModuleName(tree, schema);
expect(tree.exists(updatedModulePath)).toBe(true);
expect(tree.exists(updatedModuleSpecPath)).toBe(true);
@@ -108,11 +130,11 @@ describe('updateModuleName Rule', () => {
});
it('should update any references to the module', async () => {
await updateModuleName(tree, schema);
updateModuleName(tree, schema);
const importerFile = tree.read(secondModulePath).toString('utf-8');
expect(importerFile).toContain(
`import { SharedMyFirstModule } from '@proj/shared/my-first';`
`import { SharedMyFirstModule } from '@proj/shared-my-first';`
);
expect(importerFile).toContain(
`export class MySecondModule extends SharedMyFirstModule {}`
@@ -120,7 +142,7 @@ describe('updateModuleName Rule', () => {
});
it('should update the index.ts file which exports the module', async () => {
await updateModuleName(tree, schema);
updateModuleName(tree, schema);
const indexFile = tree.read(indexPath).toString('utf-8');
expect(indexFile).toContain(
@@ -128,6 +150,7 @@ describe('updateModuleName Rule', () => {
);
});
});
describe('rename', () => {
const schema: Schema = {
projectName: 'my-source',
@@ -142,8 +165,6 @@ describe('updateModuleName Rule', () => {
const importerPath = '/libs/my-importer/src/lib/my-importing-file.ts';
beforeEach(async () => {
tree = createTreeWithEmptyWorkspace();
// fake a mid-move tree:
await libraryGenerator(tree, {
name: 'my-destination',
@@ -211,7 +232,7 @@ describe('updateModuleName Rule', () => {
});
it('should rename the module files and update the module name', async () => {
await updateModuleName(tree, schema);
updateModuleName(tree, schema);
expect(tree.exists(modulePath)).toBe(true);
expect(tree.exists(moduleSpecPath)).toBe(true);
@@ -233,7 +254,7 @@ describe('updateModuleName Rule', () => {
});
it('should update any references to the module', async () => {
await updateModuleName(tree, schema);
updateModuleName(tree, schema);
const importerFile = tree.read(importerPath).toString('utf-8');
expect(importerFile).toContain(
@@ -245,7 +266,7 @@ describe('updateModuleName Rule', () => {
});
it('should update the index.ts file which exports the module', async () => {
await updateModuleName(tree, schema);
updateModuleName(tree, schema);
const indexFile = tree.read(indexPath).toString('utf-8');
expect(indexFile).toContain(
@@ -8,6 +8,7 @@ import {
import { getNewProjectName } from '@nrwl/workspace/src/generators/move/lib/utils';
import { join } from 'path';
import { Schema } from '../schema';
/**
* Updates the Angular module name (including the spec file and index.ts)
*
@@ -16,10 +17,10 @@ import { Schema } from '../schema';
*
* @param schema The options provided to the schematic
*/
export async function updateModuleName(
export function updateModuleName(
tree: Tree,
{ projectName, destination }: Schema
) {
): void {
const newProjectName = getNewProjectName(destination);
const project = readProjectConfiguration(tree, newProjectName);
@@ -27,7 +28,7 @@ export async function updateModuleName(
if (project.projectType === 'application') {
// Expect the module to be something like 'app.module.ts' regardless of the folder name,
// Therefore, nothing to do.
return tree;
return;
}
const moduleName = {
@@ -53,7 +54,11 @@ export async function updateModuleName(
from: `${project.sourceRoot}/lib/${moduleFile.from}.spec.ts`,
to: `${project.sourceRoot}/lib/${moduleFile.to}.spec.ts`,
},
];
].filter((rename) => rename.from !== rename.to);
if (filesToRename.length === 0) {
return;
}
const replacements = [
{
@@ -84,8 +89,7 @@ export async function updateModuleName(
const skipFiles = [...filesToRename.map((file) => file.to), indexFile];
// Update any files which import the module
for (const [name, definition] of getProjects(tree)) {
for (const [, definition] of getProjects(tree)) {
visitNotIgnoredFiles(tree, definition.root, (file) => {
// skip files that were already modified
@@ -97,6 +101,7 @@ export async function updateModuleName(
});
}
}
function updateFileContent(
tree: Tree,
replacements: { regex: RegExp; replaceWith: string }[],
@@ -1,4 +1,5 @@
import { Tree } from '@nrwl/devkit';
import * as devkit from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { angularMoveGenerator } from './move';
import libraryGenerator from '../library/library';
@@ -21,6 +22,8 @@ describe('@nrwl/angular:move', () => {
skipFormat: false,
unitTestRunner: UnitTestRunner.Jest,
});
jest.clearAllMocks();
});
it('should move a project', async () => {
@@ -34,4 +37,29 @@ describe('@nrwl/angular:move', () => {
true
);
});
it('should format files', async () => {
jest.spyOn(devkit, 'formatFiles');
await angularMoveGenerator(tree, {
projectName: 'mylib',
destination: 'mynewlib',
updateImportPath: true,
});
expect(devkit.formatFiles).toHaveBeenCalled();
});
it('should not format files when --skipFormat=true', async () => {
jest.spyOn(devkit, 'formatFiles');
await angularMoveGenerator(tree, {
projectName: 'mylib',
destination: 'mynewlib',
updateImportPath: true,
skipFormat: true,
});
expect(devkit.formatFiles).not.toHaveBeenCalled();
});
});
+10 -4
View File
@@ -1,4 +1,4 @@
import { convertNxGenerator, Tree } from '@nrwl/devkit';
import { convertNxGenerator, formatFiles, Tree } from '@nrwl/devkit';
import { moveGenerator } from '@nrwl/workspace';
import { updateModuleName } from './lib/update-module-name';
import { Schema } from './schema';
@@ -10,10 +10,16 @@ import { Schema } from './schema';
* to the workspace, so it can't use the same tricks as the `@nrwl/workspace` rules
* to get the before and after names and paths.
*/
export async function angularMoveGenerator(
tree: Tree,
schema: Schema
): Promise<void> {
await moveGenerator(tree, { ...schema, skipFormat: true });
updateModuleName(tree, schema);
export async function angularMoveGenerator(tree: Tree, schema: Schema) {
await moveGenerator(tree, schema);
await updateModuleName(tree, schema);
if (!schema.skipFormat) {
await formatFiles(tree);
}
}
export const angularMoveSchematic = convertNxGenerator(angularMoveGenerator);
+2 -1
View File
@@ -1,6 +1,7 @@
export interface Schema {
projectName: string;
destination: string;
importPath?: string;
updateImportPath: boolean;
importPath?: string;
skipFormat?: boolean;
}
@@ -33,6 +33,12 @@
"type": "boolean",
"description": "Update the import path to reflect the new location.",
"default": true
},
"skipFormat": {
"type": "boolean",
"aliases": ["skip-format"],
"description": "Skip formatting files.",
"default": false
}
},
"required": ["projectName", "destination"]
@@ -11,7 +11,10 @@ import {
} from '@nrwl/workspace';
import { join } from 'path';
import { offsetFromRoot } from '@nrwl/devkit';
import { createProjectGraphAsync } from '@nrwl/workspace/src/core/project-graph';
import {
createProjectGraphAsync,
isNpmProject,
} from '@nrwl/workspace/src/core/project-graph';
/**
* It was decided with Jason that we would do a simple replacement in this migration
@@ -67,7 +70,7 @@ async function updateProjectESLintConfigsAndBuilders(
!graph.dependencies[projectName].some(
(dependency) =>
dependency.target.startsWith('npm:@angular/') &&
graph.nodes[dependency.target].type === 'npm'
isNpmProject(graph.nodes[dependency.target])
)
) {
return;
+1
View File
@@ -1,5 +1,6 @@
export const nxVersion = '*';
export const angularVersion = '^12.1.0';
export const angularDevkitVersion = '~12.1.0';
export const angularJsVersion = '1.7.9';
export const ngrxVersion = '~12.2.0';
export const rxjsVersion = '~6.6.0';
@@ -1,4 +1,4 @@
import { Observable } from 'rxjs';
import type { Observable } from 'rxjs';
import { first, toArray } from 'rxjs/operators';
/**
@@ -143,12 +143,17 @@ if (parsedArgs.help) {
nxCloud,
});
let nxCloudInstallRes;
if (nxCloud) {
await setupNxCloud(name, packageManager);
nxCloudInstallRes = await setupNxCloud(name, packageManager);
}
showNxWarning(name);
pointToTutorialAndCourse(preset);
if (nxCloud && nxCloudInstallRes.code === 0) {
printNxCloudSuccessMessage(nxCloudInstallRes.stdout);
}
})().catch((error) => {
const { version } = require('../package.json');
output.error({
@@ -510,11 +515,12 @@ async function setupNxCloud(name: string, packageManager: PackageManager) {
const nxCloudSpinner = ora(`Setting up NxCloud`).start();
try {
const pmc = getPackageManagerCommand(packageManager);
await execAndWait(
const res = await execAndWait(
`${pmc.exec} nx g @nrwl/nx-cloud:init --no-analytics`,
path.join(process.cwd(), name)
);
nxCloudSpinner.succeed('NxCloud has been set up successfully');
return res;
} catch (e) {
nxCloudSpinner.fail();
@@ -529,6 +535,14 @@ async function setupNxCloud(name: string, packageManager: PackageManager) {
}
}
function printNxCloudSuccessMessage(nxCloudOut: string) {
const bodyLines = nxCloudOut.split('Nx Cloud has been enabled')[1].trim();
output.note({
title: `Nx Cloud has been enabled`,
bodyLines: bodyLines.split('\n').map((r) => r.trim()),
});
}
function execAndWait(command: string, cwd: string) {
return new Promise((res, rej) => {
exec(command, { cwd }, (error, stdout, stderr) => {
@@ -537,7 +551,7 @@ function execAndWait(command: string, cwd: string) {
writeFileSync(logFile, `${stdout}\n${stderr}`);
rej({ code: error.code, logFile });
} else {
res(null);
res({ code: 0, stdout });
}
});
});
@@ -1,3 +1,4 @@
import 'dotenv/config';
import { basename, dirname, join } from 'path';
import { installedCypressVersion } from '../../utils/cypress-version';
import {
@@ -37,10 +38,6 @@ export interface CypressExecutorOptions extends Json {
testingType?: 'component' | 'e2e';
}
try {
require('dotenv').config();
} catch (e) {}
export default async function cypressExecutor(
options: CypressExecutorOptions,
context: ExecutorContext
+1
View File
@@ -41,6 +41,7 @@ export {
readWorkspaceConfiguration,
updateWorkspaceConfiguration,
getProjects,
isStandaloneProject,
} from './src/generators/project-configuration';
export { toJS } from './src/generators/to-js';
export { updateTsConfigsToJs } from './src/generators/update-ts-configs-to-js';
+26 -24
View File
@@ -8,32 +8,34 @@ import { sortObjectByKeys } from '@nrwl/tao/src/utils/object-sort';
/**
* Formats all the created or updated files using Prettier
* @param host - the file system tree
* @param tree - the file system tree
*/
export async function formatFiles(host: Tree): Promise<void> {
export async function formatFiles(tree: Tree): Promise<void> {
let prettier: typeof Prettier;
try {
prettier = await import('prettier');
} catch {}
updateWorkspaceJsonToMatchFormatVersion(host);
sortWorkspaceJson(host);
sortNxJson(host);
sortTsConfig(host);
updateWorkspaceJsonToMatchFormatVersion(tree);
sortWorkspaceJson(tree);
sortNxJson(tree);
sortTsConfig(tree);
if (!prettier) return;
const files = new Set(
host.listChanges().filter((file) => file.type !== 'DELETE')
tree.listChanges().filter((file) => file.type !== 'DELETE')
);
await Promise.all(
Array.from(files).map(async (file) => {
const systemPath = path.join(host.root, file.path);
const systemPath = path.join(tree.root, file.path);
let options: Prettier.Options = {
filepath: systemPath,
};
const resolvedOptions = await prettier.resolveConfig(systemPath);
const resolvedOptions = await prettier.resolveConfig(systemPath, {
editorconfig: true,
});
if (!resolvedOptions) {
return;
}
@@ -48,7 +50,7 @@ export async function formatFiles(host: Tree): Promise<void> {
}
try {
host.write(
tree.write(
file.path,
prettier.format(file.content.toString('utf-8'), options)
);
@@ -59,17 +61,17 @@ export async function formatFiles(host: Tree): Promise<void> {
);
}
function updateWorkspaceJsonToMatchFormatVersion(host: Tree) {
const path = getWorkspacePath(host);
function updateWorkspaceJsonToMatchFormatVersion(tree: Tree) {
const path = getWorkspacePath(tree);
if (!path) {
return;
}
try {
const workspaceJson = readJson(host, path);
const workspaceJson = readJson(tree, path);
const reformatted = reformattedWorkspaceJsonOrNull(workspaceJson);
if (reformatted) {
writeJson(host, path, reformatted);
writeJson(tree, path, reformatted);
}
} catch (e) {
console.error(`Failed to format: ${path}`);
@@ -77,17 +79,17 @@ function updateWorkspaceJsonToMatchFormatVersion(host: Tree) {
}
}
function sortWorkspaceJson(host: Tree) {
const workspaceJsonPath = getWorkspacePath(host);
function sortWorkspaceJson(tree: Tree) {
const workspaceJsonPath = getWorkspacePath(tree);
if (!path) {
return;
}
try {
const workspaceJson = readJson(host, workspaceJsonPath);
const workspaceJson = readJson(tree, workspaceJsonPath);
if (Object.entries(workspaceJson.projects).length !== 0) {
const sortedProjects = sortObjectByKeys(workspaceJson.projects);
writeJson(host, workspaceJsonPath, {
writeJson(tree, workspaceJsonPath, {
...workspaceJson,
projects: sortedProjects,
});
@@ -97,11 +99,11 @@ function sortWorkspaceJson(host: Tree) {
}
}
function sortNxJson(host: Tree) {
function sortNxJson(tree: Tree) {
try {
const nxJson = readJson(host, 'nx.json');
const nxJson = readJson(tree, 'nx.json');
const sortedProjects = sortObjectByKeys(nxJson.projects);
writeJson(host, 'nx.json', {
writeJson(tree, 'nx.json', {
...nxJson,
projects: sortedProjects,
});
@@ -110,11 +112,11 @@ function sortNxJson(host: Tree) {
}
}
function sortTsConfig(host: Tree) {
function sortTsConfig(tree: Tree) {
try {
const tsconfig = readJson(host, 'tsconfig.base.json');
const tsconfig = readJson(tree, 'tsconfig.base.json');
const sortedPaths = sortObjectByKeys(tsconfig.compilerOptions.paths);
writeJson(host, 'tsconfig.base.json', {
writeJson(tree, 'tsconfig.base.json', {
...tsconfig,
compilerOptions: {
...tsconfig.compilerOptions,
@@ -27,6 +27,13 @@ const binaryExts = new Set([
// Java files
'.jar',
'.keystore',
// Font files
'.ttf',
'.otf',
'.woff',
'.woff2',
'.eot',
]);
/**
@@ -38,7 +45,7 @@ const binaryExts = new Set([
*
* Examples:
* ```typescript
* generateFiles(host, path.join(__dirname , 'files'), './tools/scripts', {tmpl: '', name: 'myscript'})
* generateFiles(tree, path.join(__dirname , 'files'), './tools/scripts', {tmpl: '', name: 'myscript'})
* ```
* This command will take all the files from the `files` directory next to the place where the command is invoked from.
* It will replace all `__tmpl__` with '' and all `__name__` with 'myscript' in the file names, and will replace all
@@ -46,13 +53,13 @@ const binaryExts = new Set([
* `tmpl: ''` is a common pattern. With it you can name files like this: `index.ts__tmpl__`, so your editor
* doesn't get confused about incorrect TypeScript files.
*
* @param host - the file system tree
* @param tree - the file system tree
* @param srcFolder - the source folder of files (absolute path)
* @param target - the target folder (relative to the host root)
* @param target - the target folder (relative to the tree root)
* @param substitutions - an object of key-value pairs
*/
export function generateFiles(
host: Tree,
tree: Tree,
srcFolder: string,
target: string,
substitutions: { [k: string]: any }
@@ -74,12 +81,12 @@ export function generateFiles(
try {
newContent = ejs.render(template, substitutions, {});
} catch (e) {
logger.error(`Error in ${filePath.replace(`${host.root}/`, '')}:`);
logger.error(`Error in ${filePath.replace(`${tree.root}/`, '')}:`);
throw e;
}
}
host.write(computedPath, newContent);
tree.write(computedPath, newContent);
});
}
@@ -1,17 +1,18 @@
import { Tree } from '@nrwl/tao/src/shared/tree';
import {
readProjectConfiguration,
addProjectConfiguration,
updateProjectConfiguration,
removeProjectConfiguration,
getProjects,
readWorkspaceConfiguration,
WorkspaceConfiguration,
updateWorkspaceConfiguration,
} from './project-configuration';
import { createTreeWithEmptyWorkspace } from '../tests/create-tree-with-empty-workspace';
import { ProjectConfiguration } from '@nrwl/tao/src/shared/workspace';
import { createTreeWithEmptyWorkspace } from '../tests/create-tree-with-empty-workspace';
import { readJson } from '../utils/json';
import {
addProjectConfiguration,
getProjects,
readProjectConfiguration,
readWorkspaceConfiguration,
removeProjectConfiguration,
updateProjectConfiguration,
updateWorkspaceConfiguration,
WorkspaceConfiguration,
} from './project-configuration';
const baseTestProjectConfig: ProjectConfiguration = {
root: 'libs/test',
@@ -171,4 +172,140 @@ describe('project configuration', () => {
expect(readJson(tree, 'nx.json').$schema).not.toBeDefined();
});
});
describe('without nx.json', () => {
beforeEach(() => tree.delete('nx.json'));
afterEach(() => expect(tree.exists('nx.json')).toEqual(false));
it('should create project.json file when adding a project if standalone is true', () => {
addProjectConfiguration(tree, 'test', baseTestProjectConfig, true);
expect(tree.exists('libs/test/project.json')).toBeTruthy();
});
it('should create project.json file if all other apps in the workspace use project.json', () => {
addProjectConfiguration(
tree,
'project-a',
{
root: 'apps/project-a',
targets: {},
},
true
);
addProjectConfiguration(
tree,
'project-b',
{
root: 'apps/project-b',
targets: {},
},
true
);
expect(tree.exists('apps/project-b/project.json')).toBeTruthy();
});
it("should not create project.json file if any other app in the workspace doesn't use project.json", () => {
addProjectConfiguration(
tree,
'project-a',
{
root: 'apps/project-a',
targets: {},
},
false
);
addProjectConfiguration(
tree,
'project-b',
{
root: 'apps/project-b',
targets: {},
},
false
);
expect(tree.exists('apps/project-a/project.json')).toBeFalsy();
expect(tree.exists('apps/project-b/project.json')).toBeFalsy();
});
it('should not create project.json file when adding a project if standalone is false', () => {
addProjectConfiguration(tree, 'test', baseTestProjectConfig, false);
expect(tree.exists('libs/test/project.json')).toBeFalsy();
});
it('should be able to read from standalone projects', () => {
tree.write(
'workspace.json',
JSON.stringify(
{
projects: {
test: {
root: '/libs/test',
},
},
},
null,
2
)
);
const projectConfig = readProjectConfiguration(tree, 'test');
expect(projectConfig).toEqual({
root: '/libs/test',
});
});
it('should update project.json file when updating a project', () => {
addProjectConfiguration(tree, 'test', baseTestProjectConfig, true);
const expectedProjectConfig = {
...baseTestProjectConfig,
targets: { build: { executor: '' } },
};
updateProjectConfiguration(tree, 'test', expectedProjectConfig);
expect(readJson(tree, 'libs/test/project.json')).toEqual(
expectedProjectConfig
);
});
it('should update workspace.json file when updating an inline project', () => {
addProjectConfiguration(tree, 'test', baseTestProjectConfig, false);
const expectedProjectConfig = {
...baseTestProjectConfig,
targets: { build: { executor: '' } },
};
updateProjectConfiguration(tree, 'test', expectedProjectConfig);
expect(readJson(tree, 'workspace.json').projects.test).toEqual(
expectedProjectConfig
);
});
it('should remove project.json file when removing project configuration', () => {
addProjectConfiguration(tree, 'test', baseTestProjectConfig, true);
removeProjectConfiguration(tree, 'test');
expect(tree.exists('test/project.json')).toBeFalsy();
});
it('should remove project configuration', () => {
addProjectConfiguration(tree, 'test', baseTestProjectConfig, false);
removeProjectConfiguration(tree, 'test');
expect(readJson(tree, 'workspace.json').projects.test).toBeUndefined();
});
it('should support workspaces with standalone and inline projects', () => {
addProjectConfiguration(tree, 'test', baseTestProjectConfig, true);
addProjectConfiguration(tree, 'test2', baseTestProjectConfig, false);
const configurations = getProjects(tree);
expect(configurations.get('test')).toEqual(baseTestProjectConfig);
expect(configurations.get('test2')).toEqual(baseTestProjectConfig);
});
});
});
@@ -1,26 +1,28 @@
import type { Tree } from '@nrwl/tao/src/shared/tree';
import {
ProjectConfiguration,
RawWorkspaceJsonConfiguration,
toNewFormat,
WorkspaceJsonConfiguration,
} from '@nrwl/tao/src/shared/workspace';
import { readJson, updateJson, writeJson } from '../utils/json';
import type {
NxJsonConfiguration,
NxJsonProjectConfiguration,
} from '@nrwl/tao/src/shared/nx';
import {
getWorkspaceLayout,
getWorkspacePath,
} from '../utils/get-workspace-layout';
import { readJson, updateJson, writeJson } from '../utils/json';
import { joinPathFragments } from '../utils/path';
import type { Tree } from '@nrwl/tao/src/shared/tree';
import type {
NxJsonConfiguration,
NxJsonProjectConfiguration,
} from '@nrwl/tao/src/shared/nx';
export type WorkspaceConfiguration = Omit<
WorkspaceJsonConfiguration,
'projects'
> &
Omit<NxJsonConfiguration, 'projects'>;
Partial<Omit<NxJsonConfiguration, 'projects'>>;
/**
* Adds project configuration to the Nx workspace.
@@ -28,20 +30,20 @@ export type WorkspaceConfiguration = Omit<
* The project configuration is stored in workspace.json and nx.json. The utility will update
* both files.
*
* @param host - the file system tree
* @param tree - the file system tree
* @param projectName - unique name. Often directories are part of the name (e.g., mydir-mylib)
* @param projectConfiguration - project configuration
* @param standalone - should the project use package.json? If false, the project config is inside workspace.json
*/
export function addProjectConfiguration(
host: Tree,
tree: Tree,
projectName: string,
projectConfiguration: ProjectConfiguration & NxJsonProjectConfiguration,
standalone: boolean = false
): void {
standalone = standalone || getWorkspaceLayout(host).standaloneAsDefault;
standalone = standalone || getWorkspaceLayout(tree).standaloneAsDefault;
setProjectConfiguration(
host,
tree,
projectName,
projectConfiguration,
'create',
@@ -55,16 +57,16 @@ export function addProjectConfiguration(
* The project configuration is stored in workspace.json and nx.json. The utility will update
* both files.
*
* @param host - the file system tree
* @param tree - the file system tree
* @param projectName - unique name. Often directories are part of the name (e.g., mydir-mylib)
* @param projectConfiguration - project configuration
*/
export function updateProjectConfiguration(
host: Tree,
tree: Tree,
projectName: string,
projectConfiguration: ProjectConfiguration & NxJsonProjectConfiguration
): void {
setProjectConfiguration(host, projectName, projectConfiguration, 'update');
setProjectConfiguration(tree, projectName, projectConfiguration, 'update');
}
/**
@@ -74,10 +76,10 @@ export function updateProjectConfiguration(
* The utility will update both files.
*/
export function removeProjectConfiguration(
host: Tree,
tree: Tree,
projectName: string
): void {
setProjectConfiguration(host, projectName, undefined, 'delete');
setProjectConfiguration(tree, projectName, undefined, 'delete');
}
/**
@@ -86,16 +88,16 @@ export function removeProjectConfiguration(
* Use {@link readProjectConfiguration} if only one project is needed.
*/
export function getProjects(
host: Tree
tree: Tree
): Map<string, ProjectConfiguration & NxJsonProjectConfiguration> {
const workspace = readWorkspace(host);
const nxJson = readJson<NxJsonConfiguration>(host, 'nx.json');
const workspace = readWorkspace(tree);
const nxJson = readNxJson(tree);
return new Map(
Object.keys(workspace.projects || {}).map((projectName) => {
return [
projectName,
getProjectConfiguration(host, projectName, workspace, nxJson),
getProjectConfiguration(projectName, workspace, nxJson),
];
})
);
@@ -106,14 +108,18 @@ export function getProjects(
*
* This does _not_ provide projects configuration, use {@link readProjectConfiguration} instead.
*/
export function readWorkspaceConfiguration(host: Tree): WorkspaceConfiguration {
const workspace = readWorkspace(host);
export function readWorkspaceConfiguration(tree: Tree): WorkspaceConfiguration {
const workspace = readWorkspace(tree);
delete workspace.projects;
const nxJson = readJson<NxJsonConfiguration>(host, 'nx.json');
delete nxJson.projects;
const nxJson = readNxJson(tree);
if (nxJson !== null) {
delete nxJson.projects;
}
return {
...workspace,
...nxJson,
...(nxJson === null ? {} : nxJson),
};
}
@@ -123,7 +129,7 @@ export function readWorkspaceConfiguration(host: Tree): WorkspaceConfiguration {
* This does _not_ update projects configuration, use {@link updateProjectConfiguration} or {@link addProjectConfiguration} instead.
*/
export function updateWorkspaceConfiguration(
host: Tree,
tree: Tree,
workspaceConfig: WorkspaceConfiguration
): void {
const {
@@ -159,15 +165,18 @@ export function updateWorkspaceConfiguration(
};
updateJson<WorkspaceJsonConfiguration>(
host,
getWorkspacePath(host),
tree,
getWorkspacePath(tree),
(json) => {
return { ...json, ...workspace };
}
);
updateJson<NxJsonConfiguration>(host, 'nx.json', (json) => {
return { ...json, ...nxJson };
});
if (tree.exists('nx.json')) {
updateJson<NxJsonConfiguration>(tree, 'nx.json', (json) => {
return { ...json, ...nxJson };
});
}
}
/**
@@ -176,54 +185,67 @@ export function updateWorkspaceConfiguration(
* The project configuration is stored in workspace.json and nx.json. The utility will read
* both files.
*
* @param host - the file system tree
* @param tree - the file system tree
* @param projectName - unique name. Often directories are part of the name (e.g., mydir-mylib)
* @throws If supplied projectName cannot be found
*/
export function readProjectConfiguration(
host: Tree,
tree: Tree,
projectName: string
): ProjectConfiguration & NxJsonProjectConfiguration {
const workspace = readWorkspace(host);
const workspace = readWorkspace(tree);
if (!workspace.projects[projectName]) {
throw new Error(
`Cannot find configuration for '${projectName}' in ${getWorkspacePath(
host
tree
)}.`
);
}
const nxJson = readJson<NxJsonConfiguration>(host, 'nx.json');
const nxJson = readNxJson(tree);
// TODO: Remove after confirming that nx.json should be optional.
// if (!nxJson.projects[projectName]) {
// throw new Error(
// `Cannot find configuration for '${projectName}' in nx.json`
// );
// }
return getProjectConfiguration(projectName, workspace, nxJson);
}
return getProjectConfiguration(host, projectName, workspace, nxJson);
export function readNxJson(tree: Tree): NxJsonConfiguration | null {
if (!tree.exists('nx.json')) {
return null;
}
return readJson<NxJsonConfiguration>(tree, 'nx.json');
}
/**
* Returns if a project has a standalone configuration (project.json).
*
* @param tree - the file system tree
* @param project - the project name
*/
export function isStandaloneProject(tree: Tree, project: string): boolean {
const rawWorkspace = readJson<RawWorkspaceJsonConfiguration>(
tree,
getWorkspacePath(tree)
);
const projectConfig = rawWorkspace.projects?.[project];
return typeof projectConfig === 'string';
}
function getProjectConfiguration(
host: Tree,
projectName: string,
workspace: WorkspaceJsonConfiguration,
nxJson: NxJsonConfiguration
nxJson: NxJsonConfiguration | null
): ProjectConfiguration & NxJsonProjectConfiguration {
return {
...readWorkspaceSection(host, workspace, projectName),
...readNxJsonSection(nxJson, projectName),
...readWorkspaceSection(workspace, projectName),
...(nxJson === null ? {} : readNxJsonSection(nxJson, projectName)),
};
}
function readWorkspaceSection(
host: Tree,
workspace: WorkspaceJsonConfiguration,
projectName: string
) {
const config = workspace.projects[projectName];
return config;
return workspace.projects[projectName];
}
function readNxJsonSection(nxJson: NxJsonConfiguration, projectName: string) {
@@ -231,15 +253,19 @@ function readNxJsonSection(nxJson: NxJsonConfiguration, projectName: string) {
}
function setProjectConfiguration(
host: Tree,
tree: Tree,
projectName: string,
projectConfiguration: ProjectConfiguration & NxJsonProjectConfiguration,
mode: 'create' | 'update' | 'delete',
standalone: boolean = false
) {
): void {
const hasNxJson = tree.exists('nx.json');
if (mode === 'delete') {
addProjectToNxJson(host, projectName, undefined, mode);
addProjectToWorkspaceJson(host, projectName, undefined, mode);
if (hasNxJson) {
addProjectToNxJson(tree, projectName, undefined, mode);
}
addProjectToWorkspaceJson(tree, projectName, undefined, mode);
return;
}
@@ -249,48 +275,51 @@ function setProjectConfiguration(
);
}
const { tags, implicitDependencies } = projectConfiguration;
addProjectToWorkspaceJson(
host,
tree,
projectName,
projectConfiguration,
mode,
standalone
);
addProjectToNxJson(
host,
projectName,
{
tags,
implicitDependencies,
},
mode
);
if (hasNxJson) {
const { tags, implicitDependencies } = projectConfiguration;
addProjectToNxJson(
tree,
projectName,
{
tags,
implicitDependencies,
},
mode
);
}
}
function addProjectToWorkspaceJson(
host: Tree,
tree: Tree,
projectName: string,
project: ProjectConfiguration & NxJsonProjectConfiguration,
mode: 'create' | 'update' | 'delete',
standalone: boolean = false
) {
const path = getWorkspacePath(host);
const workspaceJson = readJson<RawWorkspaceJsonConfiguration>(host, path);
const path = getWorkspacePath(tree);
const workspaceJson = readJson<RawWorkspaceJsonConfiguration>(tree, path);
validateWorkspaceJsonOperations(mode, workspaceJson, projectName);
const configFile =
mode === 'create' && standalone
? joinPathFragments(project.root, 'project.json')
: getProjectFileLocation(host, projectName);
: getProjectFileLocation(tree, projectName);
if (configFile) {
if (mode === 'delete') {
host.delete(configFile);
tree.delete(configFile);
delete workspaceJson.projects[projectName];
} else {
writeJson(host, configFile, project);
writeJson(tree, configFile, project);
}
if (mode === 'create') {
workspaceJson.projects[projectName] = project.root;
@@ -303,19 +332,19 @@ function addProjectToWorkspaceJson(
}
workspaceJson.projects[projectName] = workspaceConfiguration;
}
writeJson(host, path, workspaceJson);
writeJson(tree, path, workspaceJson);
}
function addProjectToNxJson(
host: Tree,
tree: Tree,
projectName: string,
config: NxJsonProjectConfiguration,
mode: 'create' | 'update' | 'delete'
) {
// distributed project files do not use nx.json,
// so only proceed if the project does not use them.
if (!getProjectFileLocation(host, projectName)) {
const nxJson = readJson<NxJsonConfiguration>(host, 'nx.json');
if (!getProjectFileLocation(tree, projectName)) {
const nxJson = readJson<NxJsonConfiguration>(tree, 'nx.json');
if (mode === 'delete') {
delete nxJson.projects[projectName];
} else {
@@ -326,12 +355,12 @@ function addProjectToNxJson(
...(config || {}),
};
}
writeJson(host, 'nx.json', nxJson);
writeJson(tree, 'nx.json', nxJson);
}
}
function readWorkspace(host: Tree): WorkspaceJsonConfiguration {
const workspaceJson = inlineProjectConfigurationsWithTree(host);
function readWorkspace(tree: Tree): WorkspaceJsonConfiguration {
const workspaceJson = inlineProjectConfigurationsWithTree(tree);
const originalVersion = workspaceJson.version;
return {
...toNewFormat(workspaceJson),
@@ -346,16 +375,16 @@ function readWorkspace(host: Tree): WorkspaceJsonConfiguration {
* @returns
*/
function inlineProjectConfigurationsWithTree(
host: Tree
tree: Tree
): WorkspaceJsonConfiguration {
const path = getWorkspacePath(host);
const workspaceJson = readJson<RawWorkspaceJsonConfiguration>(host, path);
const path = getWorkspacePath(tree);
const workspaceJson = readJson<RawWorkspaceJsonConfiguration>(tree, path);
Object.entries(workspaceJson.projects || {}).forEach(([project, config]) => {
if (typeof config === 'string') {
const configFileLocation = joinPathFragments(config, 'project.json');
workspaceJson.projects[project] = readJson<
ProjectConfiguration & NxJsonProjectConfiguration
>(host, configFileLocation);
>(tree, configFileLocation);
}
});
return workspaceJson as WorkspaceJsonConfiguration;
@@ -365,10 +394,10 @@ function inlineProjectConfigurationsWithTree(
* @description Determine where a project's configuration is located.
* @returns file path if separate from root config, null otherwise.
*/
function getProjectFileLocation(host: Tree, project: string): string | null {
function getProjectFileLocation(tree: Tree, project: string): string | null {
const rawWorkspace = readJson<RawWorkspaceJsonConfiguration>(
host,
getWorkspacePath(host)
tree,
getWorkspacePath(tree)
);
const projectConfig = rawWorkspace.projects?.[project];
return typeof projectConfig === 'string'
@@ -2,7 +2,7 @@ import type { Tree } from '@nrwl/tao/src/shared/tree';
import { updateJson } from '../utils/json';
export function updateTsConfigsToJs(
host: Tree,
tree: Tree,
options: { projectRoot: string }
): void {
let updateConfigPath: string;
@@ -26,7 +26,7 @@ export function updateTsConfigsToJs(
);
};
updateJson(host, paths.tsConfig, (json) => {
updateJson(tree, paths.tsConfig, (json) => {
if (json.compilerOptions) {
json.compilerOptions.allowJs = true;
} else {
@@ -35,7 +35,7 @@ export function updateTsConfigsToJs(
return json;
});
const projectType = getProjectType(host);
const projectType = getProjectType(tree);
if (projectType === 'library') {
updateConfigPath = paths.tsConfigLib;
@@ -44,7 +44,7 @@ export function updateTsConfigsToJs(
updateConfigPath = paths.tsConfigApp;
}
updateJson(host, updateConfigPath, (json) => {
updateJson(tree, updateConfigPath, (json) => {
json.include = uniq([...json.include, '**/*.js']);
json.exclude = uniq([...json.exclude, '**/*.spec.js']);
@@ -14,21 +14,21 @@ let storedPackageJsonValue: string;
* Runs `npm install` or `yarn install`. It will skip running the install if
* `package.json` hasn't changed at all or it hasn't changed since the last invocation.
*
* @param host - the file system tree
* @param tree - the file system tree
* @param alwaysRun - always run the command even if `package.json` hasn't changed.
*/
export function installPackagesTask(
host: Tree,
tree: Tree,
alwaysRun: boolean = false,
cwd: string = '',
packageManager: PackageManager = detectPackageManager(cwd)
): void {
const packageJsonValue = host.read(
const packageJsonValue = tree.read(
joinPathFragments(cwd, 'package.json'),
'utf-8'
);
if (
host
tree
.listChanges()
.find((f) => f.path === joinPathFragments(cwd, 'package.json')) ||
alwaysRun
@@ -38,7 +38,7 @@ export function installPackagesTask(
storedPackageJsonValue = packageJsonValue;
const pmc = getPackageManagerCommand(packageManager);
execSync(pmc.install, {
cwd: join(host.root, cwd),
cwd: join(tree.root, cwd),
stdio: [0, 1, 2],
});
}

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