feat(nx): implement next support
This commit is contained in:
parent
c3f2132436
commit
09a94b8958
33
docs/angular/api-express/schematics/init.md
Normal file
33
docs/angular/api-express/schematics/init.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# init
|
||||||
|
|
||||||
|
Initialize the @nrwl/express plugin
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ng generate init ...
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `init` in the default collection provisioned in `angular.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ng g @nrwl/express:init ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ng g init ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### skipFormat
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Skip formatting files
|
||||||
5
docs/angular/api-next/builders/build.md
Normal file
5
docs/angular/api-next/builders/build.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# build
|
||||||
|
|
||||||
|
Build a Next.js app
|
||||||
|
|
||||||
|
Builder properties can be configured in angular.json when defining the builder, or when invoking it.
|
||||||
45
docs/angular/api-next/builders/dev-server.md
Normal file
45
docs/angular/api-next/builders/dev-server.md
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# dev-server
|
||||||
|
|
||||||
|
Serve a Next.js app
|
||||||
|
|
||||||
|
Builder properties can be configured in angular.json when defining the builder, or when invoking it.
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
### buildTarget
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Target which builds the application
|
||||||
|
|
||||||
|
### dev
|
||||||
|
|
||||||
|
Default: `true`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Serve the application in the dev mode
|
||||||
|
|
||||||
|
### port
|
||||||
|
|
||||||
|
Default: `4200`
|
||||||
|
|
||||||
|
Type: `number`
|
||||||
|
|
||||||
|
Port to listen on.
|
||||||
|
|
||||||
|
### quiet
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Hide error messages containing server information.
|
||||||
|
|
||||||
|
### staticMarkup
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Static markup.
|
||||||
5
docs/angular/api-next/builders/export.md
Normal file
5
docs/angular/api-next/builders/export.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# export
|
||||||
|
|
||||||
|
Export a Next.js app
|
||||||
|
|
||||||
|
Builder properties can be configured in angular.json when defining the builder, or when invoking it.
|
||||||
143
docs/angular/api-next/schematics/application.md
Normal file
143
docs/angular/api-next/schematics/application.md
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
# application
|
||||||
|
|
||||||
|
Create a Next.js application
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ng generate application ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ng g app ... # same
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `application` in the default collection provisioned in `angular.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ng g @nrwl/next:application ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ng g application ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
Generate apps/myorg/myapp and apps/myorg/myapp-e2e:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ng g app myapp --directory=myorg
|
||||||
|
```
|
||||||
|
|
||||||
|
Use class components instead of functional components:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ng g app myapp --classComponent
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### classComponent
|
||||||
|
|
||||||
|
Alias(es): C
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Use class components instead of functional component
|
||||||
|
|
||||||
|
### directory
|
||||||
|
|
||||||
|
Alias(es): d
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The directory of the new application.
|
||||||
|
|
||||||
|
### e2eTestRunner
|
||||||
|
|
||||||
|
Default: `cypress`
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Possible values: `cypress`, `none`
|
||||||
|
|
||||||
|
Test runner to use for end to end (e2e) tests
|
||||||
|
|
||||||
|
### linter
|
||||||
|
|
||||||
|
Default: `tslint`
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Possible values: `eslint`, `tslint`
|
||||||
|
|
||||||
|
The tool to use for running lint checks.
|
||||||
|
|
||||||
|
### name
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The name of the application.
|
||||||
|
|
||||||
|
### pascalCaseFiles
|
||||||
|
|
||||||
|
Alias(es): P
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Use pascal case component file name (e.g. App.tsx)
|
||||||
|
|
||||||
|
### skipFormat
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Skip formatting files
|
||||||
|
|
||||||
|
### skipWorkspaceJson
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Skip updating workspace.json with default schematic options based on values provided to this app (e.g. babel, style)
|
||||||
|
|
||||||
|
### style
|
||||||
|
|
||||||
|
Alias(es): s
|
||||||
|
|
||||||
|
Default: `css`
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Possible values: `css`, `scss`, `styl`, `less`, `styled-components`, `@emotion/styled`
|
||||||
|
|
||||||
|
The file extension to be used for style files.
|
||||||
|
|
||||||
|
### tags
|
||||||
|
|
||||||
|
Alias(es): t
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Add tags to the application (used for linting)
|
||||||
|
|
||||||
|
### unitTestRunner
|
||||||
|
|
||||||
|
Default: `jest`
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Possible values: `jest`, `none`
|
||||||
|
|
||||||
|
Test runner to use for unit tests
|
||||||
@ -1 +1,11 @@
|
|||||||
["cypress", "express", "jest", "linter", "nest", "node", "web", "workspace"]
|
[
|
||||||
|
"cypress",
|
||||||
|
"express",
|
||||||
|
"jest",
|
||||||
|
"linter",
|
||||||
|
"nest",
|
||||||
|
"next",
|
||||||
|
"node",
|
||||||
|
"web",
|
||||||
|
"workspace"
|
||||||
|
]
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
"express",
|
"express",
|
||||||
"jest",
|
"jest",
|
||||||
"nest",
|
"nest",
|
||||||
|
"next",
|
||||||
"node",
|
"node",
|
||||||
"react",
|
"react",
|
||||||
"web",
|
"web",
|
||||||
|
|||||||
33
docs/react/api-express/schematics/init.md
Normal file
33
docs/react/api-express/schematics/init.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# init
|
||||||
|
|
||||||
|
Initialize the @nrwl/express plugin
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx generate init ...
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `init` in the default collection provisioned in `workspace.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/express:init ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g init ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### skipFormat
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Skip formatting files
|
||||||
6
docs/react/api-next/builders/build.md
Normal file
6
docs/react/api-next/builders/build.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# build
|
||||||
|
|
||||||
|
Build a Next.js app
|
||||||
|
|
||||||
|
Builder properties can be configured in workspace.json when defining the builder, or when invoking it.
|
||||||
|
Read more about how to use builders and the CLI here: https://nx.dev/react/guides/cli.
|
||||||
46
docs/react/api-next/builders/dev-server.md
Normal file
46
docs/react/api-next/builders/dev-server.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# dev-server
|
||||||
|
|
||||||
|
Serve a Next.js app
|
||||||
|
|
||||||
|
Builder properties can be configured in workspace.json when defining the builder, or when invoking it.
|
||||||
|
Read more about how to use builders and the CLI here: https://nx.dev/react/guides/cli.
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
### buildTarget
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Target which builds the application
|
||||||
|
|
||||||
|
### dev
|
||||||
|
|
||||||
|
Default: `true`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Serve the application in the dev mode
|
||||||
|
|
||||||
|
### port
|
||||||
|
|
||||||
|
Default: `4200`
|
||||||
|
|
||||||
|
Type: `number`
|
||||||
|
|
||||||
|
Port to listen on.
|
||||||
|
|
||||||
|
### quiet
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Hide error messages containing server information.
|
||||||
|
|
||||||
|
### staticMarkup
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Static markup.
|
||||||
6
docs/react/api-next/builders/export.md
Normal file
6
docs/react/api-next/builders/export.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# export
|
||||||
|
|
||||||
|
Export a Next.js app
|
||||||
|
|
||||||
|
Builder properties can be configured in workspace.json when defining the builder, or when invoking it.
|
||||||
|
Read more about how to use builders and the CLI here: https://nx.dev/react/guides/cli.
|
||||||
143
docs/react/api-next/schematics/application.md
Normal file
143
docs/react/api-next/schematics/application.md
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
# application
|
||||||
|
|
||||||
|
Create a Next.js application
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx generate application ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g app ... # same
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `application` in the default collection provisioned in `workspace.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/next:application ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g application ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
Generate apps/myorg/myapp and apps/myorg/myapp-e2e:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g app myapp --directory=myorg
|
||||||
|
```
|
||||||
|
|
||||||
|
Use class components instead of functional components:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g app myapp --classComponent
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### classComponent
|
||||||
|
|
||||||
|
Alias(es): C
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Use class components instead of functional component
|
||||||
|
|
||||||
|
### directory
|
||||||
|
|
||||||
|
Alias(es): d
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The directory of the new application.
|
||||||
|
|
||||||
|
### e2eTestRunner
|
||||||
|
|
||||||
|
Default: `cypress`
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Possible values: `cypress`, `none`
|
||||||
|
|
||||||
|
Test runner to use for end to end (e2e) tests
|
||||||
|
|
||||||
|
### linter
|
||||||
|
|
||||||
|
Default: `tslint`
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Possible values: `eslint`, `tslint`
|
||||||
|
|
||||||
|
The tool to use for running lint checks.
|
||||||
|
|
||||||
|
### name
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The name of the application.
|
||||||
|
|
||||||
|
### pascalCaseFiles
|
||||||
|
|
||||||
|
Alias(es): P
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Use pascal case component file name (e.g. App.tsx)
|
||||||
|
|
||||||
|
### skipFormat
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Skip formatting files
|
||||||
|
|
||||||
|
### skipWorkspaceJson
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Skip updating workspace.json with default schematic options based on values provided to this app (e.g. babel, style)
|
||||||
|
|
||||||
|
### style
|
||||||
|
|
||||||
|
Alias(es): s
|
||||||
|
|
||||||
|
Default: `css`
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Possible values: `css`, `scss`, `styl`, `less`, `styled-components`, `@emotion/styled`
|
||||||
|
|
||||||
|
The file extension to be used for style files.
|
||||||
|
|
||||||
|
### tags
|
||||||
|
|
||||||
|
Alias(es): t
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Add tags to the application (used for linting)
|
||||||
|
|
||||||
|
### unitTestRunner
|
||||||
|
|
||||||
|
Default: `jest`
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Possible values: `jest`, `none`
|
||||||
|
|
||||||
|
Test runner to use for unit tests
|
||||||
@ -1 +1,11 @@
|
|||||||
["cypress", "express", "jest", "linter", "nest", "node", "web", "workspace"]
|
[
|
||||||
|
"cypress",
|
||||||
|
"express",
|
||||||
|
"jest",
|
||||||
|
"linter",
|
||||||
|
"nest",
|
||||||
|
"next",
|
||||||
|
"node",
|
||||||
|
"web",
|
||||||
|
"workspace"
|
||||||
|
]
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
"express",
|
"express",
|
||||||
"jest",
|
"jest",
|
||||||
"nest",
|
"nest",
|
||||||
|
"next",
|
||||||
"node",
|
"node",
|
||||||
"react",
|
"react",
|
||||||
"web",
|
"web",
|
||||||
|
|||||||
33
docs/web/api-express/schematics/init.md
Normal file
33
docs/web/api-express/schematics/init.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# init
|
||||||
|
|
||||||
|
Initialize the @nrwl/express plugin
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx generate init ...
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `init` in the default collection provisioned in `workspace.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/express:init ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g init ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### skipFormat
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Skip formatting files
|
||||||
6
docs/web/api-next/builders/build.md
Normal file
6
docs/web/api-next/builders/build.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# build
|
||||||
|
|
||||||
|
Build a Next.js app
|
||||||
|
|
||||||
|
Builder properties can be configured in workspace.json when defining the builder, or when invoking it.
|
||||||
|
Read more about how to use builders and the CLI here: https://nx.dev/web/guides/cli.
|
||||||
46
docs/web/api-next/builders/dev-server.md
Normal file
46
docs/web/api-next/builders/dev-server.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# dev-server
|
||||||
|
|
||||||
|
Serve a Next.js app
|
||||||
|
|
||||||
|
Builder properties can be configured in workspace.json when defining the builder, or when invoking it.
|
||||||
|
Read more about how to use builders and the CLI here: https://nx.dev/web/guides/cli.
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
### buildTarget
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Target which builds the application
|
||||||
|
|
||||||
|
### dev
|
||||||
|
|
||||||
|
Default: `true`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Serve the application in the dev mode
|
||||||
|
|
||||||
|
### port
|
||||||
|
|
||||||
|
Default: `4200`
|
||||||
|
|
||||||
|
Type: `number`
|
||||||
|
|
||||||
|
Port to listen on.
|
||||||
|
|
||||||
|
### quiet
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Hide error messages containing server information.
|
||||||
|
|
||||||
|
### staticMarkup
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Static markup.
|
||||||
6
docs/web/api-next/builders/export.md
Normal file
6
docs/web/api-next/builders/export.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# export
|
||||||
|
|
||||||
|
Export a Next.js app
|
||||||
|
|
||||||
|
Builder properties can be configured in workspace.json when defining the builder, or when invoking it.
|
||||||
|
Read more about how to use builders and the CLI here: https://nx.dev/web/guides/cli.
|
||||||
143
docs/web/api-next/schematics/application.md
Normal file
143
docs/web/api-next/schematics/application.md
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
# application
|
||||||
|
|
||||||
|
Create a Next.js application
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx generate application ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g app ... # same
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `application` in the default collection provisioned in `workspace.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/next:application ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g application ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
Generate apps/myorg/myapp and apps/myorg/myapp-e2e:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g app myapp --directory=myorg
|
||||||
|
```
|
||||||
|
|
||||||
|
Use class components instead of functional components:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g app myapp --classComponent
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### classComponent
|
||||||
|
|
||||||
|
Alias(es): C
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Use class components instead of functional component
|
||||||
|
|
||||||
|
### directory
|
||||||
|
|
||||||
|
Alias(es): d
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The directory of the new application.
|
||||||
|
|
||||||
|
### e2eTestRunner
|
||||||
|
|
||||||
|
Default: `cypress`
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Possible values: `cypress`, `none`
|
||||||
|
|
||||||
|
Test runner to use for end to end (e2e) tests
|
||||||
|
|
||||||
|
### linter
|
||||||
|
|
||||||
|
Default: `tslint`
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Possible values: `eslint`, `tslint`
|
||||||
|
|
||||||
|
The tool to use for running lint checks.
|
||||||
|
|
||||||
|
### name
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The name of the application.
|
||||||
|
|
||||||
|
### pascalCaseFiles
|
||||||
|
|
||||||
|
Alias(es): P
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Use pascal case component file name (e.g. App.tsx)
|
||||||
|
|
||||||
|
### skipFormat
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Skip formatting files
|
||||||
|
|
||||||
|
### skipWorkspaceJson
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Skip updating workspace.json with default schematic options based on values provided to this app (e.g. babel, style)
|
||||||
|
|
||||||
|
### style
|
||||||
|
|
||||||
|
Alias(es): s
|
||||||
|
|
||||||
|
Default: `css`
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Possible values: `css`, `scss`, `styl`, `less`, `styled-components`, `@emotion/styled`
|
||||||
|
|
||||||
|
The file extension to be used for style files.
|
||||||
|
|
||||||
|
### tags
|
||||||
|
|
||||||
|
Alias(es): t
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Add tags to the application (used for linting)
|
||||||
|
|
||||||
|
### unitTestRunner
|
||||||
|
|
||||||
|
Default: `jest`
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Possible values: `jest`, `none`
|
||||||
|
|
||||||
|
Test runner to use for unit tests
|
||||||
@ -1 +1,11 @@
|
|||||||
["cypress", "express", "jest", "linter", "nest", "node", "web", "workspace"]
|
[
|
||||||
|
"cypress",
|
||||||
|
"express",
|
||||||
|
"jest",
|
||||||
|
"linter",
|
||||||
|
"nest",
|
||||||
|
"next",
|
||||||
|
"node",
|
||||||
|
"web",
|
||||||
|
"workspace"
|
||||||
|
]
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
"express",
|
"express",
|
||||||
"jest",
|
"jest",
|
||||||
"nest",
|
"nest",
|
||||||
|
"next",
|
||||||
"node",
|
"node",
|
||||||
"react",
|
"react",
|
||||||
"web",
|
"web",
|
||||||
|
|||||||
133
e2e/next.test.ts
Normal file
133
e2e/next.test.ts
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
import { capitalize } from '@nrwl/workspace/src/utils/strings';
|
||||||
|
import * as http from 'http';
|
||||||
|
import {
|
||||||
|
checkFilesExist,
|
||||||
|
ensureProject,
|
||||||
|
forEachCli,
|
||||||
|
readFile,
|
||||||
|
runCLI,
|
||||||
|
runCLIAsync,
|
||||||
|
uniq,
|
||||||
|
updateFile
|
||||||
|
} from './utils';
|
||||||
|
import treeKill = require('tree-kill');
|
||||||
|
|
||||||
|
forEachCli('nx', () => {
|
||||||
|
describe('Next.js Applications', () => {
|
||||||
|
it('should generate a Nest.jx app that consumes a react lib', async () => {
|
||||||
|
ensureProject();
|
||||||
|
const appName = uniq('app');
|
||||||
|
const libName = uniq('lib');
|
||||||
|
|
||||||
|
runCLI(
|
||||||
|
`generate @nrwl/next:app ${appName} --no-interactive --linter=eslint`
|
||||||
|
);
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/react:lib ${libName} --no-interactive`);
|
||||||
|
|
||||||
|
const mainPath = `apps/${appName}/pages/index.tsx`;
|
||||||
|
updateFile(mainPath, `import '@proj/${libName}';\n` + readFile(mainPath));
|
||||||
|
updateFile(
|
||||||
|
`apps/${appName}/next.config.js`,
|
||||||
|
`
|
||||||
|
module.exports = {
|
||||||
|
generateBuildId: function () {
|
||||||
|
return 'fixed';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
await checkApp(appName, { checkLint: true });
|
||||||
|
|
||||||
|
// check that the configuration was consumed
|
||||||
|
expect(readFile(`dist/apps/${appName}/BUILD_ID`)).toEqual('fixed');
|
||||||
|
}, 120000);
|
||||||
|
|
||||||
|
it('should generate a Next.js app dynamically loading a lib', async () => {
|
||||||
|
ensureProject();
|
||||||
|
const appName = uniq('app');
|
||||||
|
const libName = uniq('lib');
|
||||||
|
|
||||||
|
runCLI(
|
||||||
|
`generate @nrwl/next:app ${appName} --no-interactive --linter=eslint`
|
||||||
|
);
|
||||||
|
runCLI(`generate @nrwl/react:lib ${libName} --no-interactive`);
|
||||||
|
|
||||||
|
const mainPath = `apps/${appName}/pages/index.tsx`;
|
||||||
|
updateFile(
|
||||||
|
mainPath,
|
||||||
|
`
|
||||||
|
import dynamic from 'next/dynamic';
|
||||||
|
const DynamicComponent = dynamic(
|
||||||
|
() => import('@proj/${libName}').then(d => d.${capitalize(libName)})
|
||||||
|
);
|
||||||
|
` + readFile(mainPath)
|
||||||
|
);
|
||||||
|
|
||||||
|
await checkApp(appName, { checkLint: false });
|
||||||
|
}, 120000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
async function checkApp(appName: string, opts: { checkLint: boolean }) {
|
||||||
|
if (opts.checkLint) {
|
||||||
|
const lintResults = runCLI(`lint ${appName}`);
|
||||||
|
expect(lintResults).toContain('All files pass linting.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const testResults = await runCLIAsync(`test ${appName}`);
|
||||||
|
expect(testResults.stderr).toContain('Test Suites: 1 passed, 1 total');
|
||||||
|
|
||||||
|
// const server = fork(
|
||||||
|
// `./node_modules/@nrwl/cli/bin/nx.js`,
|
||||||
|
// [`serve`, appName],
|
||||||
|
// {
|
||||||
|
// cwd: tmpProjPath(),
|
||||||
|
// silent: true
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
// expect(server).toBeTruthy();
|
||||||
|
// await new Promise(resolve => {
|
||||||
|
// setTimeout(() => {
|
||||||
|
// getPage().then(page => {
|
||||||
|
// expect(page).toContain(`Here are some things you can do with Nx`);
|
||||||
|
// treeKill(server.pid, 'SIGTERM', err => {
|
||||||
|
// expect(err).toBeFalsy();
|
||||||
|
// resolve();
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// }, 5000);
|
||||||
|
// });
|
||||||
|
// if (supportUi()) {
|
||||||
|
// const e2eResults = runCLI(`e2e ${appName}-e2e`);
|
||||||
|
// expect(e2eResults).toContain('All specs passed!');
|
||||||
|
// }
|
||||||
|
|
||||||
|
const buildResult = runCLI(`build ${appName}`);
|
||||||
|
expect(buildResult).toContain(`Compiled successfully`);
|
||||||
|
checkFilesExist(`dist/apps/${appName}/build-manifest.json`);
|
||||||
|
|
||||||
|
const exportResult = runCLI(`export ${appName}`);
|
||||||
|
checkFilesExist(`dist/apps/${appName}/exported/index.html`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPage(): Promise<string> {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
http.get('http://localhost:4200/', res => {
|
||||||
|
let data = '';
|
||||||
|
res.on('data', chunk => {
|
||||||
|
data += chunk;
|
||||||
|
});
|
||||||
|
res.once('end', () => {
|
||||||
|
resolve(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
forEachCli('angular', () => {
|
||||||
|
describe('next', () => {
|
||||||
|
it('is not supported', () => {});
|
||||||
|
});
|
||||||
|
});
|
||||||
12
e2e/utils.ts
12
e2e/utils.ts
@ -148,15 +148,7 @@ export function ensureProject(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function supportUi() {
|
export function supportUi() {
|
||||||
// powershell => wsl => no ui for now
|
return !process.env.NO_CHROME;
|
||||||
try {
|
|
||||||
execSync(`powershell.exe echo 1`, {
|
|
||||||
stdio: ['ignore', 'ignore', 'ignore']
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
} catch (e) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function copyMissingPackages(): void {
|
export function copyMissingPackages(): void {
|
||||||
@ -216,6 +208,8 @@ export function copyMissingPackages(): void {
|
|||||||
'eslint-plugin-react',
|
'eslint-plugin-react',
|
||||||
'eslint-plugin-react-hooks',
|
'eslint-plugin-react-hooks',
|
||||||
|
|
||||||
|
'next',
|
||||||
|
'next-server',
|
||||||
'document-register-element'
|
'document-register-element'
|
||||||
];
|
];
|
||||||
modulesToCopy.forEach(m => copyNodeModule(m));
|
modulesToCopy.forEach(m => copyNodeModule(m));
|
||||||
|
|||||||
@ -147,7 +147,12 @@
|
|||||||
"webpack-node-externals": "^1.7.2",
|
"webpack-node-externals": "^1.7.2",
|
||||||
"yargs": "^11.0.0",
|
"yargs": "^11.0.0",
|
||||||
"yargs-parser": "10.0.0",
|
"yargs-parser": "10.0.0",
|
||||||
"zone.js": "^0.9.0"
|
"zone.js": "^0.9.0",
|
||||||
|
"next": "9.0.5",
|
||||||
|
"@zeit/next-css": "1.0.1",
|
||||||
|
"@zeit/next-sass": "1.0.1",
|
||||||
|
"@zeit/next-less": "1.0.1",
|
||||||
|
"@zeit/next-stylus": "1.0.1"
|
||||||
},
|
},
|
||||||
"author": "Victor Savkin",
|
"author": "Victor Savkin",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "nx/angular",
|
"name": "Nx Angular",
|
||||||
"version": "0.1",
|
"version": "0.1",
|
||||||
"extends": ["@schematics/angular", "@nrwl/workspace"],
|
"extends": ["@schematics/angular", "@nrwl/workspace"],
|
||||||
"schematics": {
|
"schematics": {
|
||||||
"ng-add": {
|
"init": {
|
||||||
"factory": "./src/schematics/ng-add/ng-add",
|
"factory": "./src/schematics/init/init",
|
||||||
"schema": "./src/schematics/ng-add/schema.json",
|
"schema": "./src/schematics/init/schema.json",
|
||||||
"description": "Add @nrwl/angular to a project",
|
"description": "Initialize the @nrwl/angular plugin",
|
||||||
|
"aliaes": ["ng-add"],
|
||||||
"hidden": true
|
"hidden": true
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,7 @@ import {
|
|||||||
addLintFiles
|
addLintFiles
|
||||||
} from '@nrwl/workspace';
|
} from '@nrwl/workspace';
|
||||||
import { join, normalize } from '@angular-devkit/core';
|
import { join, normalize } from '@angular-devkit/core';
|
||||||
import ngAdd from '../ng-add/ng-add';
|
import init from '../init/init';
|
||||||
import {
|
import {
|
||||||
addImportToModule,
|
addImportToModule,
|
||||||
addImportToTestBed,
|
addImportToTestBed,
|
||||||
@ -657,7 +657,7 @@ export default function(schema: Schema): Rule {
|
|||||||
: `${options.name}/e2e`;
|
: `${options.name}/e2e`;
|
||||||
|
|
||||||
return chain([
|
return chain([
|
||||||
ngAdd({
|
init({
|
||||||
...options,
|
...options,
|
||||||
skipFormat: true
|
skipFormat: true
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { runSchematic, callRule } from '../../utils/testing';
|
|||||||
import { createEmptyWorkspace } from '@nrwl/workspace/testing';
|
import { createEmptyWorkspace } from '@nrwl/workspace/testing';
|
||||||
import { readJsonInTree, updateJsonInTree } from '@nrwl/workspace';
|
import { readJsonInTree, updateJsonInTree } from '@nrwl/workspace';
|
||||||
|
|
||||||
describe('ng-add', () => {
|
describe('init', () => {
|
||||||
let appTree: Tree;
|
let appTree: Tree;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -11,7 +11,7 @@ describe('ng-add', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should add angular dependencies', async () => {
|
it('should add angular dependencies', async () => {
|
||||||
const tree = await runSchematic('ng-add', {}, appTree);
|
const tree = await runSchematic('init', {}, appTree);
|
||||||
const { dependencies, devDependencies } = readJsonInTree(
|
const { dependencies, devDependencies } = readJsonInTree(
|
||||||
tree,
|
tree,
|
||||||
'package.json'
|
'package.json'
|
||||||
@ -36,7 +36,7 @@ describe('ng-add', () => {
|
|||||||
describe('karma', () => {
|
describe('karma', () => {
|
||||||
it('should add karma dependencies', async () => {
|
it('should add karma dependencies', async () => {
|
||||||
const tree = await runSchematic(
|
const tree = await runSchematic(
|
||||||
'ng-add',
|
'init',
|
||||||
{
|
{
|
||||||
unitTestRunner: 'karma'
|
unitTestRunner: 'karma'
|
||||||
},
|
},
|
||||||
@ -57,7 +57,7 @@ describe('ng-add', () => {
|
|||||||
|
|
||||||
it('should add karma configuration', async () => {
|
it('should add karma configuration', async () => {
|
||||||
const tree = await runSchematic(
|
const tree = await runSchematic(
|
||||||
'ng-add',
|
'init',
|
||||||
{
|
{
|
||||||
unitTestRunner: 'karma'
|
unitTestRunner: 'karma'
|
||||||
},
|
},
|
||||||
@ -68,7 +68,7 @@ describe('ng-add', () => {
|
|||||||
|
|
||||||
it('should set defaults', async () => {
|
it('should set defaults', async () => {
|
||||||
const tree = await runSchematic(
|
const tree = await runSchematic(
|
||||||
'ng-add',
|
'init',
|
||||||
{
|
{
|
||||||
unitTestRunner: 'karma'
|
unitTestRunner: 'karma'
|
||||||
},
|
},
|
||||||
@ -87,7 +87,7 @@ describe('ng-add', () => {
|
|||||||
describe('jest', () => {
|
describe('jest', () => {
|
||||||
it('should add jest dependencies', async () => {
|
it('should add jest dependencies', async () => {
|
||||||
const tree = await runSchematic(
|
const tree = await runSchematic(
|
||||||
'ng-add',
|
'init',
|
||||||
{
|
{
|
||||||
unitTestRunner: 'jest'
|
unitTestRunner: 'jest'
|
||||||
},
|
},
|
||||||
@ -101,7 +101,7 @@ describe('ng-add', () => {
|
|||||||
|
|
||||||
it('should add jest configuration', async () => {
|
it('should add jest configuration', async () => {
|
||||||
const tree = await runSchematic(
|
const tree = await runSchematic(
|
||||||
'ng-add',
|
'init',
|
||||||
{
|
{
|
||||||
unitTestRunner: 'jest'
|
unitTestRunner: 'jest'
|
||||||
},
|
},
|
||||||
@ -112,7 +112,7 @@ describe('ng-add', () => {
|
|||||||
|
|
||||||
it('should set defaults', async () => {
|
it('should set defaults', async () => {
|
||||||
const tree = await runSchematic(
|
const tree = await runSchematic(
|
||||||
'ng-add',
|
'init',
|
||||||
{
|
{
|
||||||
unitTestRunner: 'jest'
|
unitTestRunner: 'jest'
|
||||||
},
|
},
|
||||||
@ -133,7 +133,7 @@ describe('ng-add', () => {
|
|||||||
describe('cypress', () => {
|
describe('cypress', () => {
|
||||||
it('should add cypress dependencies', async () => {
|
it('should add cypress dependencies', async () => {
|
||||||
const tree = await runSchematic(
|
const tree = await runSchematic(
|
||||||
'ng-add',
|
'init',
|
||||||
{
|
{
|
||||||
unitTestRunner: 'none',
|
unitTestRunner: 'none',
|
||||||
e2eTestRunner: 'cypress'
|
e2eTestRunner: 'cypress'
|
||||||
@ -147,7 +147,7 @@ describe('ng-add', () => {
|
|||||||
|
|
||||||
it('should set defaults', async () => {
|
it('should set defaults', async () => {
|
||||||
const tree = await runSchematic(
|
const tree = await runSchematic(
|
||||||
'ng-add',
|
'init',
|
||||||
{
|
{
|
||||||
e2eTestRunner: 'cypress'
|
e2eTestRunner: 'cypress'
|
||||||
},
|
},
|
||||||
@ -163,7 +163,7 @@ describe('ng-add', () => {
|
|||||||
describe('protractor', () => {
|
describe('protractor', () => {
|
||||||
it('should add protractor dependencies', async () => {
|
it('should add protractor dependencies', async () => {
|
||||||
const tree = await runSchematic(
|
const tree = await runSchematic(
|
||||||
'ng-add',
|
'init',
|
||||||
{
|
{
|
||||||
e2eTestRunner: 'protractor'
|
e2eTestRunner: 'protractor'
|
||||||
},
|
},
|
||||||
@ -179,7 +179,7 @@ describe('ng-add', () => {
|
|||||||
|
|
||||||
it('should set defaults', async () => {
|
it('should set defaults', async () => {
|
||||||
const tree = await runSchematic(
|
const tree = await runSchematic(
|
||||||
'ng-add',
|
'init',
|
||||||
{
|
{
|
||||||
e2eTestRunner: 'protractor'
|
e2eTestRunner: 'protractor'
|
||||||
},
|
},
|
||||||
@ -195,7 +195,7 @@ describe('ng-add', () => {
|
|||||||
|
|
||||||
describe('defaultCollection', () => {
|
describe('defaultCollection', () => {
|
||||||
it('should be set if none was set before', async () => {
|
it('should be set if none was set before', async () => {
|
||||||
const result = await runSchematic('ng-add', {}, appTree);
|
const result = await runSchematic('init', {}, appTree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/angular');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/angular');
|
||||||
});
|
});
|
||||||
@ -211,7 +211,7 @@ describe('ng-add', () => {
|
|||||||
}),
|
}),
|
||||||
appTree
|
appTree
|
||||||
);
|
);
|
||||||
const result = await runSchematic('ng-add', {}, appTree);
|
const result = await runSchematic('init', {}, appTree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/angular');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/angular');
|
||||||
});
|
});
|
||||||
@ -227,7 +227,7 @@ describe('ng-add', () => {
|
|||||||
}),
|
}),
|
||||||
appTree
|
appTree
|
||||||
);
|
);
|
||||||
const result = await runSchematic('ng-add', {}, appTree);
|
const result = await runSchematic('init', {}, appTree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/react');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/react');
|
||||||
});
|
});
|
||||||
@ -67,7 +67,7 @@ export function addUnitTestRunner(
|
|||||||
}
|
}
|
||||||
return externalSchematic(
|
return externalSchematic(
|
||||||
'@nrwl/jest',
|
'@nrwl/jest',
|
||||||
'ng-add',
|
'init',
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
interactive: false
|
interactive: false
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/schema",
|
"$schema": "http://json-schema.org/schema",
|
||||||
"id": "SchematicsNxNgAdd",
|
"id": "SchematicsAngularModuleInit",
|
||||||
"title": "Add Nx Schematics to Project and Convert Workspace",
|
"title": "Add Nx Schematics to Project and Convert Workspace",
|
||||||
"description": "NOTE: Does not work in the --dry-run mode",
|
"description": "NOTE: Does not work in the --dry-run mode",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@ -36,7 +36,7 @@ import {
|
|||||||
toPropertyName,
|
toPropertyName,
|
||||||
updateJsonInTree
|
updateJsonInTree
|
||||||
} from '@nrwl/workspace';
|
} from '@nrwl/workspace';
|
||||||
import { addUnitTestRunner } from '../ng-add/ng-add';
|
import { addUnitTestRunner } from '../init/init';
|
||||||
import { addImportToModule, addRoute } from '../../utils/ast-utils';
|
import { addImportToModule, addRoute } from '../../utils/ast-utils';
|
||||||
import { insertImport } from '@nrwl/workspace/src/utils/ast-utils';
|
import { insertImport } from '@nrwl/workspace/src/utils/ast-utils';
|
||||||
|
|
||||||
|
|||||||
@ -2,10 +2,11 @@
|
|||||||
"name": "Nx Cypress",
|
"name": "Nx Cypress",
|
||||||
"version": "0.1",
|
"version": "0.1",
|
||||||
"schematics": {
|
"schematics": {
|
||||||
"ng-add": {
|
"init": {
|
||||||
"factory": "./src/schematics/ng-add/ng-add",
|
"factory": "./src/schematics/init/init",
|
||||||
"schema": "./src/schematics/ng-add/schema.json",
|
"schema": "./src/schematics/init/schema.json",
|
||||||
"description": "Add Cypress configuration to the workspace",
|
"description": "Initialize the @nrwl/cypress plugin",
|
||||||
|
"aliases": ["ng-add"],
|
||||||
"hidden": true
|
"hidden": true
|
||||||
},
|
},
|
||||||
"cypress-project": {
|
"cypress-project": {
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { createEmptyWorkspace } from '@nrwl/workspace/testing';
|
|||||||
|
|
||||||
import { runSchematic } from '../../utils/testing';
|
import { runSchematic } from '../../utils/testing';
|
||||||
|
|
||||||
describe('ng-add', () => {
|
describe('init', () => {
|
||||||
let appTree: Tree;
|
let appTree: Tree;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -14,7 +14,7 @@ describe('ng-add', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should add dependencies into `package.json` file', async () => {
|
it('should add dependencies into `package.json` file', async () => {
|
||||||
const tree = await runSchematic('ng-add', {}, appTree);
|
const tree = await runSchematic('init', {}, appTree);
|
||||||
const packageJson = readJsonInTree(tree, 'package.json');
|
const packageJson = readJsonInTree(tree, 'package.json');
|
||||||
|
|
||||||
expect(packageJson.devDependencies.cypress).toBeDefined();
|
expect(packageJson.devDependencies.cypress).toBeDefined();
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/schema",
|
"$schema": "http://json-schema.org/schema",
|
||||||
"id": "Nx Cypress Project Schematics Schema",
|
"id": "NxCypressInit",
|
||||||
"title": "Add Cypress Configuration to the workspace",
|
"title": "Add Cypress Configuration to the workspace",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {}
|
"properties": {}
|
||||||
@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "nx/express",
|
"name": "Nx Express",
|
||||||
"version": "0.1",
|
"version": "0.1",
|
||||||
"extends": ["@nrwl/workspace"],
|
"extends": ["@nrwl/workspace"],
|
||||||
"schematics": {
|
"schematics": {
|
||||||
"ng-add": {
|
"init": {
|
||||||
"factory": "./src/schematics/ng-add/ng-add",
|
"factory": "./src/schematics/init/init",
|
||||||
"schema": "./src/schematics/ng-add/schema.json",
|
"schema": "./src/schematics/init/schema.json",
|
||||||
"description": "Add @nrwl/express to a project",
|
"description": "Initialize the @nrwl/express plugin",
|
||||||
"hidden": true
|
"alias": ["ng-add"]
|
||||||
},
|
},
|
||||||
|
|
||||||
"application": {
|
"application": {
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import { join, normalize, Path } from '@angular-devkit/core';
|
|||||||
import { Schema } from './schema';
|
import { Schema } from './schema';
|
||||||
import { updateJsonInTree } from '@nrwl/workspace';
|
import { updateJsonInTree } from '@nrwl/workspace';
|
||||||
import { toFileName, formatFiles } from '@nrwl/workspace';
|
import { toFileName, formatFiles } from '@nrwl/workspace';
|
||||||
import ngAdd from '../ng-add/ng-add';
|
import init from '../init/init';
|
||||||
|
|
||||||
interface NormalizedSchema extends Schema {
|
interface NormalizedSchema extends Schema {
|
||||||
appProjectRoot: Path;
|
appProjectRoot: Path;
|
||||||
@ -54,7 +54,7 @@ export default function(schema: Schema): Rule {
|
|||||||
return (host: Tree, context: SchematicContext) => {
|
return (host: Tree, context: SchematicContext) => {
|
||||||
const options = normalizeOptions(schema);
|
const options = normalizeOptions(schema);
|
||||||
return chain([
|
return chain([
|
||||||
ngAdd({ skipFormat: true }),
|
init({ skipFormat: true }),
|
||||||
externalSchematic('@nrwl/node', 'application', schema),
|
externalSchematic('@nrwl/node', 'application', schema),
|
||||||
addMainFile(options),
|
addMainFile(options),
|
||||||
addTypes(options),
|
addTypes(options),
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { join } from 'path';
|
|||||||
import { readJsonInTree, updateJsonInTree } from '@nrwl/workspace';
|
import { readJsonInTree, updateJsonInTree } from '@nrwl/workspace';
|
||||||
import { callRule, runSchematic } from '../../utils/testing';
|
import { callRule, runSchematic } from '../../utils/testing';
|
||||||
|
|
||||||
describe('ng-add', () => {
|
describe('init', () => {
|
||||||
let tree: Tree;
|
let tree: Tree;
|
||||||
let testRunner: SchematicTestRunner;
|
let testRunner: SchematicTestRunner;
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ describe('ng-add', () => {
|
|||||||
|
|
||||||
it('should add dependencies', async () => {
|
it('should add dependencies', async () => {
|
||||||
const result = await testRunner
|
const result = await testRunner
|
||||||
.runSchematicAsync('ng-add', {}, tree)
|
.runSchematicAsync('init', {}, tree)
|
||||||
.toPromise();
|
.toPromise();
|
||||||
const packageJson = readJsonInTree(result, 'package.json');
|
const packageJson = readJsonInTree(result, 'package.json');
|
||||||
expect(packageJson.dependencies['@nrwl/express']).toBeUndefined();
|
expect(packageJson.dependencies['@nrwl/express']).toBeUndefined();
|
||||||
@ -31,7 +31,7 @@ describe('ng-add', () => {
|
|||||||
|
|
||||||
describe('defaultCollection', () => {
|
describe('defaultCollection', () => {
|
||||||
it('should be set if none was set before', async () => {
|
it('should be set if none was set before', async () => {
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/express');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/express');
|
||||||
});
|
});
|
||||||
@ -47,7 +47,7 @@ describe('ng-add', () => {
|
|||||||
}),
|
}),
|
||||||
tree
|
tree
|
||||||
);
|
);
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/express');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/express');
|
||||||
});
|
});
|
||||||
@ -63,7 +63,7 @@ describe('ng-add', () => {
|
|||||||
}),
|
}),
|
||||||
tree
|
tree
|
||||||
);
|
);
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/angular');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/angular');
|
||||||
});
|
});
|
||||||
@ -2,7 +2,7 @@ import { Rule, chain } from '@angular-devkit/schematics';
|
|||||||
import {
|
import {
|
||||||
addDepsToPackageJson,
|
addDepsToPackageJson,
|
||||||
updateJsonInTree,
|
updateJsonInTree,
|
||||||
addPackageWithNgAdd,
|
addPackageWithInit,
|
||||||
updateWorkspace,
|
updateWorkspace,
|
||||||
formatFiles
|
formatFiles
|
||||||
} from '@nrwl/workspace';
|
} from '@nrwl/workspace';
|
||||||
@ -53,8 +53,8 @@ function setDefault(): Rule {
|
|||||||
export default function(schema: Schema) {
|
export default function(schema: Schema) {
|
||||||
return chain([
|
return chain([
|
||||||
setDefault(),
|
setDefault(),
|
||||||
addPackageWithNgAdd('@nrwl/node'),
|
addPackageWithInit('@nrwl/node'),
|
||||||
addPackageWithNgAdd('@nrwl/jest'),
|
addPackageWithInit('@nrwl/jest'),
|
||||||
addDependencies(),
|
addDependencies(),
|
||||||
moveDependency(),
|
moveDependency(),
|
||||||
formatFiles(schema)
|
formatFiles(schema)
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/schema",
|
"$schema": "http://json-schema.org/schema",
|
||||||
"id": "NxExpressNgAdd",
|
"id": "NxExpressInit",
|
||||||
"title": "Add Nx Express Schematics",
|
"title": "Add Nx Express Schematics",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -2,10 +2,11 @@
|
|||||||
"name": "Nx Jest",
|
"name": "Nx Jest",
|
||||||
"version": "0.1",
|
"version": "0.1",
|
||||||
"schematics": {
|
"schematics": {
|
||||||
"ng-add": {
|
"init": {
|
||||||
"factory": "./src/schematics/ng-add/ng-add",
|
"factory": "./src/schematics/init/init",
|
||||||
"schema": "./src/schematics/ng-add/schema.json",
|
"schema": "./src/schematics/init/schema.json",
|
||||||
"description": "Add Jest configuration to the workspace",
|
"description": "Initialize the @nrwl/jest plugin",
|
||||||
|
"aliases": ["ng-add"],
|
||||||
"hidden": true
|
"hidden": true
|
||||||
},
|
},
|
||||||
"jest-project": {
|
"jest-project": {
|
||||||
|
|||||||
@ -12,7 +12,7 @@ describe('jest', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should generate files', async () => {
|
it('should generate files', async () => {
|
||||||
const resultTree = await runSchematic('ng-add', {}, appTree);
|
const resultTree = await runSchematic('init', {}, appTree);
|
||||||
expect(resultTree.exists('jest.config.js')).toBeTruthy();
|
expect(resultTree.exists('jest.config.js')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ describe('jest', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should add dependencies', async () => {
|
it('should add dependencies', async () => {
|
||||||
const resultTree = await runSchematic('ng-add', {}, appTree);
|
const resultTree = await runSchematic('init', {}, appTree);
|
||||||
const packageJson = readJsonInTree(resultTree, 'package.json');
|
const packageJson = readJsonInTree(resultTree, 'package.json');
|
||||||
expect(packageJson.devDependencies.jest).toBeDefined();
|
expect(packageJson.devDependencies.jest).toBeDefined();
|
||||||
expect(packageJson.devDependencies['@nrwl/jest']).toBeDefined();
|
expect(packageJson.devDependencies['@nrwl/jest']).toBeDefined();
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/schema",
|
"$schema": "http://json-schema.org/schema",
|
||||||
"id": "NxJestNgAdd",
|
"id": "NxJestInit",
|
||||||
"title": "Add Jest Configuration to a workspace",
|
"title": "Add Jest Configuration to a workspace",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {},
|
"properties": {},
|
||||||
@ -19,7 +19,7 @@ import {
|
|||||||
import { getProjectConfig, addDepsToPackageJson } from '@nrwl/workspace';
|
import { getProjectConfig, addDepsToPackageJson } from '@nrwl/workspace';
|
||||||
import { offsetFromRoot } from '@nrwl/workspace';
|
import { offsetFromRoot } from '@nrwl/workspace';
|
||||||
import { join, normalize } from '@angular-devkit/core';
|
import { join, normalize } from '@angular-devkit/core';
|
||||||
import ngAdd from '../ng-add/ng-add';
|
import init from '../init/init';
|
||||||
|
|
||||||
export interface JestProjectSchema {
|
export interface JestProjectSchema {
|
||||||
project: string;
|
project: string;
|
||||||
@ -125,7 +125,7 @@ function normalizeOptions(options: JestProjectSchema): JestProjectSchema {
|
|||||||
export default function(options: JestProjectSchema): Rule {
|
export default function(options: JestProjectSchema): Rule {
|
||||||
options = normalizeOptions(options);
|
options = normalizeOptions(options);
|
||||||
return chain([
|
return chain([
|
||||||
ngAdd(),
|
init(),
|
||||||
check(options),
|
check(options),
|
||||||
generateFiles(options),
|
generateFiles(options),
|
||||||
updateTsConfig(options),
|
updateTsConfig(options),
|
||||||
|
|||||||
@ -3,10 +3,11 @@
|
|||||||
"version": "0.1",
|
"version": "0.1",
|
||||||
"extends": ["@nrwl/workspace"],
|
"extends": ["@nrwl/workspace"],
|
||||||
"schematics": {
|
"schematics": {
|
||||||
"ng-add": {
|
"init": {
|
||||||
"factory": "./src/schematics/ng-add/ng-add",
|
"factory": "./src/schematics/init/init",
|
||||||
"schema": "./src/schematics/ng-add/schema.json",
|
"schema": "./src/schematics/init/schema.json",
|
||||||
"description": "Add @nrwl/nest to a project",
|
"description": "Initialize the @nrwl/nest plugin",
|
||||||
|
"aliases": ["ng-add"],
|
||||||
"hidden": true
|
"hidden": true
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import {
|
|||||||
import { join, normalize, Path } from '@angular-devkit/core';
|
import { join, normalize, Path } from '@angular-devkit/core';
|
||||||
import { Schema } from './schema';
|
import { Schema } from './schema';
|
||||||
import { toFileName } from '@nrwl/workspace';
|
import { toFileName } from '@nrwl/workspace';
|
||||||
import ngAdd from '../ng-add/ng-add';
|
import init from '../init/init';
|
||||||
|
|
||||||
interface NormalizedSchema extends Schema {
|
interface NormalizedSchema extends Schema {
|
||||||
appProjectRoot: Path;
|
appProjectRoot: Path;
|
||||||
@ -65,7 +65,7 @@ export default function(schema: Schema): Rule {
|
|||||||
return (host: Tree, context: SchematicContext) => {
|
return (host: Tree, context: SchematicContext) => {
|
||||||
const options = normalizeOptions(schema);
|
const options = normalizeOptions(schema);
|
||||||
return chain([
|
return chain([
|
||||||
ngAdd({
|
init({
|
||||||
skipFormat: true
|
skipFormat: true
|
||||||
}),
|
}),
|
||||||
externalSchematic('@nrwl/node', 'application', schema),
|
externalSchematic('@nrwl/node', 'application', schema),
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { createEmptyWorkspace } from '@nrwl/workspace/testing';
|
|||||||
import { readJsonInTree, updateJsonInTree } from '@nrwl/workspace';
|
import { readJsonInTree, updateJsonInTree } from '@nrwl/workspace';
|
||||||
import { runSchematic, callRule } from '../../utils/testing';
|
import { runSchematic, callRule } from '../../utils/testing';
|
||||||
|
|
||||||
describe('ng-add', () => {
|
describe('init', () => {
|
||||||
let tree: Tree;
|
let tree: Tree;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -12,7 +12,7 @@ describe('ng-add', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should add dependencies', async () => {
|
it('should add dependencies', async () => {
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const packageJson = readJsonInTree(result, 'package.json');
|
const packageJson = readJsonInTree(result, 'package.json');
|
||||||
|
|
||||||
expect(packageJson.dependencies['@nrwl/nest']).toBeUndefined();
|
expect(packageJson.dependencies['@nrwl/nest']).toBeUndefined();
|
||||||
@ -22,7 +22,7 @@ describe('ng-add', () => {
|
|||||||
|
|
||||||
describe('defaultCollection', () => {
|
describe('defaultCollection', () => {
|
||||||
it('should be set if none was set before', async () => {
|
it('should be set if none was set before', async () => {
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/nest');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/nest');
|
||||||
});
|
});
|
||||||
@ -38,7 +38,7 @@ describe('ng-add', () => {
|
|||||||
}),
|
}),
|
||||||
tree
|
tree
|
||||||
);
|
);
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/nest');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/nest');
|
||||||
});
|
});
|
||||||
@ -54,7 +54,7 @@ describe('ng-add', () => {
|
|||||||
}),
|
}),
|
||||||
tree
|
tree
|
||||||
);
|
);
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/angular');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/angular');
|
||||||
});
|
});
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { chain, Rule } from '@angular-devkit/schematics';
|
import { chain, Rule } from '@angular-devkit/schematics';
|
||||||
import {
|
import {
|
||||||
addDepsToPackageJson,
|
addDepsToPackageJson,
|
||||||
addPackageWithNgAdd,
|
addPackageWithInit,
|
||||||
formatFiles,
|
formatFiles,
|
||||||
updateJsonInTree,
|
updateJsonInTree,
|
||||||
updateWorkspace
|
updateWorkspace
|
||||||
@ -57,8 +57,8 @@ function setDefault(): Rule {
|
|||||||
export default function(schema: Schema) {
|
export default function(schema: Schema) {
|
||||||
return chain([
|
return chain([
|
||||||
setDefault(),
|
setDefault(),
|
||||||
addPackageWithNgAdd('@nrwl/node'),
|
addPackageWithInit('@nrwl/node'),
|
||||||
addPackageWithNgAdd('@nrwl/jest'),
|
addPackageWithInit('@nrwl/jest'),
|
||||||
addDependencies(),
|
addDependencies(),
|
||||||
moveDependency(),
|
moveDependency(),
|
||||||
formatFiles(schema)
|
formatFiles(schema)
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/schema",
|
"$schema": "http://json-schema.org/schema",
|
||||||
"id": "NxNestNgAdd",
|
"id": "NxNestInit",
|
||||||
"title": "Add Nx Nest Schematics",
|
"title": "Add Nx Nest Schematics",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
20
packages/next/builders.json
Normal file
20
packages/next/builders.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"$schema": "@angular-devkit/architect/src/builders-schema.json",
|
||||||
|
"builders": {
|
||||||
|
"build": {
|
||||||
|
"implementation": "./src/builders/build/build.impl",
|
||||||
|
"schema": "./src/builders/build/schema.json",
|
||||||
|
"description": "Build a Next.js app"
|
||||||
|
},
|
||||||
|
"dev-server": {
|
||||||
|
"implementation": "./src/builders/dev-server/dev-server.impl",
|
||||||
|
"schema": "./src/builders/dev-server/schema.json",
|
||||||
|
"description": "Serve a Next.js app"
|
||||||
|
},
|
||||||
|
"export": {
|
||||||
|
"implementation": "./src/builders/export/export.impl",
|
||||||
|
"schema": "./src/builders/export/schema.json",
|
||||||
|
"description": "Export a Next.js app"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
packages/next/collection.json
Normal file
20
packages/next/collection.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "nx/nest",
|
||||||
|
"version": "0.1",
|
||||||
|
"extends": ["@nrwl/react"],
|
||||||
|
"schematics": {
|
||||||
|
"init": {
|
||||||
|
"factory": "./src/schematics/init/init",
|
||||||
|
"schema": "./src/schematics/init/schema.json",
|
||||||
|
"description": "Initialize the @nrwl/next plugin",
|
||||||
|
"hidden": true
|
||||||
|
},
|
||||||
|
|
||||||
|
"application": {
|
||||||
|
"factory": "./src/schematics/application/application",
|
||||||
|
"schema": "./src/schematics/application/schema.json",
|
||||||
|
"aliases": ["app"],
|
||||||
|
"description": "Create a Next.js application"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
packages/next/migrations.json
Normal file
3
packages/next/migrations.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"schematics": {}
|
||||||
|
}
|
||||||
38
packages/next/package.json
Normal file
38
packages/next/package.json
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"name": "@nrwl/next",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "Next.js Plugin for Nx",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/nrwl/nx.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"Monorepo",
|
||||||
|
"Node",
|
||||||
|
"Next",
|
||||||
|
"Jest",
|
||||||
|
"Cypress",
|
||||||
|
"CLI"
|
||||||
|
],
|
||||||
|
"main": "index.js",
|
||||||
|
"types": "index.d.ts",
|
||||||
|
"author": "Victor Savkin",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/nrwl/nx/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://nx.dev",
|
||||||
|
"schematics": "./collection.json",
|
||||||
|
"builders": "./builders.json",
|
||||||
|
"ng-update": {
|
||||||
|
"requirements": {},
|
||||||
|
"migrations": "./migrations.json"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@nrwl/workspace": "*"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@nrwl/react": "*",
|
||||||
|
"@angular-devkit/schematics": "8.1.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
37
packages/next/src/builders/build/build.impl.ts
Normal file
37
packages/next/src/builders/build/build.impl.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import {
|
||||||
|
BuilderContext,
|
||||||
|
BuilderOutput,
|
||||||
|
createBuilder
|
||||||
|
} from '@angular-devkit/architect';
|
||||||
|
import { JsonObject } from '@angular-devkit/core';
|
||||||
|
import { PHASE_PRODUCTION_BUILD } from 'next-server/constants';
|
||||||
|
import build from 'next/dist/build';
|
||||||
|
import * as path from 'path';
|
||||||
|
import { from, Observable } from 'rxjs';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
import { prepareConfig } from '../../utils/config';
|
||||||
|
|
||||||
|
try {
|
||||||
|
require('dotenv').config();
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
export interface NextBuildBuilderOptions extends JsonObject {
|
||||||
|
root: string;
|
||||||
|
outputPath: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default createBuilder<NextBuildBuilderOptions>(run);
|
||||||
|
|
||||||
|
function run(
|
||||||
|
options: NextBuildBuilderOptions,
|
||||||
|
context: BuilderContext
|
||||||
|
): Observable<BuilderOutput> {
|
||||||
|
const root = path.resolve(context.workspaceRoot, options.root);
|
||||||
|
const config = prepareConfig(
|
||||||
|
context.workspaceRoot,
|
||||||
|
options.root,
|
||||||
|
options.outputPath,
|
||||||
|
PHASE_PRODUCTION_BUILD
|
||||||
|
);
|
||||||
|
return from(build(root, config as any)).pipe(map(() => ({ success: true })));
|
||||||
|
}
|
||||||
7
packages/next/src/builders/build/schema.json
Normal file
7
packages/next/src/builders/build/schema.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"title": "Next Build",
|
||||||
|
"description": "Build a Next.js app",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {},
|
||||||
|
"required": []
|
||||||
|
}
|
||||||
72
packages/next/src/builders/dev-server/dev-server.impl.ts
Normal file
72
packages/next/src/builders/dev-server/dev-server.impl.ts
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import {
|
||||||
|
BuilderContext,
|
||||||
|
BuilderOutput,
|
||||||
|
createBuilder,
|
||||||
|
targetFromTargetString,
|
||||||
|
scheduleTargetAndForget
|
||||||
|
} from '@angular-devkit/architect';
|
||||||
|
import { JsonObject } from '@angular-devkit/core';
|
||||||
|
import {
|
||||||
|
PHASE_DEVELOPMENT_SERVER,
|
||||||
|
PHASE_PRODUCTION_SERVER
|
||||||
|
} from 'next-server/constants';
|
||||||
|
import startServer from 'next/dist/server/lib/start-server';
|
||||||
|
import * as path from 'path';
|
||||||
|
import { from, Observable, of } from 'rxjs';
|
||||||
|
import { switchMap, concatMap } from 'rxjs/operators';
|
||||||
|
import { prepareConfig } from '../../utils/config';
|
||||||
|
|
||||||
|
try {
|
||||||
|
require('dotenv').config();
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
export interface NextBuildBuilderOptions extends JsonObject {
|
||||||
|
dev: boolean;
|
||||||
|
port: number;
|
||||||
|
staticMarkup: boolean;
|
||||||
|
quiet: boolean;
|
||||||
|
buildTarget: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default createBuilder<NextBuildBuilderOptions>(run);
|
||||||
|
|
||||||
|
function run(
|
||||||
|
options: NextBuildBuilderOptions,
|
||||||
|
context: BuilderContext
|
||||||
|
): Observable<BuilderOutput> {
|
||||||
|
const buildTarget = targetFromTargetString(options.buildTarget);
|
||||||
|
|
||||||
|
const build$ = !options.dev
|
||||||
|
? scheduleTargetAndForget(context, buildTarget)
|
||||||
|
: of({ success: true });
|
||||||
|
|
||||||
|
return build$.pipe(
|
||||||
|
concatMap(r => {
|
||||||
|
if (!r.success) return of(r);
|
||||||
|
return from(context.getTargetOptions(buildTarget)).pipe(
|
||||||
|
concatMap((buildOptions: any) => {
|
||||||
|
const root = path.resolve(context.workspaceRoot, buildOptions.root);
|
||||||
|
const config = prepareConfig(
|
||||||
|
context.workspaceRoot,
|
||||||
|
buildOptions.root,
|
||||||
|
buildOptions.outputPath,
|
||||||
|
options.dev ? PHASE_DEVELOPMENT_SERVER : PHASE_PRODUCTION_SERVER
|
||||||
|
);
|
||||||
|
|
||||||
|
return from(
|
||||||
|
startServer(
|
||||||
|
{
|
||||||
|
dev: options.dev,
|
||||||
|
dir: root,
|
||||||
|
staticMarkup: options.staticMarkup,
|
||||||
|
quiet: options.quiet,
|
||||||
|
conf: config
|
||||||
|
} as any,
|
||||||
|
options.port
|
||||||
|
).then(app => app.prepare())
|
||||||
|
).pipe(switchMap(e => new Observable<BuilderOutput>(obs => {})));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
32
packages/next/src/builders/dev-server/schema.json
Normal file
32
packages/next/src/builders/dev-server/schema.json
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"title": "Next Serve",
|
||||||
|
"description": "Serve a Next.js app",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"dev": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Serve the application in the dev mode",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"buildTarget": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Target which builds the application"
|
||||||
|
},
|
||||||
|
"port": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "Port to listen on.",
|
||||||
|
"default": 4200
|
||||||
|
},
|
||||||
|
"staticMarkup": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Static markup.",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"quiet": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Hide error messages containing server information.",
|
||||||
|
"default": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": []
|
||||||
|
}
|
||||||
64
packages/next/src/builders/export/export.impl.ts
Normal file
64
packages/next/src/builders/export/export.impl.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import {
|
||||||
|
BuilderContext,
|
||||||
|
BuilderOutput,
|
||||||
|
createBuilder,
|
||||||
|
targetFromTargetString,
|
||||||
|
scheduleTargetAndForget
|
||||||
|
} from '@angular-devkit/architect';
|
||||||
|
import { JsonObject } from '@angular-devkit/core';
|
||||||
|
import { PHASE_EXPORT } from 'next-server/constants';
|
||||||
|
import exportApp from 'next/dist/export';
|
||||||
|
import * as path from 'path';
|
||||||
|
import { from, Observable, of } from 'rxjs';
|
||||||
|
import { map, concatMap } from 'rxjs/operators';
|
||||||
|
import { prepareConfig } from '../../utils/config';
|
||||||
|
|
||||||
|
try {
|
||||||
|
require('dotenv').config();
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
export interface NextBuildBuilderOptions extends JsonObject {
|
||||||
|
buildTarget: string;
|
||||||
|
silent: boolean;
|
||||||
|
threads: number;
|
||||||
|
concurrency: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default createBuilder<NextBuildBuilderOptions>(run);
|
||||||
|
|
||||||
|
function run(
|
||||||
|
options: NextBuildBuilderOptions,
|
||||||
|
context: BuilderContext
|
||||||
|
): Observable<BuilderOutput> {
|
||||||
|
const buildTarget = targetFromTargetString(options.buildTarget);
|
||||||
|
const build$ = scheduleTargetAndForget(context, buildTarget);
|
||||||
|
|
||||||
|
return build$.pipe(
|
||||||
|
concatMap(r => {
|
||||||
|
if (!r.success) return of(r);
|
||||||
|
return from(context.getTargetOptions(buildTarget)).pipe(
|
||||||
|
concatMap((buildOptions: any) => {
|
||||||
|
const root = path.resolve(context.workspaceRoot, buildOptions.root);
|
||||||
|
const config = prepareConfig(
|
||||||
|
context.workspaceRoot,
|
||||||
|
buildOptions.root,
|
||||||
|
buildOptions.outputPath,
|
||||||
|
PHASE_EXPORT
|
||||||
|
);
|
||||||
|
return from(
|
||||||
|
exportApp(
|
||||||
|
root,
|
||||||
|
{
|
||||||
|
silent: options.silent,
|
||||||
|
threads: options.threads,
|
||||||
|
concurrency: options.concurrency,
|
||||||
|
outdir: `${buildOptions.outputPath}/exported`
|
||||||
|
} as any,
|
||||||
|
config
|
||||||
|
)
|
||||||
|
).pipe(map(() => ({ success: true })));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
7
packages/next/src/builders/export/schema.json
Normal file
7
packages/next/src/builders/export/schema.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"title": "Next Export",
|
||||||
|
"description": "Export a Next.js app",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {},
|
||||||
|
"required": []
|
||||||
|
}
|
||||||
289
packages/next/src/schematics/application/application.spec.ts
Normal file
289
packages/next/src/schematics/application/application.spec.ts
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
import { Tree } from '@angular-devkit/schematics';
|
||||||
|
import { createEmptyWorkspace } from '@nrwl/workspace/testing';
|
||||||
|
import { readJsonInTree, NxJson } from '@nrwl/workspace';
|
||||||
|
import { runSchematic } from '../../utils/testing';
|
||||||
|
|
||||||
|
describe('app', () => {
|
||||||
|
let appTree: Tree;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
appTree = Tree.empty();
|
||||||
|
appTree = createEmptyWorkspace(appTree);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('not nested', () => {
|
||||||
|
it('should update workspace.json', async () => {
|
||||||
|
const tree = await runSchematic('app', { name: 'myApp' }, appTree);
|
||||||
|
const workspaceJson = readJsonInTree(tree, '/workspace.json');
|
||||||
|
|
||||||
|
expect(workspaceJson.projects['my-app'].root).toEqual('apps/my-app');
|
||||||
|
expect(workspaceJson.projects['my-app-e2e'].root).toEqual(
|
||||||
|
'apps/my-app-e2e'
|
||||||
|
);
|
||||||
|
expect(workspaceJson.defaultProject).toEqual('my-app');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update nx.json', async () => {
|
||||||
|
const tree = await runSchematic(
|
||||||
|
'app',
|
||||||
|
{ name: 'myApp', tags: 'one,two' },
|
||||||
|
appTree
|
||||||
|
);
|
||||||
|
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
||||||
|
expect(nxJson).toEqual({
|
||||||
|
npmScope: 'proj',
|
||||||
|
projects: {
|
||||||
|
'my-app': {
|
||||||
|
tags: ['one', 'two']
|
||||||
|
},
|
||||||
|
'my-app-e2e': {
|
||||||
|
tags: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should generate files', async () => {
|
||||||
|
const tree = await runSchematic('app', { name: 'myApp' }, appTree);
|
||||||
|
expect(tree.exists('apps/my-app/tsconfig.json')).toBeTruthy();
|
||||||
|
expect(tree.exists('apps/my-app/pages/index.tsx')).toBeTruthy();
|
||||||
|
expect(tree.exists('apps/my-app/specs/index.spec.tsx')).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('--style scss', () => {
|
||||||
|
it('should generate scss styles', async () => {
|
||||||
|
const result = await runSchematic(
|
||||||
|
'app',
|
||||||
|
{ name: 'myApp', style: 'scss' },
|
||||||
|
appTree
|
||||||
|
);
|
||||||
|
expect(result.exists('apps/my-app/pages/index.scss')).toEqual(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should setup jest with tsx support', async () => {
|
||||||
|
const tree = await runSchematic(
|
||||||
|
'app',
|
||||||
|
{
|
||||||
|
name: 'my-app'
|
||||||
|
},
|
||||||
|
appTree
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(tree.readContent('apps/my-app/jest.config.js')).toContain(
|
||||||
|
`moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set up the nrwl next build builder', async () => {
|
||||||
|
const tree = await runSchematic(
|
||||||
|
'app',
|
||||||
|
{
|
||||||
|
name: 'my-app'
|
||||||
|
},
|
||||||
|
appTree
|
||||||
|
);
|
||||||
|
const workspaceJson = readJsonInTree(tree, 'workspace.json');
|
||||||
|
const architectConfig = workspaceJson.projects['my-app'].architect;
|
||||||
|
expect(architectConfig.build.builder).toEqual('@nrwl/next:build');
|
||||||
|
expect(architectConfig.build.options).toEqual({
|
||||||
|
root: 'apps/my-app',
|
||||||
|
outputPath: 'dist/apps/my-app'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set up the nrwl next dev exportr builder', async () => {
|
||||||
|
const tree = await runSchematic(
|
||||||
|
'app',
|
||||||
|
{
|
||||||
|
name: 'my-app'
|
||||||
|
},
|
||||||
|
appTree
|
||||||
|
);
|
||||||
|
const workspaceJson = readJsonInTree(tree, 'workspace.json');
|
||||||
|
const architectConfig = workspaceJson.projects['my-app'].architect;
|
||||||
|
expect(architectConfig.serve.builder).toEqual('@nrwl/next:dev-server');
|
||||||
|
expect(architectConfig.serve.options).toEqual({
|
||||||
|
buildTarget: 'my-app:build',
|
||||||
|
dev: true
|
||||||
|
});
|
||||||
|
expect(architectConfig.serve.configurations).toEqual({
|
||||||
|
production: { dev: false }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set up the nrwl next export builder', async () => {
|
||||||
|
const tree = await runSchematic(
|
||||||
|
'app',
|
||||||
|
{
|
||||||
|
name: 'my-app'
|
||||||
|
},
|
||||||
|
appTree
|
||||||
|
);
|
||||||
|
const workspaceJson = readJsonInTree(tree, 'workspace.json');
|
||||||
|
const architectConfig = workspaceJson.projects['my-app'].architect;
|
||||||
|
expect(architectConfig.export.builder).toEqual('@nrwl/next:export');
|
||||||
|
expect(architectConfig.export.options).toEqual({
|
||||||
|
buildTarget: 'my-app:build'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('--unit-test-runner none', () => {
|
||||||
|
it('should not generate test configuration', async () => {
|
||||||
|
const tree = await runSchematic(
|
||||||
|
'app',
|
||||||
|
{ name: 'myApp', unitTestRunner: 'none' },
|
||||||
|
appTree
|
||||||
|
);
|
||||||
|
expect(tree.exists('apps/my-app/specs/index.spec.tsx')).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('--e2e-test-runner none', () => {
|
||||||
|
it('should not generate test configuration', async () => {
|
||||||
|
const tree = await runSchematic(
|
||||||
|
'app',
|
||||||
|
{ name: 'myApp', e2eTestRunner: 'none' },
|
||||||
|
appTree
|
||||||
|
);
|
||||||
|
expect(tree.exists('apps/my-app-e2e')).toBeFalsy();
|
||||||
|
const workspaceJson = readJsonInTree(tree, 'workspace.json');
|
||||||
|
expect(workspaceJson.projects['my-app-e2e']).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('--pascalCaseFiles', () => {
|
||||||
|
it('should use upper case app file', async () => {
|
||||||
|
const tree = await runSchematic(
|
||||||
|
'app',
|
||||||
|
{ name: 'myApp', pascalCaseFiles: true },
|
||||||
|
appTree
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(tree.exists('apps/my-app/pages/Index.tsx')).toBeTruthy();
|
||||||
|
expect(tree.exists('apps/my-app/specs/Index.spec.tsx')).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should generate functional components by default', async () => {
|
||||||
|
const tree = await runSchematic('app', { name: 'myApp' }, appTree);
|
||||||
|
|
||||||
|
const appContent = tree.read('apps/my-app/pages/index.tsx').toString();
|
||||||
|
|
||||||
|
expect(appContent).not.toMatch(/extends Component/);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('--class-component', () => {
|
||||||
|
it('should generate class components', async () => {
|
||||||
|
const tree = await runSchematic(
|
||||||
|
'app',
|
||||||
|
{ name: 'myApp', classComponent: true },
|
||||||
|
appTree
|
||||||
|
);
|
||||||
|
|
||||||
|
const appContent = tree.read('apps/my-app/pages/index.tsx').toString();
|
||||||
|
|
||||||
|
expect(appContent).toMatch(/extends Component/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// uncomment
|
||||||
|
// describe('--style styled-components', () => {
|
||||||
|
// it('should use styled-components as the styled API library', async () => {
|
||||||
|
// const tree = await runSchematic(
|
||||||
|
// 'app',
|
||||||
|
// { name: 'myApp', style: 'styled-components' },
|
||||||
|
// appTree
|
||||||
|
// );
|
||||||
|
|
||||||
|
// expect(
|
||||||
|
// tree.exists('apps/my-app/src/app/app.styled-components')
|
||||||
|
// ).toBeFalsy();
|
||||||
|
// expect(tree.exists('apps/my-app/src/app/app.tsx')).toBeTruthy();
|
||||||
|
|
||||||
|
// const content = tree.read('apps/my-app/src/app/app.tsx').toString();
|
||||||
|
// expect(content).toContain('styled-component');
|
||||||
|
// expect(content).toContain('<StyledApp>');
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it('should add dependencies to package.json', async () => {
|
||||||
|
// const tree = await runSchematic(
|
||||||
|
// 'app',
|
||||||
|
// { name: 'myApp', style: 'styled-components' },
|
||||||
|
// appTree
|
||||||
|
// );
|
||||||
|
|
||||||
|
// const packageJSON = readJsonInTree(tree, 'package.json');
|
||||||
|
// expect(packageJSON.dependencies['styled-components']).toBeDefined();
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
// describe('--style @emotion/styled', () => {
|
||||||
|
// it('should use @emotion/styled as the styled API library', async () => {
|
||||||
|
// const tree = await runSchematic(
|
||||||
|
// 'app',
|
||||||
|
// { name: 'myApp', style: '@emotion/styled' },
|
||||||
|
// appTree
|
||||||
|
// );
|
||||||
|
|
||||||
|
// expect(
|
||||||
|
// tree.exists('apps/my-app/src/app/app.@emotion/styled')
|
||||||
|
// ).toBeFalsy();
|
||||||
|
// expect(tree.exists('apps/my-app/src/app/app.tsx')).toBeTruthy();
|
||||||
|
|
||||||
|
// const content = tree.read('apps/my-app/src/app/app.tsx').toString();
|
||||||
|
// expect(content).toContain('@emotion/styled');
|
||||||
|
// expect(content).toContain('<StyledApp>');
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it('should exclude styles from workspace.json', async () => {
|
||||||
|
// const tree = await runSchematic(
|
||||||
|
// 'app',
|
||||||
|
// { name: 'myApp', style: '@emotion/styled' },
|
||||||
|
// appTree
|
||||||
|
// );
|
||||||
|
|
||||||
|
// const workspaceJson = readJsonInTree(tree, 'workspace.json');
|
||||||
|
|
||||||
|
// expect(
|
||||||
|
// workspaceJson.projects['my-app'].architect.build.options.styles
|
||||||
|
// ).toEqual([]);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// it('should add dependencies to package.json', async () => {
|
||||||
|
// const tree = await runSchematic(
|
||||||
|
// 'app',
|
||||||
|
// { name: 'myApp', style: '@emotion/styled' },
|
||||||
|
// appTree
|
||||||
|
// );
|
||||||
|
|
||||||
|
// const packageJSON = readJsonInTree(tree, 'package.json');
|
||||||
|
// expect(packageJSON.dependencies['@emotion/core']).toBeDefined();
|
||||||
|
// expect(packageJSON.dependencies['@emotion/styled']).toBeDefined();
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
describe('--linter=eslint', () => {
|
||||||
|
it('should add .eslintrc and dependencies', async () => {
|
||||||
|
const tree = await runSchematic(
|
||||||
|
'app',
|
||||||
|
{ name: 'myApp', linter: 'eslint' },
|
||||||
|
appTree
|
||||||
|
);
|
||||||
|
|
||||||
|
const eslintJson = readJsonInTree(tree, '/apps/my-app/.eslintrc');
|
||||||
|
const packageJson = readJsonInTree(tree, '/package.json');
|
||||||
|
|
||||||
|
expect(eslintJson.plugins).toEqual(
|
||||||
|
expect.arrayContaining(['react', 'react-hooks'])
|
||||||
|
);
|
||||||
|
expect(packageJson).toMatchObject({
|
||||||
|
devDependencies: {
|
||||||
|
'eslint-plugin-react': expect.anything(),
|
||||||
|
'eslint-plugin-react-hooks': expect.anything()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
259
packages/next/src/schematics/application/application.ts
Normal file
259
packages/next/src/schematics/application/application.ts
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
import { join, JsonObject, normalize, Path } from '@angular-devkit/core';
|
||||||
|
import {
|
||||||
|
apply,
|
||||||
|
chain,
|
||||||
|
externalSchematic,
|
||||||
|
filter,
|
||||||
|
mergeWith,
|
||||||
|
move,
|
||||||
|
noop,
|
||||||
|
Rule,
|
||||||
|
SchematicContext,
|
||||||
|
template,
|
||||||
|
Tree,
|
||||||
|
url
|
||||||
|
} from '@angular-devkit/schematics';
|
||||||
|
import {
|
||||||
|
assertValidStyle,
|
||||||
|
extraEslintDependencies,
|
||||||
|
reactEslintJson,
|
||||||
|
CSS_IN_JS_DEPENDENCIES
|
||||||
|
} from '@nrwl/react';
|
||||||
|
import {
|
||||||
|
addLintFiles,
|
||||||
|
formatFiles,
|
||||||
|
generateProjectLint,
|
||||||
|
names,
|
||||||
|
NxJson,
|
||||||
|
offsetFromRoot,
|
||||||
|
toFileName,
|
||||||
|
updateJsonInTree,
|
||||||
|
updateWorkspace
|
||||||
|
} from '@nrwl/workspace';
|
||||||
|
import {
|
||||||
|
updateWorkspaceInTree,
|
||||||
|
addDepsToPackageJson
|
||||||
|
} from '@nrwl/workspace/src/utils/ast-utils';
|
||||||
|
import init from '../init/init';
|
||||||
|
import { Schema } from './schema';
|
||||||
|
|
||||||
|
interface NormalizedSchema extends Schema {
|
||||||
|
projectName: string;
|
||||||
|
appProjectRoot: Path;
|
||||||
|
e2eProjectName: string;
|
||||||
|
e2eProjectRoot: Path;
|
||||||
|
parsedTags: string[];
|
||||||
|
fileName: string;
|
||||||
|
styledModule: null | string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function(schema: Schema): Rule {
|
||||||
|
return (host: Tree, context: SchematicContext) => {
|
||||||
|
const options = normalizeOptions(host, schema);
|
||||||
|
|
||||||
|
return chain([
|
||||||
|
init({
|
||||||
|
skipFormat: true
|
||||||
|
}),
|
||||||
|
addLintFiles(options.appProjectRoot, options.linter, {
|
||||||
|
localConfig: reactEslintJson,
|
||||||
|
extraPackageDeps: extraEslintDependencies
|
||||||
|
}),
|
||||||
|
createApplicationFiles(options),
|
||||||
|
updateNxJson(options),
|
||||||
|
addProject(options),
|
||||||
|
addCypress(options),
|
||||||
|
addJest(options),
|
||||||
|
addStyledModuleDependencies(options),
|
||||||
|
setDefaults(options),
|
||||||
|
formatFiles(options)
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function createApplicationFiles(options: NormalizedSchema): Rule {
|
||||||
|
return mergeWith(
|
||||||
|
apply(url(`./files`), [
|
||||||
|
template({
|
||||||
|
...names(options.name),
|
||||||
|
...options,
|
||||||
|
tmpl: '',
|
||||||
|
offsetFromRoot: offsetFromRoot(options.appProjectRoot)
|
||||||
|
}),
|
||||||
|
options.styledModule
|
||||||
|
? filter(file => !file.endsWith(`.${options.style}`))
|
||||||
|
: noop(),
|
||||||
|
options.unitTestRunner === 'none'
|
||||||
|
? filter(file => file !== `/specs/index.spec.tsx`)
|
||||||
|
: noop(),
|
||||||
|
move(options.appProjectRoot)
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateNxJson(options: NormalizedSchema): Rule {
|
||||||
|
return updateJsonInTree<NxJson>('nx.json', json => {
|
||||||
|
json.projects[options.projectName] = { tags: options.parsedTags };
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addProject(options: NormalizedSchema): Rule {
|
||||||
|
return updateWorkspaceInTree(json => {
|
||||||
|
const architect: { [key: string]: any } = {};
|
||||||
|
|
||||||
|
architect.build = {
|
||||||
|
builder: '@nrwl/next:build',
|
||||||
|
options: {
|
||||||
|
root: options.appProjectRoot,
|
||||||
|
outputPath: join(normalize('dist'), options.appProjectRoot)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
architect.serve = {
|
||||||
|
builder: '@nrwl/next:dev-server',
|
||||||
|
options: {
|
||||||
|
buildTarget: `${options.projectName}:build`,
|
||||||
|
dev: true
|
||||||
|
},
|
||||||
|
configurations: {
|
||||||
|
production: {
|
||||||
|
dev: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
architect.export = {
|
||||||
|
builder: '@nrwl/next:export',
|
||||||
|
options: {
|
||||||
|
buildTarget: `${options.projectName}:build`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
architect.lint = generateProjectLint(
|
||||||
|
normalize(options.appProjectRoot),
|
||||||
|
join(normalize(options.appProjectRoot), 'tsconfig.json'),
|
||||||
|
options.linter
|
||||||
|
);
|
||||||
|
|
||||||
|
json.projects[options.projectName] = {
|
||||||
|
root: options.appProjectRoot,
|
||||||
|
sourceRoot: options.appProjectRoot,
|
||||||
|
projectType: 'application',
|
||||||
|
schematics: {},
|
||||||
|
architect
|
||||||
|
};
|
||||||
|
|
||||||
|
json.defaultProject = json.defaultProject || options.projectName;
|
||||||
|
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addCypress(options: NormalizedSchema): Rule {
|
||||||
|
return options.e2eTestRunner === 'cypress'
|
||||||
|
? externalSchematic('@nrwl/cypress', 'cypress-project', {
|
||||||
|
...options,
|
||||||
|
name: options.name + '-e2e',
|
||||||
|
directory: options.directory,
|
||||||
|
project: options.projectName
|
||||||
|
})
|
||||||
|
: noop();
|
||||||
|
}
|
||||||
|
|
||||||
|
function addJest(options: NormalizedSchema): Rule {
|
||||||
|
return options.unitTestRunner === 'jest'
|
||||||
|
? chain([
|
||||||
|
externalSchematic('@nrwl/jest', 'jest-project', {
|
||||||
|
project: options.projectName,
|
||||||
|
supportTsx: true,
|
||||||
|
skipSerializers: true,
|
||||||
|
setupFile: 'none'
|
||||||
|
}),
|
||||||
|
updateJsonInTree(
|
||||||
|
`${options.appProjectRoot}/tsconfig.spec.json`,
|
||||||
|
json => {
|
||||||
|
json.compilerOptions.jsx = 'react';
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
])
|
||||||
|
: noop();
|
||||||
|
}
|
||||||
|
|
||||||
|
function addStyledModuleDependencies(options: NormalizedSchema): Rule {
|
||||||
|
const extraDependencies = CSS_IN_JS_DEPENDENCIES[options.styledModule];
|
||||||
|
return extraDependencies
|
||||||
|
? addDepsToPackageJson(
|
||||||
|
extraDependencies.dependencies,
|
||||||
|
extraDependencies.devDependencies
|
||||||
|
)
|
||||||
|
: noop();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDefaults(options: NormalizedSchema): Rule {
|
||||||
|
return options.skipWorkspaceJson
|
||||||
|
? noop()
|
||||||
|
: updateWorkspace(workspace => {
|
||||||
|
workspace.extensions.schematics = jsonIdentity(
|
||||||
|
workspace.extensions.schematics || {}
|
||||||
|
);
|
||||||
|
workspace.extensions.schematics['@nrwl/next'] =
|
||||||
|
workspace.extensions.schematics['@nrwl/next'] || {};
|
||||||
|
const prev = jsonIdentity(
|
||||||
|
workspace.extensions.schematics['@nrwl/next']
|
||||||
|
);
|
||||||
|
|
||||||
|
workspace.extensions.schematics = {
|
||||||
|
...workspace.extensions.schematics,
|
||||||
|
'@nrwl/next': {
|
||||||
|
...prev,
|
||||||
|
application: {
|
||||||
|
style: options.style,
|
||||||
|
linter: options.linter,
|
||||||
|
...jsonIdentity(prev.application)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function jsonIdentity(x: any): JsonObject {
|
||||||
|
return x as JsonObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
|
||||||
|
const appDirectory = options.directory
|
||||||
|
? `${toFileName(options.directory)}/${toFileName(options.name)}`
|
||||||
|
: toFileName(options.name);
|
||||||
|
|
||||||
|
const appProjectName = appDirectory.replace(new RegExp('/', 'g'), '-');
|
||||||
|
const e2eProjectName = `${appProjectName}-e2e`;
|
||||||
|
|
||||||
|
const appProjectRoot = normalize(`apps/${appDirectory}`);
|
||||||
|
const e2eProjectRoot = normalize(`apps/${appDirectory}-e2e`);
|
||||||
|
|
||||||
|
const parsedTags = options.tags
|
||||||
|
? options.tags.split(',').map(s => s.trim())
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const fileName = options.pascalCaseFiles ? 'Index' : 'index';
|
||||||
|
|
||||||
|
const styledModule = /^(css|scss|less|styl)$/.test(options.style)
|
||||||
|
? null
|
||||||
|
: options.style;
|
||||||
|
|
||||||
|
assertValidStyle(options.style);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...options,
|
||||||
|
name: toFileName(options.name),
|
||||||
|
projectName: appProjectName,
|
||||||
|
appProjectRoot,
|
||||||
|
e2eProjectRoot,
|
||||||
|
e2eProjectName,
|
||||||
|
parsedTags,
|
||||||
|
fileName,
|
||||||
|
styledModule
|
||||||
|
};
|
||||||
|
}
|
||||||
2
packages/next/src/schematics/application/files/next-env.d.ts
vendored
Normal file
2
packages/next/src/schematics/application/files/next-env.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/// <reference types="next" />
|
||||||
|
/// <reference types="next/types/global" />
|
||||||
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* Remove template code below
|
||||||
|
*/
|
||||||
|
|
||||||
|
.app {
|
||||||
|
font-family: sans-serif;
|
||||||
|
min-width: 300px;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 50px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app .gutter-left {
|
||||||
|
margin-left: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app .col-span-2 {
|
||||||
|
grid-column: span 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app .flex {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app header {
|
||||||
|
background-color: #143055;
|
||||||
|
color: white;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app main {
|
||||||
|
padding: 0 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app p {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app h1 {
|
||||||
|
text-align: center;
|
||||||
|
margin-left: 18px;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app h2 {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
margin: 40px 0 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app .resources {
|
||||||
|
text-align: center;
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 9px;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app .resource {
|
||||||
|
color: #0094ba;
|
||||||
|
height: 36px;
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 3px 9px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app .resource:hover {
|
||||||
|
background-color: rgba(68, 138, 255, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app pre {
|
||||||
|
padding: 9px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: black;
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app details {
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #333;
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
|
padding: 3px 9px;
|
||||||
|
margin-bottom: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app summary {
|
||||||
|
outline: none;
|
||||||
|
height: 36px;
|
||||||
|
line-height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app .github-star-container {
|
||||||
|
margin-top: 12px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app .github-star-container a {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app .github-star-badge {
|
||||||
|
color: #24292e;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 3px 10px;
|
||||||
|
border: 1px solid rgba(27,31,35,.2);
|
||||||
|
border-radius: 3px;
|
||||||
|
background-image: linear-gradient(-180deg,#fafbfc,#eff3f6 90%);
|
||||||
|
margin-left: 4px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app .github-star-badge:hover {
|
||||||
|
background-image: linear-gradient(-180deg,#f0f3f6,#e6ebf1 90%);
|
||||||
|
border-color: rgba(27,31,35,.35);
|
||||||
|
background-position: -.5em;
|
||||||
|
}
|
||||||
|
.app .github-star-badge .material-icons {
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
@ -0,0 +1,265 @@
|
|||||||
|
<% if (classComponent) { %>
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
<% } else { %>
|
||||||
|
import React from 'react';
|
||||||
|
<% } %>
|
||||||
|
<% if (styledModule) {
|
||||||
|
var wrapper = 'StyledApp';
|
||||||
|
%>import styled from '<%= styledModule %>';<% } else {
|
||||||
|
var wrapper = 'div';
|
||||||
|
%>
|
||||||
|
|
||||||
|
import './<%= fileName %>.<%= style %>';
|
||||||
|
|
||||||
|
<% }
|
||||||
|
%>
|
||||||
|
|
||||||
|
<% if (styledModule) { %>
|
||||||
|
const StyledApp = styled.div`
|
||||||
|
/*
|
||||||
|
* Remove template code below
|
||||||
|
*/
|
||||||
|
|
||||||
|
font-family: sans-serif;
|
||||||
|
min-width: 300px;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 50px auto;
|
||||||
|
|
||||||
|
.gutter-left {
|
||||||
|
margin-left: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-span-2 {
|
||||||
|
grid-column: span 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
background-color: #143055;
|
||||||
|
color: white;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
padding: 0 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
margin-left: 18px;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
margin: 40px 0 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resources {
|
||||||
|
text-align: center;
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
display: grid;
|
||||||
|
grid-gap: 9px;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resource {
|
||||||
|
color: #0094ba;
|
||||||
|
height: 36px;
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 3px 9px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resource:hover {
|
||||||
|
background-color: rgba(68, 138, 255, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
padding: 9px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: black;
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
details {
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #333;
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
|
padding: 3px 9px;
|
||||||
|
margin-bottom: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
summary {
|
||||||
|
outline: none;
|
||||||
|
height: 36px;
|
||||||
|
line-height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.github-star-container {
|
||||||
|
margin-top: 12px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.github-star-container a {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.github-star-badge {
|
||||||
|
color: #24292e;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 3px 10px;
|
||||||
|
border: 1px solid rgba(27,31,35,.2);
|
||||||
|
border-radius: 3px;
|
||||||
|
background-image: linear-gradient(-180deg,#fafbfc,#eff3f6 90%);
|
||||||
|
margin-left: 4px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.github-star-badge:hover {
|
||||||
|
background-image: linear-gradient(-180deg,#f0f3f6,#e6ebf1 90%);
|
||||||
|
border-color: rgba(27,31,35,.35);
|
||||||
|
background-position: -.5em;
|
||||||
|
}
|
||||||
|
.github-star-badge .material-icons {
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
<% }%>
|
||||||
|
|
||||||
|
<%
|
||||||
|
var innerJsx = `
|
||||||
|
<header className="flex">
|
||||||
|
<img
|
||||||
|
alt=""
|
||||||
|
width="75"
|
||||||
|
src="https://nx.dev/assets/images/nx-logo-white.svg"
|
||||||
|
/>
|
||||||
|
<h1>Welcome to ${name}!</h1>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<h2>Resources & Tools</h2>
|
||||||
|
<p>
|
||||||
|
Thank you for using and showing some ♥ for Nx.
|
||||||
|
</p>
|
||||||
|
<div className="flex github-star-container">
|
||||||
|
<a href="https://github.com/nrwl/nx" target="_blank" rel="noopener noreferrer"> If you like Nx, please give it a star:
|
||||||
|
<div className="github-star-badge">
|
||||||
|
<svg className="material-icons" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></svg>
|
||||||
|
Star
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Here are some links to help you get started.
|
||||||
|
</p>
|
||||||
|
<ul className="resources">
|
||||||
|
<li className="col-span-2">
|
||||||
|
<a
|
||||||
|
className="resource flex"
|
||||||
|
href="https://nx.dev/react/getting-started/what-is-nx"
|
||||||
|
>
|
||||||
|
Nx video tutorial
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li className="col-span-2">
|
||||||
|
<a
|
||||||
|
className="resource flex"
|
||||||
|
href="https://nx.dev/react/tutorial/01-create-application"
|
||||||
|
>
|
||||||
|
Interactive tutorial
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li className="col-span-2">
|
||||||
|
<a className="resource flex" href="https://connect.nrwl.io/">
|
||||||
|
<img
|
||||||
|
height="36"
|
||||||
|
alt="Nrwl Connect"
|
||||||
|
src="https://connect.nrwl.io/assets/img/CONNECT_ColorIcon.png"
|
||||||
|
/>
|
||||||
|
<span className="gutter-left">
|
||||||
|
Nrwl Connect
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h2>Next Steps</h2>
|
||||||
|
<p>
|
||||||
|
Here are some things you can do with Nx.
|
||||||
|
</p>
|
||||||
|
<details open>
|
||||||
|
<summary>Add UI library</summary>
|
||||||
|
<pre>{\`# Generate UI lib
|
||||||
|
nx g @nrwl/react:lib ui
|
||||||
|
|
||||||
|
# Add a component
|
||||||
|
nx g @nrwl/react:component xyz --project ui\`}</pre>
|
||||||
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary>View dependency graph</summary>
|
||||||
|
<pre>{\`nx dep-graph\`}</pre>
|
||||||
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary>Run affected commands</summary>
|
||||||
|
<pre>{\`# see what's been affected by changes
|
||||||
|
nx affected:dep-graph
|
||||||
|
|
||||||
|
# run tests for current changes
|
||||||
|
nx affected:test
|
||||||
|
|
||||||
|
# run e2e tests for current changes
|
||||||
|
nx affected:e2e
|
||||||
|
\`}</pre>
|
||||||
|
</details>
|
||||||
|
</main>
|
||||||
|
`;
|
||||||
|
%>
|
||||||
|
|
||||||
|
<% if (classComponent) { %>
|
||||||
|
export class Index extends Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<<%= wrapper %>>
|
||||||
|
<%= innerJsx %>
|
||||||
|
</<%= wrapper %>>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<% } else { %>
|
||||||
|
export const Index = () => {
|
||||||
|
/*
|
||||||
|
* Replace the elements below with your own.
|
||||||
|
*
|
||||||
|
* Note: The corresponding styles are in the ./${fileName}.${style} file.
|
||||||
|
*/
|
||||||
|
return (
|
||||||
|
<<%= wrapper %><% if (!styledModule) {%> className="app"<% } %>>
|
||||||
|
<%= innerJsx %>
|
||||||
|
</<%= wrapper %>>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
export default Index;
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { render, cleanup } from '@testing-library/react';
|
||||||
|
|
||||||
|
import Index from '../pages/index';
|
||||||
|
|
||||||
|
describe('Index', () => {
|
||||||
|
afterEach(cleanup);
|
||||||
|
|
||||||
|
it('should render successfully', () => {
|
||||||
|
const { baseElement } = render(<Index />);
|
||||||
|
expect(baseElement).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a greeting as the title', () => {
|
||||||
|
const { getByText } = render(<Index />);
|
||||||
|
expect(getByText('Welcome to <%= projectName %>!')).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
16
packages/next/src/schematics/application/files/tsconfig.json
Normal file
16
packages/next/src/schematics/application/files/tsconfig.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"extends": "<%= offsetFromRoot %>tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"jsx": "preserve",
|
||||||
|
"allowJs": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"types": ["node", "jest"],
|
||||||
|
"strict": false,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true
|
||||||
|
},
|
||||||
|
"include": ["**/*.ts", "**/*.tsx", "next-env.d.ts"]
|
||||||
|
}
|
||||||
15
packages/next/src/schematics/application/schema.d.ts
vendored
Normal file
15
packages/next/src/schematics/application/schema.d.ts
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { Linter } from '@nrwl/workspace';
|
||||||
|
|
||||||
|
export interface Schema {
|
||||||
|
name: string;
|
||||||
|
style?: string;
|
||||||
|
skipFormat: boolean;
|
||||||
|
directory?: string;
|
||||||
|
tags?: string;
|
||||||
|
unitTestRunner: 'jest' | 'none';
|
||||||
|
e2eTestRunner: 'cypress' | 'none';
|
||||||
|
linter: Linter;
|
||||||
|
pascalCaseFiles?: boolean;
|
||||||
|
skipWorkspaceJson?: boolean;
|
||||||
|
classComponent: boolean;
|
||||||
|
}
|
||||||
111
packages/next/src/schematics/application/schema.json
Normal file
111
packages/next/src/schematics/application/schema.json
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/schema",
|
||||||
|
"id": "NxNextApp",
|
||||||
|
"title": "Create a Next.js Application for Nx",
|
||||||
|
"examples": [
|
||||||
|
{
|
||||||
|
"command": "g app myapp --directory=myorg",
|
||||||
|
"description": "Generate apps/myorg/myapp and apps/myorg/myapp-e2e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "g app myapp --classComponent",
|
||||||
|
"description": "Use class components instead of functional components"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"description": "The name of the application.",
|
||||||
|
"type": "string",
|
||||||
|
"$default": {
|
||||||
|
"$source": "argv",
|
||||||
|
"index": 0
|
||||||
|
},
|
||||||
|
"x-prompt": "What name would you like to use for the application?"
|
||||||
|
},
|
||||||
|
"directory": {
|
||||||
|
"description": "The directory of the new application.",
|
||||||
|
"type": "string",
|
||||||
|
"alias": "d"
|
||||||
|
},
|
||||||
|
"style": {
|
||||||
|
"description": "The file extension to be used for style files.",
|
||||||
|
"type": "string",
|
||||||
|
"default": "css",
|
||||||
|
"alias": "s",
|
||||||
|
"x-prompt": {
|
||||||
|
"message": "Which stylesheet format would you like to use?",
|
||||||
|
"type": "list",
|
||||||
|
"items": [
|
||||||
|
{ "value": "css", "label": "CSS" },
|
||||||
|
{
|
||||||
|
"value": "scss",
|
||||||
|
"label": "SASS(.scss) [ http://sass-lang.com ]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "styl",
|
||||||
|
"label": "Stylus(.styl) [ http://stylus-lang.com ]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "less",
|
||||||
|
"label": "LESS [ http://lesscss.org ]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "styled-components",
|
||||||
|
"label": "styled-components [ https://styled-components.com ]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "@emotion/styled",
|
||||||
|
"label": "emotion [ https://emotion.sh ]"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"linter": {
|
||||||
|
"description": "The tool to use for running lint checks.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["eslint", "tslint"],
|
||||||
|
"default": "tslint"
|
||||||
|
},
|
||||||
|
"skipFormat": {
|
||||||
|
"description": "Skip formatting files",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"skipWorkspaceJson": {
|
||||||
|
"description": "Skip updating workspace.json with default schematic options based on values provided to this app (e.g. babel, style)",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"unitTestRunner": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["jest", "none"],
|
||||||
|
"description": "Test runner to use for unit tests",
|
||||||
|
"default": "jest"
|
||||||
|
},
|
||||||
|
"e2eTestRunner": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["cypress", "none"],
|
||||||
|
"description": "Test runner to use for end to end (e2e) tests",
|
||||||
|
"default": "cypress"
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Add tags to the application (used for linting)",
|
||||||
|
"alias": "t"
|
||||||
|
},
|
||||||
|
"pascalCaseFiles": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Use pascal case component file name (e.g. App.tsx)",
|
||||||
|
"alias": "P",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"classComponent": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Use class components instead of functional component",
|
||||||
|
"alias": "C",
|
||||||
|
"default": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": []
|
||||||
|
}
|
||||||
64
packages/next/src/schematics/init/init.spec.ts
Normal file
64
packages/next/src/schematics/init/init.spec.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import { Tree } from '@angular-devkit/schematics';
|
||||||
|
import { createEmptyWorkspace } from '@nrwl/workspace/testing';
|
||||||
|
import { readJsonInTree } from '@nrwl/workspace';
|
||||||
|
import { updateJsonInTree } from '@nrwl/workspace';
|
||||||
|
import { runSchematic, callRule } from '../../utils/testing';
|
||||||
|
|
||||||
|
describe('init', () => {
|
||||||
|
let tree: Tree;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
tree = Tree.empty();
|
||||||
|
tree = createEmptyWorkspace(tree);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add react dependencies', async () => {
|
||||||
|
const result = await runSchematic('init', {}, tree);
|
||||||
|
const packageJson = readJsonInTree(result, 'package.json');
|
||||||
|
expect(packageJson.dependencies['@nrwl/next']).toBeUndefined();
|
||||||
|
expect(packageJson.dependencies['@nrwl/react']).toBeUndefined();
|
||||||
|
expect(packageJson.dependencies['next']).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('defaultCollection', () => {
|
||||||
|
it('should be set if none was set before', async () => {
|
||||||
|
const result = await runSchematic('init', {}, tree);
|
||||||
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/next');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be set if @nrwl/workspace was set before', async () => {
|
||||||
|
tree = await callRule(
|
||||||
|
updateJsonInTree('workspace.json', json => {
|
||||||
|
json.cli = {
|
||||||
|
defaultCollection: '@nrwl/workspace'
|
||||||
|
};
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}),
|
||||||
|
tree
|
||||||
|
);
|
||||||
|
const result = await runSchematic('init', {}, tree);
|
||||||
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/next');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not be set if something else was set before', async () => {
|
||||||
|
tree = await callRule(
|
||||||
|
updateJsonInTree('workspace.json', json => {
|
||||||
|
json.cli = {
|
||||||
|
defaultCollection: '@nrwl/angular'
|
||||||
|
};
|
||||||
|
|
||||||
|
json.schematics = {};
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}),
|
||||||
|
tree
|
||||||
|
);
|
||||||
|
const result = await runSchematic('init', {}, tree);
|
||||||
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/angular');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
47
packages/next/src/schematics/init/init.ts
Normal file
47
packages/next/src/schematics/init/init.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import { JsonObject } from '@angular-devkit/core';
|
||||||
|
import { chain, Rule } from '@angular-devkit/schematics';
|
||||||
|
import {
|
||||||
|
addDepsToPackageJson,
|
||||||
|
addPackageWithInit,
|
||||||
|
updateWorkspace
|
||||||
|
} from '@nrwl/workspace';
|
||||||
|
import { frameworkVersion, pluginVersion } from '../../utils/versions';
|
||||||
|
import { Schema } from './schema';
|
||||||
|
|
||||||
|
export function addDependencies(): Rule {
|
||||||
|
return addDepsToPackageJson(
|
||||||
|
{
|
||||||
|
next: frameworkVersion,
|
||||||
|
'@zeit/next-css': pluginVersion,
|
||||||
|
'@zeit/next-sass': pluginVersion,
|
||||||
|
'@zeit/next-less': pluginVersion,
|
||||||
|
'@zeit/next-stylus': pluginVersion
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDefault(): Rule {
|
||||||
|
return updateWorkspace(workspace => {
|
||||||
|
// Set workspace default collection to 'react' if not already set.
|
||||||
|
workspace.extensions.cli = workspace.extensions.cli || {};
|
||||||
|
const defaultCollection: string =
|
||||||
|
workspace.extensions.cli &&
|
||||||
|
((workspace.extensions.cli as JsonObject).defaultCollection as string);
|
||||||
|
|
||||||
|
if (!defaultCollection || defaultCollection === '@nrwl/workspace') {
|
||||||
|
(workspace.extensions.cli as JsonObject).defaultCollection = '@nrwl/next';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function(schema: Schema) {
|
||||||
|
return chain([
|
||||||
|
setDefault(),
|
||||||
|
addPackageWithInit('@nrwl/jest'),
|
||||||
|
addPackageWithInit('@nrwl/cypress'),
|
||||||
|
addPackageWithInit('@nrwl/web'),
|
||||||
|
addPackageWithInit('@nrwl/react'),
|
||||||
|
addDependencies()
|
||||||
|
]);
|
||||||
|
}
|
||||||
14
packages/next/src/schematics/init/schema.json
Normal file
14
packages/next/src/schematics/init/schema.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/schema",
|
||||||
|
"id": "NxNextNgInit",
|
||||||
|
"title": "Add Nx Next Schematics",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"skipFormat": {
|
||||||
|
"description": "Skip formatting files",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": []
|
||||||
|
}
|
||||||
45
packages/next/src/utils/config.ts
Normal file
45
packages/next/src/utils/config.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import TsConfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
|
||||||
|
import loadConfig from 'next-server/dist/server/config';
|
||||||
|
import { offsetFromRoot } from '@nrwl/workspace';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as withCSS from '@zeit/next-css';
|
||||||
|
import * as withLESS from '@zeit/next-less';
|
||||||
|
import * as withSASS from '@zeit/next-sass';
|
||||||
|
import * as withSTYLUS from '@zeit/next-stylus';
|
||||||
|
|
||||||
|
function createWebpackConfig(root: string) {
|
||||||
|
return function webpackConfig(config, { defaultLoaders }) {
|
||||||
|
const mainFields = ['es2015', 'module', 'main'];
|
||||||
|
const extensions = ['.ts', '.tsx', '.mjs', '.js', '.jsx'];
|
||||||
|
config.resolve.plugins = [
|
||||||
|
new TsConfigPathsPlugin({
|
||||||
|
configFile: path.resolve(root, 'tsconfig.json'),
|
||||||
|
extensions,
|
||||||
|
mainFields
|
||||||
|
})
|
||||||
|
];
|
||||||
|
config.module.rules.push({
|
||||||
|
test: /\.tsx/,
|
||||||
|
use: [defaultLoaders.babel]
|
||||||
|
});
|
||||||
|
return config;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function prepareConfig(
|
||||||
|
workspaceRoot: string,
|
||||||
|
root: string,
|
||||||
|
outputPath: string,
|
||||||
|
mode: string
|
||||||
|
) {
|
||||||
|
const absoluteRoot = path.resolve(workspaceRoot, root);
|
||||||
|
const config = withSTYLUS(
|
||||||
|
withSASS(withLESS(withCSS(loadConfig(mode, root, null))))
|
||||||
|
);
|
||||||
|
config.distDir = `${offsetFromRoot(root)}${outputPath}`;
|
||||||
|
config.outdir = `${offsetFromRoot(root)}${outputPath}`;
|
||||||
|
const userWebpack = config.webpack;
|
||||||
|
config.webpack = (a, b) =>
|
||||||
|
createWebpackConfig(absoluteRoot)(userWebpack(a, b), b);
|
||||||
|
return config;
|
||||||
|
}
|
||||||
35
packages/next/src/utils/testing.ts
Normal file
35
packages/next/src/utils/testing.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { join } from 'path';
|
||||||
|
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
|
||||||
|
import { Rule, Tree } from '@angular-devkit/schematics';
|
||||||
|
import { names } from '@nrwl/workspace/src/utils/name-utils';
|
||||||
|
import { updateWorkspace } from '@nrwl/workspace/src/utils/workspace';
|
||||||
|
|
||||||
|
const testRunner = new SchematicTestRunner(
|
||||||
|
'@nrwl/next',
|
||||||
|
join(__dirname, '../../collection.json')
|
||||||
|
);
|
||||||
|
|
||||||
|
export function runSchematic(schematicName: string, options: any, tree: Tree) {
|
||||||
|
return testRunner.runSchematicAsync(schematicName, options, tree).toPromise();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function callRule(rule: Rule, tree: Tree) {
|
||||||
|
return testRunner.callRule(rule, tree).toPromise();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createApp(tree: Tree, appName: string): Promise<Tree> {
|
||||||
|
const { fileName } = names(appName);
|
||||||
|
|
||||||
|
return callRule(
|
||||||
|
updateWorkspace(workspace => {
|
||||||
|
workspace.projects.add({
|
||||||
|
name: fileName,
|
||||||
|
root: `apps/${fileName}`,
|
||||||
|
projectType: 'application',
|
||||||
|
sourceRoot: `apps/${fileName}/src`,
|
||||||
|
targets: {}
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
tree
|
||||||
|
);
|
||||||
|
}
|
||||||
3
packages/next/src/utils/versions.ts
Normal file
3
packages/next/src/utils/versions.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export const nxVersion = '*';
|
||||||
|
export const frameworkVersion = '9.0.5';
|
||||||
|
export const pluginVersion = '1.0.1';
|
||||||
@ -3,10 +3,11 @@
|
|||||||
"version": "0.1",
|
"version": "0.1",
|
||||||
"extends": ["@nrwl/workspace"],
|
"extends": ["@nrwl/workspace"],
|
||||||
"schematics": {
|
"schematics": {
|
||||||
"ng-add": {
|
"init": {
|
||||||
"factory": "./src/schematics/ng-add/ng-add",
|
"factory": "./src/schematics/init/init",
|
||||||
"schema": "./src/schematics/ng-add/schema.json",
|
"schema": "./src/schematics/init/schema.json",
|
||||||
"description": "Add @nrwl/node to a project",
|
"description": "Initialize the @nrwl/node plugin",
|
||||||
|
"aliases": ["ng-add"],
|
||||||
"hidden": true
|
"hidden": true
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@ import {
|
|||||||
import { toFileName } from '@nrwl/workspace';
|
import { toFileName } from '@nrwl/workspace';
|
||||||
import { getProjectConfig } from '@nrwl/workspace';
|
import { getProjectConfig } from '@nrwl/workspace';
|
||||||
import { offsetFromRoot } from '@nrwl/workspace';
|
import { offsetFromRoot } from '@nrwl/workspace';
|
||||||
import ngAdd from '../ng-add/ng-add';
|
import init from '../init/init';
|
||||||
|
|
||||||
interface NormalizedSchema extends Schema {
|
interface NormalizedSchema extends Schema {
|
||||||
appProjectRoot: Path;
|
appProjectRoot: Path;
|
||||||
@ -148,7 +148,7 @@ export default function(schema: Schema): Rule {
|
|||||||
return (host: Tree, context: SchematicContext) => {
|
return (host: Tree, context: SchematicContext) => {
|
||||||
const options = normalizeOptions(schema);
|
const options = normalizeOptions(schema);
|
||||||
return chain([
|
return chain([
|
||||||
ngAdd({
|
init({
|
||||||
skipFormat: true
|
skipFormat: true
|
||||||
}),
|
}),
|
||||||
addLintFiles(options.appProjectRoot, options.linter),
|
addLintFiles(options.appProjectRoot, options.linter),
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { createEmptyWorkspace } from '@nrwl/workspace/testing';
|
|||||||
import { readJsonInTree, updateJsonInTree } from '@nrwl/workspace';
|
import { readJsonInTree, updateJsonInTree } from '@nrwl/workspace';
|
||||||
import { callRule, runSchematic } from '../../utils/testing';
|
import { callRule, runSchematic } from '../../utils/testing';
|
||||||
|
|
||||||
describe('ng-add', () => {
|
describe('init', () => {
|
||||||
let tree: Tree;
|
let tree: Tree;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -12,7 +12,7 @@ describe('ng-add', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should add dependencies', async () => {
|
it('should add dependencies', async () => {
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const packageJson = readJsonInTree(result, 'package.json');
|
const packageJson = readJsonInTree(result, 'package.json');
|
||||||
expect(packageJson.dependencies['@nrwl/node']).toBeUndefined();
|
expect(packageJson.dependencies['@nrwl/node']).toBeUndefined();
|
||||||
expect(packageJson.devDependencies['@nrwl/node']).toBeDefined();
|
expect(packageJson.devDependencies['@nrwl/node']).toBeDefined();
|
||||||
@ -20,7 +20,7 @@ describe('ng-add', () => {
|
|||||||
|
|
||||||
describe('defaultCollection', () => {
|
describe('defaultCollection', () => {
|
||||||
it('should be set if none was set before', async () => {
|
it('should be set if none was set before', async () => {
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/node');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/node');
|
||||||
});
|
});
|
||||||
@ -36,7 +36,7 @@ describe('ng-add', () => {
|
|||||||
}),
|
}),
|
||||||
tree
|
tree
|
||||||
);
|
);
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/node');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/node');
|
||||||
});
|
});
|
||||||
@ -52,7 +52,7 @@ describe('ng-add', () => {
|
|||||||
}),
|
}),
|
||||||
tree
|
tree
|
||||||
);
|
);
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/angular');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/angular');
|
||||||
});
|
});
|
||||||
@ -2,7 +2,7 @@ import { Rule, chain } from '@angular-devkit/schematics';
|
|||||||
import {
|
import {
|
||||||
addDepsToPackageJson,
|
addDepsToPackageJson,
|
||||||
updateJsonInTree,
|
updateJsonInTree,
|
||||||
addPackageWithNgAdd,
|
addPackageWithInit,
|
||||||
updateWorkspace,
|
updateWorkspace,
|
||||||
formatFiles
|
formatFiles
|
||||||
} from '@nrwl/workspace';
|
} from '@nrwl/workspace';
|
||||||
@ -45,7 +45,7 @@ function setDefault(): Rule {
|
|||||||
export default function(schema: Schema) {
|
export default function(schema: Schema) {
|
||||||
return chain([
|
return chain([
|
||||||
setDefault(),
|
setDefault(),
|
||||||
addPackageWithNgAdd('@nrwl/jest'),
|
addPackageWithInit('@nrwl/jest'),
|
||||||
addDependencies(),
|
addDependencies(),
|
||||||
moveDependency(),
|
moveDependency(),
|
||||||
formatFiles(schema)
|
formatFiles(schema)
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/schema",
|
"$schema": "http://json-schema.org/schema",
|
||||||
"id": "NxNodeNgAdd",
|
"id": "NxNodeInit",
|
||||||
"title": "Add Nx Node Schematics",
|
"title": "Add Nx Node Schematics",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -1,12 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "nx/react",
|
"name": "Nx React",
|
||||||
"version": "0.1",
|
"version": "0.1",
|
||||||
"extends": ["@nrwl/workspace"],
|
"extends": ["@nrwl/workspace"],
|
||||||
"schematics": {
|
"schematics": {
|
||||||
"ng-add": {
|
"init": {
|
||||||
"factory": "./src/schematics/ng-add/ng-add",
|
"factory": "./src/schematics/init/init",
|
||||||
"schema": "./src/schematics/ng-add/schema.json",
|
"schema": "./src/schematics/init/schema.json",
|
||||||
"description": "Add @nrwl/react to a project",
|
"description": "Initialize the @nrwl/react plugin",
|
||||||
|
"aliases": ["ng-add"],
|
||||||
"hidden": true
|
"hidden": true
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
export { extraEslintDependencies, reactEslintJson } from './src/utils/lint';
|
||||||
|
export { CSS_IN_JS_DEPENDENCIES } from './src/utils/styled';
|
||||||
|
export { assertValidStyle } from './src/utils/assertion';
|
||||||
@ -30,7 +30,7 @@ import {
|
|||||||
addDepsToPackageJson,
|
addDepsToPackageJson,
|
||||||
updateWorkspaceInTree
|
updateWorkspaceInTree
|
||||||
} from '@nrwl/workspace/src/utils/ast-utils';
|
} from '@nrwl/workspace/src/utils/ast-utils';
|
||||||
import ngAdd from '../ng-add/ng-add';
|
import init from '../init/init';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import { Schema } from './schema';
|
import { Schema } from './schema';
|
||||||
@ -59,7 +59,7 @@ export default function(schema: Schema): Rule {
|
|||||||
const options = normalizeOptions(host, schema);
|
const options = normalizeOptions(host, schema);
|
||||||
|
|
||||||
return chain([
|
return chain([
|
||||||
ngAdd({
|
init({
|
||||||
skipFormat: true
|
skipFormat: true
|
||||||
}),
|
}),
|
||||||
addLintFiles(options.appProjectRoot, options.linter, {
|
addLintFiles(options.appProjectRoot, options.linter, {
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { readJsonInTree } from '@nrwl/workspace';
|
|||||||
import { updateJsonInTree } from '@nrwl/workspace';
|
import { updateJsonInTree } from '@nrwl/workspace';
|
||||||
import { runSchematic, callRule } from '../../utils/testing';
|
import { runSchematic, callRule } from '../../utils/testing';
|
||||||
|
|
||||||
describe('ng-add', () => {
|
describe('init', () => {
|
||||||
let tree: Tree;
|
let tree: Tree;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -13,7 +13,7 @@ describe('ng-add', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should add react dependencies', async () => {
|
it('should add react dependencies', async () => {
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const packageJson = readJsonInTree(result, 'package.json');
|
const packageJson = readJsonInTree(result, 'package.json');
|
||||||
expect(packageJson.dependencies['@nrwl/react']).toBeUndefined();
|
expect(packageJson.dependencies['@nrwl/react']).toBeUndefined();
|
||||||
expect(packageJson.dependencies['react']).toBeDefined();
|
expect(packageJson.dependencies['react']).toBeDefined();
|
||||||
@ -26,7 +26,7 @@ describe('ng-add', () => {
|
|||||||
|
|
||||||
describe('defaultCollection', () => {
|
describe('defaultCollection', () => {
|
||||||
it('should be set if none was set before', async () => {
|
it('should be set if none was set before', async () => {
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/react');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/react');
|
||||||
expect(workspaceJson.schematics['@nrwl/react'].application.babel).toBe(
|
expect(workspaceJson.schematics['@nrwl/react'].application.babel).toBe(
|
||||||
@ -45,7 +45,7 @@ describe('ng-add', () => {
|
|||||||
}),
|
}),
|
||||||
tree
|
tree
|
||||||
);
|
);
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/react');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/react');
|
||||||
expect(workspaceJson.schematics['@nrwl/react'].application.babel).toBe(
|
expect(workspaceJson.schematics['@nrwl/react'].application.babel).toBe(
|
||||||
@ -66,7 +66,7 @@ describe('ng-add', () => {
|
|||||||
}),
|
}),
|
||||||
tree
|
tree
|
||||||
);
|
);
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/angular');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/angular');
|
||||||
});
|
});
|
||||||
@ -2,7 +2,7 @@ import { chain, Rule } from '@angular-devkit/schematics';
|
|||||||
import {
|
import {
|
||||||
addDepsToPackageJson,
|
addDepsToPackageJson,
|
||||||
updateJsonInTree,
|
updateJsonInTree,
|
||||||
addPackageWithNgAdd,
|
addPackageWithInit,
|
||||||
updateWorkspace
|
updateWorkspace
|
||||||
} from '@nrwl/workspace';
|
} from '@nrwl/workspace';
|
||||||
import { Schema } from './schema';
|
import { Schema } from './schema';
|
||||||
@ -76,9 +76,9 @@ function jsonIdentity(x: any): JsonObject {
|
|||||||
export default function(schema: Schema) {
|
export default function(schema: Schema) {
|
||||||
return chain([
|
return chain([
|
||||||
setDefault(),
|
setDefault(),
|
||||||
addPackageWithNgAdd('@nrwl/jest'),
|
addPackageWithInit('@nrwl/jest'),
|
||||||
addPackageWithNgAdd('@nrwl/cypress'),
|
addPackageWithInit('@nrwl/cypress'),
|
||||||
addPackageWithNgAdd('@nrwl/web'),
|
addPackageWithInit('@nrwl/web'),
|
||||||
addDependencies(),
|
addDependencies(),
|
||||||
moveDependency()
|
moveDependency()
|
||||||
]);
|
]);
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/schema",
|
"$schema": "http://json-schema.org/schema",
|
||||||
"id": "NxReactNgAdd",
|
"id": "NxReactNgInit",
|
||||||
"title": "Add Nx React Schematics",
|
"title": "Add Nx React Schematics",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
import { join, Path, strings } from '@angular-devkit/core';
|
import { join, Path, strings } from '@angular-devkit/core';
|
||||||
import '@nrwl/tao/src/compat/angular-cli-compat';
|
import '@nrwl/tao/src/compat/compat';
|
||||||
import {
|
import {
|
||||||
addDepsToPackageJson,
|
addDepsToPackageJson,
|
||||||
addGlobal,
|
addGlobal,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
import './src/compat/angular-cli-compat';
|
import './src/compat/compat';
|
||||||
|
|
||||||
export async function invokeCommand(
|
export async function invokeCommand(
|
||||||
command: string,
|
command: string,
|
||||||
|
|||||||
@ -3,9 +3,9 @@
|
|||||||
"version": "0.1",
|
"version": "0.1",
|
||||||
"extends": ["@nrwl/workspace"],
|
"extends": ["@nrwl/workspace"],
|
||||||
"schematics": {
|
"schematics": {
|
||||||
"ng-add": {
|
"init": {
|
||||||
"factory": "./src/schematics/ng-add/ng-add",
|
"factory": "./src/schematics/init/init",
|
||||||
"schema": "./src/schematics/ng-add/schema.json",
|
"schema": "./src/schematics/init/schema.json",
|
||||||
"description": "Add @nrwl/web to a project",
|
"description": "Add @nrwl/web to a project",
|
||||||
"hidden": true
|
"hidden": true
|
||||||
},
|
},
|
||||||
|
|||||||
@ -26,7 +26,7 @@ import {
|
|||||||
generateProjectLint,
|
generateProjectLint,
|
||||||
addLintFiles
|
addLintFiles
|
||||||
} from '@nrwl/workspace';
|
} from '@nrwl/workspace';
|
||||||
import ngAdd from '../ng-add/ng-add';
|
import init from '../init/init';
|
||||||
|
|
||||||
interface NormalizedSchema extends Schema {
|
interface NormalizedSchema extends Schema {
|
||||||
projectName: string;
|
projectName: string;
|
||||||
@ -150,7 +150,7 @@ export default function(schema: Schema): Rule {
|
|||||||
const options = normalizeOptions(host, schema);
|
const options = normalizeOptions(host, schema);
|
||||||
|
|
||||||
return chain([
|
return chain([
|
||||||
ngAdd({
|
init({
|
||||||
skipFormat: true
|
skipFormat: true
|
||||||
}),
|
}),
|
||||||
addLintFiles(options.appProjectRoot, options.linter),
|
addLintFiles(options.appProjectRoot, options.linter),
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { readJsonInTree } from '@nrwl/workspace';
|
|||||||
import { callRule, runSchematic } from '../../utils/testing';
|
import { callRule, runSchematic } from '../../utils/testing';
|
||||||
import { updateJsonInTree } from '@nrwl/workspace/src/utils/ast-utils';
|
import { updateJsonInTree } from '@nrwl/workspace/src/utils/ast-utils';
|
||||||
|
|
||||||
describe('ng-add', () => {
|
describe('init', () => {
|
||||||
let tree: Tree;
|
let tree: Tree;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -13,7 +13,7 @@ describe('ng-add', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should add web dependencies', async () => {
|
it('should add web dependencies', async () => {
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const packageJson = readJsonInTree(result, 'package.json');
|
const packageJson = readJsonInTree(result, 'package.json');
|
||||||
expect(packageJson.dependencies['@nrwl/web']).toBeUndefined();
|
expect(packageJson.dependencies['@nrwl/web']).toBeUndefined();
|
||||||
expect(packageJson.dependencies['document-register-element']).toBeDefined();
|
expect(packageJson.dependencies['document-register-element']).toBeDefined();
|
||||||
@ -22,7 +22,7 @@ describe('ng-add', () => {
|
|||||||
|
|
||||||
describe('defaultCollection', () => {
|
describe('defaultCollection', () => {
|
||||||
it('should be set if none was set before', async () => {
|
it('should be set if none was set before', async () => {
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/web');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/web');
|
||||||
});
|
});
|
||||||
@ -38,7 +38,7 @@ describe('ng-add', () => {
|
|||||||
}),
|
}),
|
||||||
tree
|
tree
|
||||||
);
|
);
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/web');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/web');
|
||||||
});
|
});
|
||||||
@ -54,7 +54,7 @@ describe('ng-add', () => {
|
|||||||
}),
|
}),
|
||||||
tree
|
tree
|
||||||
);
|
);
|
||||||
const result = await runSchematic('ng-add', {}, tree);
|
const result = await runSchematic('init', {}, tree);
|
||||||
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
const workspaceJson = readJsonInTree(result, 'workspace.json');
|
||||||
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/angular');
|
expect(workspaceJson.cli.defaultCollection).toEqual('@nrwl/angular');
|
||||||
});
|
});
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { Rule, chain } from '@angular-devkit/schematics';
|
import { Rule, chain } from '@angular-devkit/schematics';
|
||||||
import {
|
import {
|
||||||
updateJsonInTree,
|
updateJsonInTree,
|
||||||
addPackageWithNgAdd,
|
addPackageWithInit,
|
||||||
formatFiles
|
formatFiles
|
||||||
} from '@nrwl/workspace';
|
} from '@nrwl/workspace';
|
||||||
import { addDepsToPackageJson } from '@nrwl/workspace';
|
import { addDepsToPackageJson } from '@nrwl/workspace';
|
||||||
@ -50,8 +50,8 @@ function setDefault(): Rule {
|
|||||||
export default function(schema: Schema) {
|
export default function(schema: Schema) {
|
||||||
return chain([
|
return chain([
|
||||||
setDefault(),
|
setDefault(),
|
||||||
addPackageWithNgAdd('@nrwl/jest'),
|
addPackageWithInit('@nrwl/jest'),
|
||||||
addPackageWithNgAdd('@nrwl/cypress'),
|
addPackageWithInit('@nrwl/cypress'),
|
||||||
addDependencies(),
|
addDependencies(),
|
||||||
moveDependency(),
|
moveDependency(),
|
||||||
formatFiles(schema)
|
formatFiles(schema)
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user