feat(web): add file-server builder
This commit is contained in:
parent
c8259074ac
commit
4511ec65fb
55
docs/angular/api-web/builders/file-server.md
Normal file
55
docs/angular/api-web/builders/file-server.md
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# file-server
|
||||||
|
|
||||||
|
Serve a web application from a folder
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
### host
|
||||||
|
|
||||||
|
Default: `localhost`
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Host to listen on.
|
||||||
|
|
||||||
|
### port
|
||||||
|
|
||||||
|
Default: `4200`
|
||||||
|
|
||||||
|
Type: `number`
|
||||||
|
|
||||||
|
Port to listen on.
|
||||||
|
|
||||||
|
### proxyUrl
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
URL to proxy unhandled requests to.
|
||||||
|
|
||||||
|
### ssl
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Serve using HTTPS.
|
||||||
|
|
||||||
|
### sslCert
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
SSL certificate to use for serving HTTPS.
|
||||||
|
|
||||||
|
### sslKey
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
SSL key to use for serving HTTPS.
|
||||||
65
docs/angular/api-workspace/schematics/move.md
Normal file
65
docs/angular/api-workspace/schematics/move.md
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
# move
|
||||||
|
|
||||||
|
Move an application or library to another folder
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx generate move ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g mv ... # same
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `move` in the default collection provisioned in `angular.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:move ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g move ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
Move libs/my-feature-lib to libs/shared/my-feature-lib:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:move --project my-feature-lib shared/my-feature-lib
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### destination
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The folder to move the project into
|
||||||
|
|
||||||
|
### importPath
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The new import path to use in the tsconfig.base.json
|
||||||
|
|
||||||
|
### projectName
|
||||||
|
|
||||||
|
Alias(es): project
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The name of the project to move
|
||||||
|
|
||||||
|
### updateImportPath
|
||||||
|
|
||||||
|
Default: `true`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Should the schematic update the import path to reflect the new location?
|
||||||
71
docs/angular/api-workspace/schematics/remove.md
Normal file
71
docs/angular/api-workspace/schematics/remove.md
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# remove
|
||||||
|
|
||||||
|
Remove an application or library
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx generate remove ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g rm ... # same
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `remove` in the default collection provisioned in `angular.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:remove ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g remove ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
Remove my-feature-lib from the workspace:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:remove my-feature-lib
|
||||||
|
```
|
||||||
|
|
||||||
|
Force removal of my-feature-lib from the workspace:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:remove my-feature-lib --forceRemove
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### forceRemove
|
||||||
|
|
||||||
|
Alias(es): force-remove
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
When true, forces removal even if the project is still in use.
|
||||||
|
|
||||||
|
### projectName
|
||||||
|
|
||||||
|
Alias(es): project
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The name of the project to remove
|
||||||
|
|
||||||
|
### skipFormat
|
||||||
|
|
||||||
|
Alias(es): skip-format
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Skip formatting files.
|
||||||
73
docs/angular/api-workspace/schematics/run-commands.md
Normal file
73
docs/angular/api-workspace/schematics/run-commands.md
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# run-commands
|
||||||
|
|
||||||
|
Generates a target to run any command in the terminal
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx generate run-commands ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g run-command ... # same
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `run-commands` in the default collection provisioned in `angular.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:run-commands ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g run-commands ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
Add the printhello target to my-feature-lib:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:run-commands printhello --project my-feature-lib --command 'echo hello'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### command
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Command to run
|
||||||
|
|
||||||
|
### cwd
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Current working directory of the command
|
||||||
|
|
||||||
|
### envFile
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Env files to be loaded before executing the commands
|
||||||
|
|
||||||
|
### name
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Target name
|
||||||
|
|
||||||
|
### outputs
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Allows you to specify where the build artifacts are stored. This allows Nx Cloud to pick them up correctly, in the case that the build artifacts are placed somewhere other than the top level dist folder.
|
||||||
|
|
||||||
|
### project
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Project name
|
||||||
39
docs/angular/api-workspace/schematics/workspace-schematic.md
Normal file
39
docs/angular/api-workspace/schematics/workspace-schematic.md
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# workspace-schematic
|
||||||
|
|
||||||
|
Generates a workspace schematic
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx generate workspace-schematic ...
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `workspace-schematic` in the default collection provisioned in `angular.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:workspace-schematic ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g workspace-schematic ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### name
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Schematic name
|
||||||
|
|
||||||
|
### skipFormat
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Skip formatting files
|
||||||
@ -341,6 +341,11 @@
|
|||||||
"id": "dev-server",
|
"id": "dev-server",
|
||||||
"file": "angular/api-web/builders/dev-server"
|
"file": "angular/api-web/builders/dev-server"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "file-server",
|
||||||
|
"id": "file-server",
|
||||||
|
"file": "angular/api-web/builders/file-server"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "package",
|
"name": "package",
|
||||||
"id": "package",
|
"id": "package",
|
||||||
@ -1429,6 +1434,11 @@
|
|||||||
"id": "dev-server",
|
"id": "dev-server",
|
||||||
"file": "react/api-web/builders/dev-server"
|
"file": "react/api-web/builders/dev-server"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "file-server",
|
||||||
|
"id": "file-server",
|
||||||
|
"file": "react/api-web/builders/file-server"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "package",
|
"name": "package",
|
||||||
"id": "package",
|
"id": "package",
|
||||||
@ -2470,6 +2480,11 @@
|
|||||||
"id": "dev-server",
|
"id": "dev-server",
|
||||||
"file": "node/api-web/builders/dev-server"
|
"file": "node/api-web/builders/dev-server"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "file-server",
|
||||||
|
"id": "file-server",
|
||||||
|
"file": "node/api-web/builders/file-server"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "package",
|
"name": "package",
|
||||||
"id": "package",
|
"id": "package",
|
||||||
|
|||||||
56
docs/node/api-web/builders/file-server.md
Normal file
56
docs/node/api-web/builders/file-server.md
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# file-server
|
||||||
|
|
||||||
|
Serve a web application from a folder
|
||||||
|
|
||||||
|
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/node/guides/cli.
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
### buildTarget
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Target which builds the application
|
||||||
|
|
||||||
|
### host
|
||||||
|
|
||||||
|
Default: `localhost`
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Host to listen on.
|
||||||
|
|
||||||
|
### port
|
||||||
|
|
||||||
|
Default: `4200`
|
||||||
|
|
||||||
|
Type: `number`
|
||||||
|
|
||||||
|
Port to listen on.
|
||||||
|
|
||||||
|
### proxyUrl
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
URL to proxy unhandled requests to.
|
||||||
|
|
||||||
|
### ssl
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Serve using HTTPS.
|
||||||
|
|
||||||
|
### sslCert
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
SSL certificate to use for serving HTTPS.
|
||||||
|
|
||||||
|
### sslKey
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
SSL key to use for serving HTTPS.
|
||||||
65
docs/node/api-workspace/schematics/move.md
Normal file
65
docs/node/api-workspace/schematics/move.md
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
# move
|
||||||
|
|
||||||
|
Move an application or library to another folder
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx generate move ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g mv ... # same
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `move` in the default collection provisioned in `workspace.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:move ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g move ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
Move libs/my-feature-lib to libs/shared/my-feature-lib:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:move --project my-feature-lib shared/my-feature-lib
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### destination
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The folder to move the project into
|
||||||
|
|
||||||
|
### importPath
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The new import path to use in the tsconfig.base.json
|
||||||
|
|
||||||
|
### projectName
|
||||||
|
|
||||||
|
Alias(es): project
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The name of the project to move
|
||||||
|
|
||||||
|
### updateImportPath
|
||||||
|
|
||||||
|
Default: `true`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Should the schematic update the import path to reflect the new location?
|
||||||
71
docs/node/api-workspace/schematics/remove.md
Normal file
71
docs/node/api-workspace/schematics/remove.md
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# remove
|
||||||
|
|
||||||
|
Remove an application or library
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx generate remove ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g rm ... # same
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `remove` in the default collection provisioned in `workspace.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:remove ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g remove ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
Remove my-feature-lib from the workspace:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:remove my-feature-lib
|
||||||
|
```
|
||||||
|
|
||||||
|
Force removal of my-feature-lib from the workspace:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:remove my-feature-lib --forceRemove
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### forceRemove
|
||||||
|
|
||||||
|
Alias(es): force-remove
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
When true, forces removal even if the project is still in use.
|
||||||
|
|
||||||
|
### projectName
|
||||||
|
|
||||||
|
Alias(es): project
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The name of the project to remove
|
||||||
|
|
||||||
|
### skipFormat
|
||||||
|
|
||||||
|
Alias(es): skip-format
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Skip formatting files.
|
||||||
73
docs/node/api-workspace/schematics/run-commands.md
Normal file
73
docs/node/api-workspace/schematics/run-commands.md
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# run-commands
|
||||||
|
|
||||||
|
Generates a target to run any command in the terminal
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx generate run-commands ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g run-command ... # same
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `run-commands` in the default collection provisioned in `workspace.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:run-commands ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g run-commands ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
Add the printhello target to my-feature-lib:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:run-commands printhello --project my-feature-lib --command 'echo hello'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### command
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Command to run
|
||||||
|
|
||||||
|
### cwd
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Current working directory of the command
|
||||||
|
|
||||||
|
### envFile
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Env files to be loaded before executing the commands
|
||||||
|
|
||||||
|
### name
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Target name
|
||||||
|
|
||||||
|
### outputs
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Allows you to specify where the build artifacts are stored. This allows Nx Cloud to pick them up correctly, in the case that the build artifacts are placed somewhere other than the top level dist folder.
|
||||||
|
|
||||||
|
### project
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Project name
|
||||||
39
docs/node/api-workspace/schematics/workspace-schematic.md
Normal file
39
docs/node/api-workspace/schematics/workspace-schematic.md
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# workspace-schematic
|
||||||
|
|
||||||
|
Generates a workspace schematic
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx generate workspace-schematic ...
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `workspace-schematic` in the default collection provisioned in `workspace.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:workspace-schematic ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g workspace-schematic ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### name
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Schematic name
|
||||||
|
|
||||||
|
### skipFormat
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Skip formatting files
|
||||||
56
docs/react/api-web/builders/file-server.md
Normal file
56
docs/react/api-web/builders/file-server.md
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# file-server
|
||||||
|
|
||||||
|
Serve a web application from a folder
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
### host
|
||||||
|
|
||||||
|
Default: `localhost`
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Host to listen on.
|
||||||
|
|
||||||
|
### port
|
||||||
|
|
||||||
|
Default: `4200`
|
||||||
|
|
||||||
|
Type: `number`
|
||||||
|
|
||||||
|
Port to listen on.
|
||||||
|
|
||||||
|
### proxyUrl
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
URL to proxy unhandled requests to.
|
||||||
|
|
||||||
|
### ssl
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Serve using HTTPS.
|
||||||
|
|
||||||
|
### sslCert
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
SSL certificate to use for serving HTTPS.
|
||||||
|
|
||||||
|
### sslKey
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
SSL key to use for serving HTTPS.
|
||||||
65
docs/react/api-workspace/schematics/move.md
Normal file
65
docs/react/api-workspace/schematics/move.md
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
# move
|
||||||
|
|
||||||
|
Move an application or library to another folder
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx generate move ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g mv ... # same
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `move` in the default collection provisioned in `workspace.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:move ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g move ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
Move libs/my-feature-lib to libs/shared/my-feature-lib:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:move --project my-feature-lib shared/my-feature-lib
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### destination
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The folder to move the project into
|
||||||
|
|
||||||
|
### importPath
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The new import path to use in the tsconfig.base.json
|
||||||
|
|
||||||
|
### projectName
|
||||||
|
|
||||||
|
Alias(es): project
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The name of the project to move
|
||||||
|
|
||||||
|
### updateImportPath
|
||||||
|
|
||||||
|
Default: `true`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Should the schematic update the import path to reflect the new location?
|
||||||
71
docs/react/api-workspace/schematics/remove.md
Normal file
71
docs/react/api-workspace/schematics/remove.md
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# remove
|
||||||
|
|
||||||
|
Remove an application or library
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx generate remove ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g rm ... # same
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `remove` in the default collection provisioned in `workspace.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:remove ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g remove ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
Remove my-feature-lib from the workspace:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:remove my-feature-lib
|
||||||
|
```
|
||||||
|
|
||||||
|
Force removal of my-feature-lib from the workspace:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:remove my-feature-lib --forceRemove
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### forceRemove
|
||||||
|
|
||||||
|
Alias(es): force-remove
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
When true, forces removal even if the project is still in use.
|
||||||
|
|
||||||
|
### projectName
|
||||||
|
|
||||||
|
Alias(es): project
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
The name of the project to remove
|
||||||
|
|
||||||
|
### skipFormat
|
||||||
|
|
||||||
|
Alias(es): skip-format
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Skip formatting files.
|
||||||
73
docs/react/api-workspace/schematics/run-commands.md
Normal file
73
docs/react/api-workspace/schematics/run-commands.md
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# run-commands
|
||||||
|
|
||||||
|
Generates a target to run any command in the terminal
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx generate run-commands ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g run-command ... # same
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `run-commands` in the default collection provisioned in `workspace.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:run-commands ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g run-commands ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
Add the printhello target to my-feature-lib:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:run-commands printhello --project my-feature-lib --command 'echo hello'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### command
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Command to run
|
||||||
|
|
||||||
|
### cwd
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Current working directory of the command
|
||||||
|
|
||||||
|
### envFile
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Env files to be loaded before executing the commands
|
||||||
|
|
||||||
|
### name
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Target name
|
||||||
|
|
||||||
|
### outputs
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Allows you to specify where the build artifacts are stored. This allows Nx Cloud to pick them up correctly, in the case that the build artifacts are placed somewhere other than the top level dist folder.
|
||||||
|
|
||||||
|
### project
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Project name
|
||||||
39
docs/react/api-workspace/schematics/workspace-schematic.md
Normal file
39
docs/react/api-workspace/schematics/workspace-schematic.md
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# workspace-schematic
|
||||||
|
|
||||||
|
Generates a workspace schematic
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx generate workspace-schematic ...
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, Nx will search for `workspace-schematic` in the default collection provisioned in `workspace.json`.
|
||||||
|
|
||||||
|
You can specify the collection explicitly as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g @nrwl/workspace:workspace-schematic ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Show what will be generated without writing to disk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nx g workspace-schematic ... --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### name
|
||||||
|
|
||||||
|
Type: `string`
|
||||||
|
|
||||||
|
Schematic name
|
||||||
|
|
||||||
|
### skipFormat
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Skip formatting files
|
||||||
@ -1,23 +1,21 @@
|
|||||||
import {
|
import {
|
||||||
ensureProject,
|
checkFilesExist,
|
||||||
exists,
|
|
||||||
expectTestsPass,
|
expectTestsPass,
|
||||||
|
forEachCli,
|
||||||
getSize,
|
getSize,
|
||||||
|
newProject,
|
||||||
runCLI,
|
runCLI,
|
||||||
runCLIAsync,
|
runCLIAsync,
|
||||||
|
tmpProjPath,
|
||||||
uniq,
|
uniq,
|
||||||
updateFile,
|
updateFile,
|
||||||
forEachCli,
|
|
||||||
checkFilesExist,
|
|
||||||
tmpProjPath,
|
|
||||||
supportUi,
|
|
||||||
} from '@nrwl/e2e/utils';
|
} from '@nrwl/e2e/utils';
|
||||||
import { toClassName } from '@nrwl/workspace';
|
import { toClassName } from '@nrwl/workspace';
|
||||||
|
|
||||||
forEachCli(() => {
|
forEachCli(() => {
|
||||||
describe('Angular Package', () => {
|
describe('Angular Package', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
ensureProject();
|
newProject();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work', async () => {
|
it('should work', async () => {
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
import {
|
import {
|
||||||
ensureProject,
|
forEachCli,
|
||||||
|
newProject,
|
||||||
|
patchKarmaToWorkOnWSL,
|
||||||
runCLI,
|
runCLI,
|
||||||
|
runCommand,
|
||||||
uniq,
|
uniq,
|
||||||
updateFile,
|
updateFile,
|
||||||
forEachCli,
|
|
||||||
patchKarmaToWorkOnWSL,
|
|
||||||
runCommand,
|
|
||||||
} from '@nrwl/e2e/utils';
|
} from '@nrwl/e2e/utils';
|
||||||
|
|
||||||
forEachCli('angular', () => {
|
forEachCli('angular', () => {
|
||||||
// TODO: This test is super flaky, investigate and re-enable.
|
// TODO: This test is super flaky, investigate and re-enable.
|
||||||
describe('AngularJS Schematics', () => {
|
describe('AngularJS Schematics', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
ensureProject();
|
newProject();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DowngradeModule', () => {
|
describe('DowngradeModule', () => {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
ensureProject,
|
|
||||||
forEachCli,
|
forEachCli,
|
||||||
|
newProject,
|
||||||
patchKarmaToWorkOnWSL,
|
patchKarmaToWorkOnWSL,
|
||||||
runCLI,
|
runCLI,
|
||||||
runCLIAsync,
|
runCLIAsync,
|
||||||
@ -11,7 +11,7 @@ forEachCli(() => {
|
|||||||
// TODO: This test is super flaky, investigate and re-enable.
|
// TODO: This test is super flaky, investigate and re-enable.
|
||||||
xdescribe('Karma', () => {
|
xdescribe('Karma', () => {
|
||||||
it('should be able to generate a testable library using karma', async (done) => {
|
it('should be able to generate a testable library using karma', async (done) => {
|
||||||
ensureProject();
|
newProject();
|
||||||
|
|
||||||
// run an app
|
// run an app
|
||||||
const myapp = uniq('myapp');
|
const myapp = uniq('myapp');
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
import {
|
import {
|
||||||
runCLI,
|
|
||||||
expectTestsPass,
|
expectTestsPass,
|
||||||
|
forEachCli,
|
||||||
|
newProject,
|
||||||
|
readJson,
|
||||||
|
runCLI,
|
||||||
runCLIAsync,
|
runCLIAsync,
|
||||||
uniq,
|
uniq,
|
||||||
ensureProject,
|
|
||||||
readJson,
|
|
||||||
forEachCli,
|
|
||||||
} from '@nrwl/e2e/utils';
|
} from '@nrwl/e2e/utils';
|
||||||
|
|
||||||
forEachCli(() => {
|
forEachCli(() => {
|
||||||
describe('ngrx', () => {
|
describe('ngrx', () => {
|
||||||
it('should work', async () => {
|
it('should work', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
|
|
||||||
const myapp = uniq('myapp');
|
const myapp = uniq('myapp');
|
||||||
runCLI(`generate @nrwl/angular:app ${myapp} --no-interactive`);
|
runCLI(`generate @nrwl/angular:app ${myapp} --no-interactive`);
|
||||||
@ -39,7 +39,7 @@ forEachCli(() => {
|
|||||||
}, 1000000);
|
}, 1000000);
|
||||||
|
|
||||||
it('should work with creators', async () => {
|
it('should work with creators', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
|
|
||||||
const myapp = uniq('myapp');
|
const myapp = uniq('myapp');
|
||||||
runCLI(`generate @nrwl/angular:app ${myapp} --routing --no-interactive`);
|
runCLI(`generate @nrwl/angular:app ${myapp} --routing --no-interactive`);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { ensureProject, runCLI, uniq, forEachCli } from '@nrwl/e2e/utils';
|
import { forEachCli, newProject, runCLI, uniq } from '@nrwl/e2e/utils';
|
||||||
|
|
||||||
forEachCli(() => {
|
forEachCli(() => {
|
||||||
describe('Protractor', () => {
|
describe('Protractor', () => {
|
||||||
@ -9,7 +9,7 @@ forEachCli(() => {
|
|||||||
|
|
||||||
xdescribe('Protractor', () => {
|
xdescribe('Protractor', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
ensureProject();
|
newProject();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work', async () => {
|
it('should work', async () => {
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { packagesWeCareAbout } from '@nrwl/workspace/src/command-line/report';
|
import { packagesWeCareAbout } from '@nrwl/workspace/src/command-line/report';
|
||||||
import { renameSync } from 'fs';
|
import { renameSync } from 'fs';
|
||||||
import {
|
import {
|
||||||
ensureProject,
|
|
||||||
forEachCli,
|
forEachCli,
|
||||||
newProject,
|
newProject,
|
||||||
readFile,
|
readFile,
|
||||||
@ -16,7 +15,7 @@ import {
|
|||||||
forEachCli('nx', () => {
|
forEachCli('nx', () => {
|
||||||
describe('Help', () => {
|
describe('Help', () => {
|
||||||
it('should show help', async () => {
|
it('should show help', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const myapp = uniq('myapp');
|
const myapp = uniq('myapp');
|
||||||
runCLI(`generate @nrwl/web:app ${myapp}`);
|
runCLI(`generate @nrwl/web:app ${myapp}`);
|
||||||
|
|
||||||
@ -48,7 +47,7 @@ forEachCli('nx', () => {
|
|||||||
forEachCli('angular', () => {
|
forEachCli('angular', () => {
|
||||||
describe('help', () => {
|
describe('help', () => {
|
||||||
it('should show help', async () => {
|
it('should show help', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const myapp = uniq('myapp');
|
const myapp = uniq('myapp');
|
||||||
runCLI(`generate @nrwl/web:app ${myapp}`);
|
runCLI(`generate @nrwl/web:app ${myapp}`);
|
||||||
|
|
||||||
@ -80,7 +79,7 @@ forEachCli('angular', () => {
|
|||||||
forEachCli(() => {
|
forEachCli(() => {
|
||||||
describe('report', () => {
|
describe('report', () => {
|
||||||
it(`should report package versions`, async () => {
|
it(`should report package versions`, async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
|
|
||||||
const reportOutput = runCommand('npm run nx report');
|
const reportOutput = runCommand('npm run nx report');
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
checkFilesExist,
|
checkFilesExist,
|
||||||
ensureProject,
|
|
||||||
forEachCli,
|
|
||||||
newProject,
|
newProject,
|
||||||
readFile,
|
readFile,
|
||||||
readJson,
|
readJson,
|
||||||
@ -11,63 +9,58 @@ import {
|
|||||||
updateFile,
|
updateFile,
|
||||||
} from '@nrwl/e2e/utils';
|
} from '@nrwl/e2e/utils';
|
||||||
|
|
||||||
forEachCli((currentCLIName) => {
|
describe('Cypress E2E Test runner', () => {
|
||||||
const linter = currentCLIName === 'angular' ? 'tslint' : 'eslint';
|
describe('project scaffolding', () => {
|
||||||
const nrwlPackageName = currentCLIName === 'angular' ? 'angular' : 'react';
|
it('should generate an app with the Cypress as e2e test runner', () => {
|
||||||
|
newProject();
|
||||||
|
const myapp = uniq('myapp');
|
||||||
|
runCLI(
|
||||||
|
`generate @nrwl/react:app ${myapp} --e2eTestRunner=cypress --linter=eslint`
|
||||||
|
);
|
||||||
|
|
||||||
describe('Cypress E2E Test runner', () => {
|
// Making sure the package.json file contains the Cypress dependency
|
||||||
describe('project scaffolding', () => {
|
const packageJson = readJson('package.json');
|
||||||
it('should generate an app with the Cypress as e2e test runner', () => {
|
expect(packageJson.devDependencies['cypress']).toBeTruthy();
|
||||||
ensureProject();
|
|
||||||
|
// Making sure the cypress folders & files are created
|
||||||
|
checkFilesExist(`apps/${myapp}-e2e/cypress.json`);
|
||||||
|
checkFilesExist(`apps/${myapp}-e2e/tsconfig.e2e.json`);
|
||||||
|
|
||||||
|
checkFilesExist(`apps/${myapp}-e2e/src/fixtures/example.json`);
|
||||||
|
checkFilesExist(`apps/${myapp}-e2e/src/integration/app.spec.ts`);
|
||||||
|
checkFilesExist(`apps/${myapp}-e2e/src/plugins/index.js`);
|
||||||
|
checkFilesExist(`apps/${myapp}-e2e/src/support/app.po.ts`);
|
||||||
|
checkFilesExist(`apps/${myapp}-e2e/src/support/index.ts`);
|
||||||
|
checkFilesExist(`apps/${myapp}-e2e/src/support/commands.ts`);
|
||||||
|
}, 1000000);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (supportUi()) {
|
||||||
|
describe('running Cypress', () => {
|
||||||
|
it('should execute e2e tests using Cypress', () => {
|
||||||
|
newProject();
|
||||||
const myapp = uniq('myapp');
|
const myapp = uniq('myapp');
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/${nrwlPackageName}:app ${myapp} --e2eTestRunner=cypress --linter=${linter}`
|
`generate @nrwl/react:app ${myapp} --e2eTestRunner=cypress --linter=eslint`
|
||||||
);
|
);
|
||||||
|
|
||||||
// Making sure the package.json file contains the Cypress dependency
|
expect(runCLI(`e2e ${myapp}-e2e --headless --no-watch`)).toContain(
|
||||||
const packageJson = readJson('package.json');
|
'All specs passed!'
|
||||||
expect(packageJson.devDependencies['cypress']).toBeTruthy();
|
);
|
||||||
|
|
||||||
// Making sure the cypress folders & files are created
|
const originalContents = JSON.parse(
|
||||||
checkFilesExist(`apps/${myapp}-e2e/cypress.json`);
|
readFile(`apps/${myapp}-e2e/cypress.json`)
|
||||||
checkFilesExist(`apps/${myapp}-e2e/tsconfig.e2e.json`);
|
);
|
||||||
|
delete originalContents.fixturesFolder;
|
||||||
|
updateFile(
|
||||||
|
`apps/${myapp}-e2e/cypress.json`,
|
||||||
|
JSON.stringify(originalContents)
|
||||||
|
);
|
||||||
|
|
||||||
checkFilesExist(`apps/${myapp}-e2e/src/fixtures/example.json`);
|
expect(runCLI(`e2e ${myapp}-e2e --headless --no-watch`)).toContain(
|
||||||
checkFilesExist(`apps/${myapp}-e2e/src/integration/app.spec.ts`);
|
'All specs passed!'
|
||||||
checkFilesExist(`apps/${myapp}-e2e/src/plugins/index.js`);
|
);
|
||||||
checkFilesExist(`apps/${myapp}-e2e/src/support/app.po.ts`);
|
|
||||||
checkFilesExist(`apps/${myapp}-e2e/src/support/index.ts`);
|
|
||||||
checkFilesExist(`apps/${myapp}-e2e/src/support/commands.ts`);
|
|
||||||
}, 1000000);
|
}, 1000000);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
if (supportUi()) {
|
|
||||||
describe('running Cypress', () => {
|
|
||||||
it('should execute e2e tests using Cypress', () => {
|
|
||||||
newProject();
|
|
||||||
const myapp = uniq('myapp');
|
|
||||||
runCLI(
|
|
||||||
`generate @nrwl/${nrwlPackageName}:app ${myapp} --e2eTestRunner=cypress --linter=${linter}`
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(runCLI(`e2e ${myapp}-e2e --headless --no-watch`)).toContain(
|
|
||||||
'All specs passed!'
|
|
||||||
);
|
|
||||||
|
|
||||||
const originalContents = JSON.parse(
|
|
||||||
readFile(`apps/${myapp}-e2e/cypress.json`)
|
|
||||||
);
|
|
||||||
delete originalContents.fixturesFolder;
|
|
||||||
updateFile(
|
|
||||||
`apps/${myapp}-e2e/cypress.json`,
|
|
||||||
JSON.stringify(originalContents)
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(runCLI(`e2e ${myapp}-e2e --headless --no-watch`)).toContain(
|
|
||||||
'All specs passed!'
|
|
||||||
);
|
|
||||||
}, 1000000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,61 +1,59 @@
|
|||||||
import { stripIndents } from '@angular-devkit/core/src/utils/literals';
|
import { stripIndents } from '@angular-devkit/core/src/utils/literals';
|
||||||
import {
|
import {
|
||||||
ensureProject,
|
newProject,
|
||||||
forEachCli,
|
|
||||||
runCLI,
|
runCLI,
|
||||||
runCLIAsync,
|
runCLIAsync,
|
||||||
uniq,
|
uniq,
|
||||||
updateFile,
|
updateFile,
|
||||||
} from '@nrwl/e2e/utils';
|
} from '@nrwl/e2e/utils';
|
||||||
|
|
||||||
forEachCli(() => {
|
describe('Jest', () => {
|
||||||
describe('Jest', () => {
|
it('should be able test projects using jest', async (done) => {
|
||||||
it('should be able test projects using jest', async (done) => {
|
newProject();
|
||||||
ensureProject();
|
const mylib = uniq('mylib');
|
||||||
const mylib = uniq('mylib');
|
const myapp = uniq('myapp');
|
||||||
const myapp = uniq('myapp');
|
runCLI(`generate @nrwl/angular:app ${myapp} --unit-test-runner jest`);
|
||||||
runCLI(`generate @nrwl/angular:app ${myapp} --unit-test-runner jest`);
|
runCLI(
|
||||||
runCLI(
|
`generate @nrwl/angular:lib ${mylib} --unit-test-runner jest --add-module-spec`
|
||||||
`generate @nrwl/angular:lib ${mylib} --unit-test-runner jest --add-module-spec`
|
);
|
||||||
);
|
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
runCLIAsync(`generate @nrwl/angular:service test --project ${myapp}`),
|
runCLIAsync(`generate @nrwl/angular:service test --project ${myapp}`),
|
||||||
runCLIAsync(`generate @nrwl/angular:component test --project ${myapp}`),
|
runCLIAsync(`generate @nrwl/angular:component test --project ${myapp}`),
|
||||||
runCLIAsync(`generate @nrwl/angular:service test --project ${mylib}`),
|
runCLIAsync(`generate @nrwl/angular:service test --project ${mylib}`),
|
||||||
runCLIAsync(`generate @nrwl/angular:component test --project ${mylib}`),
|
runCLIAsync(`generate @nrwl/angular:component test --project ${mylib}`),
|
||||||
]);
|
]);
|
||||||
const appResult = await runCLIAsync(`test ${myapp} --no-watch`);
|
const appResult = await runCLIAsync(`test ${myapp} --no-watch`);
|
||||||
expect(appResult.combinedOutput).toContain(
|
expect(appResult.combinedOutput).toContain(
|
||||||
'Test Suites: 3 passed, 3 total'
|
'Test Suites: 3 passed, 3 total'
|
||||||
);
|
);
|
||||||
const libResult = await runCLIAsync(`test ${mylib}`);
|
const libResult = await runCLIAsync(`test ${mylib}`);
|
||||||
expect(libResult.combinedOutput).toContain(
|
expect(libResult.combinedOutput).toContain(
|
||||||
'Test Suites: 3 passed, 3 total'
|
'Test Suites: 3 passed, 3 total'
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
}, 45000);
|
}, 45000);
|
||||||
|
|
||||||
it('should merge with jest config globals', async (done) => {
|
it('should merge with jest config globals', async (done) => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const testGlobal = `'My Test Global'`;
|
const testGlobal = `'My Test Global'`;
|
||||||
const mylib = uniq('mylib');
|
const mylib = uniq('mylib');
|
||||||
runCLI(`generate @nrwl/workspace:lib ${mylib} --unit-test-runner jest`);
|
runCLI(`generate @nrwl/workspace:lib ${mylib} --unit-test-runner jest`);
|
||||||
|
|
||||||
updateFile(`libs/${mylib}/src/lib/${mylib}.ts`, `export class Test { }`);
|
updateFile(`libs/${mylib}/src/lib/${mylib}.ts`, `export class Test { }`);
|
||||||
|
|
||||||
updateFile(
|
updateFile(
|
||||||
`libs/${mylib}/src/lib/${mylib}.spec.ts`,
|
`libs/${mylib}/src/lib/${mylib}.spec.ts`,
|
||||||
`
|
`
|
||||||
test('can access jest global', () => {
|
test('can access jest global', () => {
|
||||||
expect((global as any).testGlobal).toBe(${testGlobal});
|
expect((global as any).testGlobal).toBe(${testGlobal});
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
updateFile(
|
updateFile(
|
||||||
`libs/${mylib}/jest.config.js`,
|
`libs/${mylib}/jest.config.js`,
|
||||||
stripIndents`
|
stripIndents`
|
||||||
module.exports = {
|
module.exports = {
|
||||||
testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
|
testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
|
||||||
transform: {
|
transform: {
|
||||||
@ -67,57 +65,56 @@ forEachCli(() => {
|
|||||||
passWithNoTests: true,
|
passWithNoTests: true,
|
||||||
globals: { testGlobal: ${testGlobal} }
|
globals: { testGlobal: ${testGlobal} }
|
||||||
};`
|
};`
|
||||||
);
|
);
|
||||||
|
|
||||||
const appResult = await runCLIAsync(`test ${mylib} --no-watch`);
|
const appResult = await runCLIAsync(`test ${mylib} --no-watch`);
|
||||||
expect(appResult.combinedOutput).toContain(
|
expect(appResult.combinedOutput).toContain(
|
||||||
'Test Suites: 1 passed, 1 total'
|
'Test Suites: 1 passed, 1 total'
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
}, 45000);
|
}, 45000);
|
||||||
|
|
||||||
it('should set the NODE_ENV to `test`', async (done) => {
|
it('should set the NODE_ENV to `test`', async (done) => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const mylib = uniq('mylib');
|
const mylib = uniq('mylib');
|
||||||
runCLI(`generate @nrwl/workspace:lib ${mylib} --unit-test-runner jest`);
|
runCLI(`generate @nrwl/workspace:lib ${mylib} --unit-test-runner jest`);
|
||||||
|
|
||||||
updateFile(
|
updateFile(
|
||||||
`libs/${mylib}/src/lib/${mylib}.spec.ts`,
|
`libs/${mylib}/src/lib/${mylib}.spec.ts`,
|
||||||
`
|
`
|
||||||
test('can access jest global', () => {
|
test('can access jest global', () => {
|
||||||
expect(process.env.NODE_ENV).toBe('test');
|
expect(process.env.NODE_ENV).toBe('test');
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
const appResult = await runCLIAsync(`test ${mylib} --no-watch`);
|
const appResult = await runCLIAsync(`test ${mylib} --no-watch`);
|
||||||
expect(appResult.combinedOutput).toContain(
|
expect(appResult.combinedOutput).toContain(
|
||||||
'Test Suites: 1 passed, 1 total'
|
'Test Suites: 1 passed, 1 total'
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
}, 45000);
|
}, 45000);
|
||||||
|
|
||||||
it('should support multiple `coverageReporters` through CLI', async (done) => {
|
it('should support multiple `coverageReporters` through CLI', async (done) => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const mylib = uniq('mylib');
|
const mylib = uniq('mylib');
|
||||||
runCLI(`generate @nrwl/workspace:lib ${mylib} --unit-test-runner jest`);
|
runCLI(`generate @nrwl/workspace:lib ${mylib} --unit-test-runner jest`);
|
||||||
|
|
||||||
updateFile(
|
updateFile(
|
||||||
`libs/${mylib}/src/lib/${mylib}.spec.ts`,
|
`libs/${mylib}/src/lib/${mylib}.spec.ts`,
|
||||||
`
|
`
|
||||||
test('can access jest global', () => {
|
test('can access jest global', () => {
|
||||||
expect(true).toBe(true);
|
expect(true).toBe(true);
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
const result = await runCLIAsync(
|
const result = await runCLIAsync(
|
||||||
`test ${mylib} --no-watch --code-coverage --coverageReporters=text --coverageReporters=text-summary`
|
`test ${mylib} --no-watch --code-coverage --coverageReporters=text --coverageReporters=text-summary`
|
||||||
);
|
);
|
||||||
expect(result.stdout).toContain(
|
expect(result.stdout).toContain(
|
||||||
'File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s'
|
'File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s'
|
||||||
); // text
|
); // text
|
||||||
expect(result.stdout).toContain('Coverage summary'); // text-summary
|
expect(result.stdout).toContain('Coverage summary'); // text-summary
|
||||||
done();
|
done();
|
||||||
}, 45000);
|
}, 45000);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,215 +4,175 @@ import {
|
|||||||
readFile,
|
readFile,
|
||||||
readJson,
|
readJson,
|
||||||
runCLI,
|
runCLI,
|
||||||
updateFile,
|
|
||||||
ensureProject,
|
|
||||||
uniq,
|
uniq,
|
||||||
forEachCli,
|
updateFile,
|
||||||
} from '@nrwl/e2e/utils';
|
} from '@nrwl/e2e/utils';
|
||||||
|
|
||||||
forEachCli('nx', () => {
|
describe('Linter', () => {
|
||||||
describe('Linter', () => {
|
it('linting should error when rules are not followed', () => {
|
||||||
it('linting should error when rules are not followed', () => {
|
|
||||||
ensureProject();
|
|
||||||
const myapp = uniq('myapp');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/react:app ${myapp}`);
|
|
||||||
|
|
||||||
const eslintrc = readJson('.eslintrc.json');
|
|
||||||
eslintrc.overrides.forEach((override) => {
|
|
||||||
if (override.files.includes('*.ts')) {
|
|
||||||
override.rules['no-console'] = 'error';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
updateFile('.eslintrc.json', JSON.stringify(eslintrc, null, 2));
|
|
||||||
|
|
||||||
updateFile(`apps/${myapp}/src/main.ts`, `console.log("should fail");`);
|
|
||||||
|
|
||||||
const out = runCLI(`lint ${myapp}`, { silenceError: true });
|
|
||||||
expect(out).toContain('Unexpected console statement');
|
|
||||||
}, 1000000);
|
|
||||||
|
|
||||||
it('linting should not error when rules are not followed and the force flag is specified', () => {
|
|
||||||
ensureProject();
|
|
||||||
const myapp = uniq('myapp');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/react:app ${myapp}`);
|
|
||||||
|
|
||||||
const eslintrc = readJson('.eslintrc.json');
|
|
||||||
eslintrc.overrides.forEach((override) => {
|
|
||||||
if (override.files.includes('*.ts')) {
|
|
||||||
override.rules['no-console'] = 'error';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
updateFile('.eslintrc.json', JSON.stringify(eslintrc, null, 2));
|
|
||||||
|
|
||||||
updateFile(`apps/${myapp}/src/main.ts`, `console.log("should fail");`);
|
|
||||||
|
|
||||||
expect(() => runCLI(`lint ${myapp} --force`)).not.toThrow();
|
|
||||||
}, 1000000);
|
|
||||||
|
|
||||||
it('linting should not error when all rules are followed', () => {
|
|
||||||
ensureProject();
|
|
||||||
const myapp = uniq('myapp');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/react:app ${myapp}`);
|
|
||||||
|
|
||||||
const eslintrc = readJson('.eslintrc.json');
|
|
||||||
eslintrc.overrides.forEach((override) => {
|
|
||||||
if (override.files.includes('*.ts')) {
|
|
||||||
override.rules['no-console'] = undefined;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
updateFile('.eslintrc.json', JSON.stringify(eslintrc, null, 2));
|
|
||||||
|
|
||||||
updateFile(`apps/${myapp}/src/main.ts`, `console.log("should fail");`);
|
|
||||||
|
|
||||||
const out = runCLI(`lint ${myapp}`, { silenceError: true });
|
|
||||||
expect(out).toContain('All files pass linting');
|
|
||||||
}, 1000000);
|
|
||||||
|
|
||||||
it('linting should error when an invalid linter is specified', () => {
|
|
||||||
ensureProject();
|
|
||||||
const myapp = uniq('myapp');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/react:app ${myapp}`);
|
|
||||||
|
|
||||||
// This test is only relevant for the deprecated lint builder,
|
|
||||||
// so we need to patch the workspace.json to use it
|
|
||||||
const workspaceJson = readJson(`workspace.json`);
|
|
||||||
workspaceJson.projects[myapp].architect.lint = {
|
|
||||||
builder: '@nrwl/linter:lint',
|
|
||||||
options: {
|
|
||||||
linter: 'eslint',
|
|
||||||
tsConfig: [
|
|
||||||
`apps/${myapp}/tsconfig.app.json`,
|
|
||||||
`apps/${myapp}/tsconfig.spec.json`,
|
|
||||||
],
|
|
||||||
exclude: ['**/node_modules/**', `!apps/${myapp}/**/*`],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
updateFile('workspace.json', JSON.stringify(workspaceJson, null, 2));
|
|
||||||
|
|
||||||
const eslintrc = readJson('.eslintrc.json');
|
|
||||||
eslintrc.overrides.forEach((override) => {
|
|
||||||
if (override.files.includes('*.ts')) {
|
|
||||||
override.rules['no-console'] = undefined;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
updateFile('.eslintrc.json', JSON.stringify(eslintrc, null, 2));
|
|
||||||
|
|
||||||
updateFile(`apps/${myapp}/src/main.ts`, `console.log("should fail");`);
|
|
||||||
|
|
||||||
expect(() => runCLI(`lint ${myapp} --linter=tslint`)).toThrow(
|
|
||||||
/'tslint' option is no longer supported/
|
|
||||||
);
|
|
||||||
expect(() => runCLI(`lint ${myapp} --linter=random`)).toThrow(
|
|
||||||
/Schema validation failed/
|
|
||||||
);
|
|
||||||
}, 1000000);
|
|
||||||
|
|
||||||
it('linting should generate a default cache file', () => {
|
|
||||||
newProject();
|
|
||||||
const myapp = uniq('myapp');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/react:app ${myapp}`);
|
|
||||||
|
|
||||||
expect(() => checkFilesExist(`.eslintcache`)).toThrow();
|
|
||||||
runCLI(`lint ${myapp} --cache`, { silenceError: true });
|
|
||||||
expect(() => checkFilesExist(`.eslintcache`)).not.toThrow();
|
|
||||||
const cacheInfo = readFile('.eslintcache');
|
|
||||||
expect(cacheInfo).toContain(`${myapp}/src/app/app.spec.tsx`);
|
|
||||||
}, 1000000);
|
|
||||||
|
|
||||||
it('linting should let you specify a cache file location', () => {
|
|
||||||
newProject();
|
|
||||||
const myapp = uniq('myapp');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/react:app ${myapp}`);
|
|
||||||
|
|
||||||
expect(() => checkFilesExist(`my-cache`)).toThrow();
|
|
||||||
runCLI(`lint ${myapp} --cache --cache-location="my-cache"`, {
|
|
||||||
silenceError: true,
|
|
||||||
});
|
|
||||||
expect(() => checkFilesExist(`my-cache`)).not.toThrow();
|
|
||||||
const cacheInfo = readFile('my-cache');
|
|
||||||
expect(cacheInfo).toContain(`${myapp}/src/app/app.spec.tsx`);
|
|
||||||
}, 1000000);
|
|
||||||
|
|
||||||
it('linting should generate an output file with a specific format', () => {
|
|
||||||
newProject();
|
|
||||||
const myapp = uniq('myapp');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/react:app ${myapp}`);
|
|
||||||
|
|
||||||
const eslintrc = readJson('.eslintrc.json');
|
|
||||||
eslintrc.overrides.forEach((override) => {
|
|
||||||
if (override.files.includes('*.ts')) {
|
|
||||||
override.rules['no-console'] = 'error';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
updateFile('.eslintrc.json', JSON.stringify(eslintrc, null, 2));
|
|
||||||
updateFile(`apps/${myapp}/src/main.ts`, `console.log("should fail");`);
|
|
||||||
|
|
||||||
const outputFile = 'a/b/c/lint-output.json';
|
|
||||||
expect(() => {
|
|
||||||
checkFilesExist(outputFile);
|
|
||||||
}).toThrow();
|
|
||||||
const stdout = runCLI(
|
|
||||||
`lint ${myapp} --output-file="${outputFile}" --format=json`,
|
|
||||||
{
|
|
||||||
silenceError: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
expect(stdout).toContain('Unexpected console statement');
|
|
||||||
expect(() => checkFilesExist(outputFile)).not.toThrow();
|
|
||||||
const outputContents = JSON.parse(readFile(outputFile));
|
|
||||||
const outputForApp: any = Object.values(
|
|
||||||
outputContents
|
|
||||||
).filter((result: any) =>
|
|
||||||
result.filePath.includes(`${myapp}/src/main.ts`)
|
|
||||||
)[0];
|
|
||||||
expect(outputForApp.errorCount).toBe(1);
|
|
||||||
expect(outputForApp.messages[0].ruleId).toBe('no-console');
|
|
||||||
expect(outputForApp.messages[0].message).toBe(
|
|
||||||
'Unexpected console statement.'
|
|
||||||
);
|
|
||||||
}, 1000000);
|
|
||||||
});
|
|
||||||
|
|
||||||
// bad test. fix and reenable
|
|
||||||
xit('supports warning options', () => {
|
|
||||||
newProject();
|
newProject();
|
||||||
const myapp = uniq('myapp');
|
const myapp = uniq('myapp');
|
||||||
|
|
||||||
runCLI(`generate @nrwl/react:app ${myapp}`);
|
runCLI(`generate @nrwl/react:app ${myapp}`);
|
||||||
|
|
||||||
const eslintrc = readJson(`apps/${myapp}/.eslintrc.json`);
|
const eslintrc = readJson('.eslintrc.json');
|
||||||
eslintrc.rules['no-console'] = 'warn';
|
eslintrc.overrides.forEach((override) => {
|
||||||
updateFile(
|
if (override.files.includes('*.ts')) {
|
||||||
`apps/${myapp}/.eslintrc.json`,
|
override.rules['no-console'] = 'error';
|
||||||
JSON.stringify(eslintrc, null, 2)
|
}
|
||||||
);
|
});
|
||||||
updateFile(
|
updateFile('.eslintrc.json', JSON.stringify(eslintrc, null, 2));
|
||||||
`apps/${myapp}/src/main.ts`,
|
|
||||||
`console.log('once'); console.log('twice');`
|
|
||||||
);
|
|
||||||
|
|
||||||
let output = runCLI(`lint ${myapp}`, { silenceError: true });
|
updateFile(`apps/${myapp}/src/main.ts`, `console.log("should fail");`);
|
||||||
expect(output).toMatch(/warnings found/);
|
|
||||||
output = runCLI(`lint ${myapp} --maxWarning=1`, { silenceError: true });
|
const out = runCLI(`lint ${myapp}`, { silenceError: true });
|
||||||
expect(output).toMatch(/warnings found/);
|
expect(out).toContain('Unexpected console statement');
|
||||||
output = runCLI(`lint ${myapp} --maxWarning=3`, { silenceError: true });
|
}, 1000000);
|
||||||
expect(output).not.toMatch(/warnings found/);
|
|
||||||
output = runCLI(`lint ${myapp} --quiet`, { silenceError: true });
|
it('linting should not error when rules are not followed and the force flag is specified', () => {
|
||||||
expect(output).not.toMatch(/warnings found/);
|
newProject();
|
||||||
|
const myapp = uniq('myapp');
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/react:app ${myapp}`);
|
||||||
|
|
||||||
|
const eslintrc = readJson('.eslintrc.json');
|
||||||
|
eslintrc.overrides.forEach((override) => {
|
||||||
|
if (override.files.includes('*.ts')) {
|
||||||
|
override.rules['no-console'] = 'error';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
updateFile('.eslintrc.json', JSON.stringify(eslintrc, null, 2));
|
||||||
|
|
||||||
|
updateFile(`apps/${myapp}/src/main.ts`, `console.log("should fail");`);
|
||||||
|
|
||||||
|
expect(() => runCLI(`lint ${myapp} --force`)).not.toThrow();
|
||||||
|
}, 1000000);
|
||||||
|
|
||||||
|
it('linting should not error when all rules are followed', () => {
|
||||||
|
newProject();
|
||||||
|
const myapp = uniq('myapp');
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/react:app ${myapp}`);
|
||||||
|
|
||||||
|
const eslintrc = readJson('.eslintrc.json');
|
||||||
|
eslintrc.overrides.forEach((override) => {
|
||||||
|
if (override.files.includes('*.ts')) {
|
||||||
|
override.rules['no-console'] = undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
updateFile('.eslintrc.json', JSON.stringify(eslintrc, null, 2));
|
||||||
|
|
||||||
|
updateFile(`apps/${myapp}/src/main.ts`, `console.log("should fail");`);
|
||||||
|
|
||||||
|
const out = runCLI(`lint ${myapp}`, { silenceError: true });
|
||||||
|
expect(out).toContain('All files pass linting');
|
||||||
|
}, 1000000);
|
||||||
|
|
||||||
|
it('linting should error when an invalid linter is specified', () => {
|
||||||
|
newProject();
|
||||||
|
const myapp = uniq('myapp');
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/react:app ${myapp}`);
|
||||||
|
|
||||||
|
// This test is only relevant for the deprecated lint builder,
|
||||||
|
// so we need to patch the workspace.json to use it
|
||||||
|
const workspaceJson = readJson(`workspace.json`);
|
||||||
|
workspaceJson.projects[myapp].architect.lint = {
|
||||||
|
builder: '@nrwl/linter:lint',
|
||||||
|
options: {
|
||||||
|
linter: 'eslint',
|
||||||
|
tsConfig: [
|
||||||
|
`apps/${myapp}/tsconfig.app.json`,
|
||||||
|
`apps/${myapp}/tsconfig.spec.json`,
|
||||||
|
],
|
||||||
|
exclude: ['**/node_modules/**', `!apps/${myapp}/**/*`],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
updateFile('workspace.json', JSON.stringify(workspaceJson, null, 2));
|
||||||
|
|
||||||
|
const eslintrc = readJson('.eslintrc.json');
|
||||||
|
eslintrc.overrides.forEach((override) => {
|
||||||
|
if (override.files.includes('*.ts')) {
|
||||||
|
override.rules['no-console'] = undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
updateFile('.eslintrc.json', JSON.stringify(eslintrc, null, 2));
|
||||||
|
|
||||||
|
updateFile(`apps/${myapp}/src/main.ts`, `console.log("should fail");`);
|
||||||
|
|
||||||
|
expect(() => runCLI(`lint ${myapp} --linter=tslint`)).toThrow(
|
||||||
|
/'tslint' option is no longer supported/
|
||||||
|
);
|
||||||
|
expect(() => runCLI(`lint ${myapp} --linter=random`)).toThrow(
|
||||||
|
/Schema validation failed/
|
||||||
|
);
|
||||||
|
}, 1000000);
|
||||||
|
|
||||||
|
it('linting should generate a default cache file', () => {
|
||||||
|
newProject();
|
||||||
|
const myapp = uniq('myapp');
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/react:app ${myapp}`);
|
||||||
|
|
||||||
|
expect(() => checkFilesExist(`.eslintcache`)).toThrow();
|
||||||
|
runCLI(`lint ${myapp} --cache`, { silenceError: true });
|
||||||
|
expect(() => checkFilesExist(`.eslintcache`)).not.toThrow();
|
||||||
|
const cacheInfo = readFile('.eslintcache');
|
||||||
|
expect(cacheInfo).toContain(`${myapp}/src/app/app.spec.tsx`);
|
||||||
|
}, 1000000);
|
||||||
|
|
||||||
|
it('linting should let you specify a cache file location', () => {
|
||||||
|
newProject();
|
||||||
|
const myapp = uniq('myapp');
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/react:app ${myapp}`);
|
||||||
|
|
||||||
|
expect(() => checkFilesExist(`my-cache`)).toThrow();
|
||||||
|
runCLI(`lint ${myapp} --cache --cache-location="my-cache"`, {
|
||||||
|
silenceError: true,
|
||||||
|
});
|
||||||
|
expect(() => checkFilesExist(`my-cache`)).not.toThrow();
|
||||||
|
const cacheInfo = readFile('my-cache');
|
||||||
|
expect(cacheInfo).toContain(`${myapp}/src/app/app.spec.tsx`);
|
||||||
|
}, 1000000);
|
||||||
|
|
||||||
|
it('linting should generate an output file with a specific format', () => {
|
||||||
|
newProject();
|
||||||
|
const myapp = uniq('myapp');
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/react:app ${myapp}`);
|
||||||
|
|
||||||
|
const eslintrc = readJson('.eslintrc.json');
|
||||||
|
eslintrc.overrides.forEach((override) => {
|
||||||
|
if (override.files.includes('*.ts')) {
|
||||||
|
override.rules['no-console'] = 'error';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
updateFile('.eslintrc.json', JSON.stringify(eslintrc, null, 2));
|
||||||
|
updateFile(`apps/${myapp}/src/main.ts`, `console.log("should fail");`);
|
||||||
|
|
||||||
|
const outputFile = 'a/b/c/lint-output.json';
|
||||||
|
expect(() => {
|
||||||
|
checkFilesExist(outputFile);
|
||||||
|
}).toThrow();
|
||||||
|
const stdout = runCLI(
|
||||||
|
`lint ${myapp} --output-file="${outputFile}" --format=json`,
|
||||||
|
{
|
||||||
|
silenceError: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
expect(stdout).toContain('Unexpected console statement');
|
||||||
|
expect(() => checkFilesExist(outputFile)).not.toThrow();
|
||||||
|
const outputContents = JSON.parse(readFile(outputFile));
|
||||||
|
const outputForApp: any = Object.values(
|
||||||
|
outputContents
|
||||||
|
).filter((result: any) =>
|
||||||
|
result.filePath.includes(`${myapp}/src/main.ts`)
|
||||||
|
)[0];
|
||||||
|
expect(outputForApp.errorCount).toBe(1);
|
||||||
|
expect(outputForApp.messages[0].ruleId).toBe('no-console');
|
||||||
|
expect(outputForApp.messages[0].message).toBe(
|
||||||
|
'Unexpected console statement.'
|
||||||
|
);
|
||||||
}, 1000000);
|
}, 1000000);
|
||||||
});
|
});
|
||||||
|
|
||||||
forEachCli('angular', () => {
|
|
||||||
describe('Linter', () => {
|
|
||||||
it('empty test', () => {
|
|
||||||
expect(1).toEqual(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import { stringUtils } from '@nrwl/workspace';
|
import { stringUtils } from '@nrwl/workspace';
|
||||||
import {
|
import {
|
||||||
checkFilesExist,
|
checkFilesExist,
|
||||||
ensureProject,
|
newProject,
|
||||||
forEachCli,
|
|
||||||
readFile,
|
readFile,
|
||||||
readJson,
|
readJson,
|
||||||
runCLI,
|
runCLI,
|
||||||
@ -11,27 +10,26 @@ import {
|
|||||||
updateFile,
|
updateFile,
|
||||||
} from '@nrwl/e2e/utils';
|
} from '@nrwl/e2e/utils';
|
||||||
|
|
||||||
forEachCli('nx', () => {
|
describe('Next.js Applications', () => {
|
||||||
describe('Next.js Applications', () => {
|
it('should be able to serve with a proxy configuration', async () => {
|
||||||
it('should be able to serve with a proxy configuration', async () => {
|
newProject();
|
||||||
ensureProject();
|
const appName = uniq('app');
|
||||||
const appName = uniq('app');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/next:app ${appName} --no-interactive`);
|
runCLI(`generate @nrwl/next:app ${appName} --no-interactive`);
|
||||||
|
|
||||||
const proxyConf = {
|
const proxyConf = {
|
||||||
'/external-api': {
|
'/external-api': {
|
||||||
target: 'http://localhost:4200',
|
target: 'http://localhost:4200',
|
||||||
pathRewrite: {
|
pathRewrite: {
|
||||||
'^/external-api/hello': '/api/hello',
|
'^/external-api/hello': '/api/hello',
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
},
|
||||||
updateFile(`apps/${appName}/proxy.conf.json`, JSON.stringify(proxyConf));
|
};
|
||||||
|
updateFile(`apps/${appName}/proxy.conf.json`, JSON.stringify(proxyConf));
|
||||||
|
|
||||||
updateFile(
|
updateFile(
|
||||||
`apps/${appName}-e2e/src/integration/app.spec.ts`,
|
`apps/${appName}-e2e/src/integration/app.spec.ts`,
|
||||||
`
|
`
|
||||||
describe('next-app', () => {
|
describe('next-app', () => {
|
||||||
beforeEach(() => cy.visit('/'));
|
beforeEach(() => cy.visit('/'));
|
||||||
|
|
||||||
@ -40,11 +38,11 @@ forEachCli('nx', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
updateFile(
|
updateFile(
|
||||||
`apps/${appName}/pages/index.tsx`,
|
`apps/${appName}/pages/index.tsx`,
|
||||||
`
|
`
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
export const Index = () => {
|
export const Index = () => {
|
||||||
@ -60,109 +58,105 @@ forEachCli('nx', () => {
|
|||||||
};
|
};
|
||||||
export default Index;
|
export default Index;
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
updateFile(
|
updateFile(
|
||||||
`apps/${appName}/pages/api/hello.js`,
|
`apps/${appName}/pages/api/hello.js`,
|
||||||
`
|
`
|
||||||
export default (_req, res) => {
|
export default (_req, res) => {
|
||||||
res.status(200).send('Hello Next.js!');
|
res.status(200).send('Hello Next.js!');
|
||||||
};
|
};
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
}, 120000);
|
}, 120000);
|
||||||
|
|
||||||
it('should be able to consume a react lib', async () => {
|
it('should be able to consume a react lib', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const appName = uniq('app');
|
const appName = uniq('app');
|
||||||
const libName = uniq('lib');
|
const libName = uniq('lib');
|
||||||
|
|
||||||
runCLI(`generate @nrwl/next:app ${appName} --no-interactive`);
|
runCLI(`generate @nrwl/next:app ${appName} --no-interactive`);
|
||||||
|
|
||||||
runCLI(
|
runCLI(`generate @nrwl/react:lib ${libName} --no-interactive --style=none`);
|
||||||
`generate @nrwl/react:lib ${libName} --no-interactive --style=none`
|
|
||||||
);
|
|
||||||
|
|
||||||
const mainPath = `apps/${appName}/pages/index.tsx`;
|
const mainPath = `apps/${appName}/pages/index.tsx`;
|
||||||
updateFile(mainPath, `import '@proj/${libName}';\n` + readFile(mainPath));
|
updateFile(mainPath, `import '@proj/${libName}';\n` + readFile(mainPath));
|
||||||
|
|
||||||
// Update lib to use css modules
|
// Update lib to use css modules
|
||||||
updateFile(
|
updateFile(
|
||||||
`libs/${libName}/src/lib/${libName}.tsx`,
|
`libs/${libName}/src/lib/${libName}.tsx`,
|
||||||
`
|
`
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styles from './style.module.css';
|
import styles from './style.module.css';
|
||||||
export function Test() {
|
export function Test() {
|
||||||
return <div className={styles.container}>Hello</div>;
|
return <div className={styles.container}>Hello</div>;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
updateFile(
|
updateFile(
|
||||||
`libs/${libName}/src/lib/style.module.css`,
|
`libs/${libName}/src/lib/style.module.css`,
|
||||||
`
|
`
|
||||||
.container {}
|
.container {}
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
await checkApp(appName, {
|
await checkApp(appName, {
|
||||||
checkUnitTest: true,
|
checkUnitTest: true,
|
||||||
checkLint: true,
|
checkLint: true,
|
||||||
checkE2E: false,
|
checkE2E: false,
|
||||||
});
|
});
|
||||||
}, 120000);
|
}, 120000);
|
||||||
|
|
||||||
it('should be able to dynamically load a lib', async () => {
|
it('should be able to dynamically load a lib', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const appName = uniq('app');
|
const appName = uniq('app');
|
||||||
const libName = uniq('lib');
|
const libName = uniq('lib');
|
||||||
|
|
||||||
runCLI(`generate @nrwl/next:app ${appName} --no-interactive`);
|
runCLI(`generate @nrwl/next:app ${appName} --no-interactive`);
|
||||||
runCLI(
|
runCLI(`generate @nrwl/react:lib ${libName} --no-interactive --style=none`);
|
||||||
`generate @nrwl/react:lib ${libName} --no-interactive --style=none`
|
|
||||||
);
|
|
||||||
|
|
||||||
const mainPath = `apps/${appName}/pages/index.tsx`;
|
const mainPath = `apps/${appName}/pages/index.tsx`;
|
||||||
updateFile(
|
updateFile(
|
||||||
mainPath,
|
mainPath,
|
||||||
`
|
`
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
const DynamicComponent = dynamic(
|
const DynamicComponent = dynamic(
|
||||||
() => import('@proj/${libName}').then(d => d.${stringUtils.capitalize(
|
() => import('@proj/${libName}').then(d => d.${stringUtils.capitalize(
|
||||||
libName
|
libName
|
||||||
)})
|
)})
|
||||||
);
|
);
|
||||||
` + readFile(mainPath)
|
` + readFile(mainPath)
|
||||||
);
|
);
|
||||||
|
|
||||||
await checkApp(appName, {
|
await checkApp(appName, {
|
||||||
checkUnitTest: false,
|
checkUnitTest: false,
|
||||||
checkLint: false,
|
checkLint: false,
|
||||||
checkE2E: true,
|
checkE2E: true,
|
||||||
});
|
});
|
||||||
}, 120000);
|
}, 120000);
|
||||||
|
|
||||||
it('should compile when using a workspace and react lib written in TypeScript', async () => {
|
it('should compile when using a workspace and react lib written in TypeScript', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const appName = uniq('app');
|
const appName = uniq('app');
|
||||||
const tsLibName = uniq('tslib');
|
const tsLibName = uniq('tslib');
|
||||||
const tsxLibName = uniq('tsxlib');
|
const tsxLibName = uniq('tsxlib');
|
||||||
|
|
||||||
runCLI(`generate @nrwl/next:app ${appName} --no-interactive`);
|
runCLI(`generate @nrwl/next:app ${appName} --no-interactive`);
|
||||||
runCLI(`generate @nrwl/react:lib ${tsxLibName} --no-interactive`);
|
runCLI(`generate @nrwl/react:lib ${tsxLibName} --no-interactive`);
|
||||||
runCLI(`generate @nrwl/workspace:lib ${tsLibName} --no-interactive`);
|
runCLI(`generate @nrwl/workspace:lib ${tsLibName} --no-interactive`);
|
||||||
|
|
||||||
updateFile(
|
updateFile(
|
||||||
`libs/${tsLibName}/src/lib/${tsLibName}.ts`,
|
`libs/${tsLibName}/src/lib/${tsLibName}.ts`,
|
||||||
`
|
`
|
||||||
export function testFn(): string {
|
export function testFn(): string {
|
||||||
return 'Hello Nx';
|
return 'Hello Nx';
|
||||||
};
|
};
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
updateFile(
|
updateFile(
|
||||||
`libs/${tsxLibName}/src/lib/${tsxLibName}.tsx`,
|
`libs/${tsxLibName}/src/lib/${tsxLibName}.tsx`,
|
||||||
`
|
`
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
interface TestComponentProps {
|
interface TestComponentProps {
|
||||||
@ -175,77 +169,76 @@ forEachCli('nx', () => {
|
|||||||
|
|
||||||
export default TestComponent;
|
export default TestComponent;
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
const mainPath = `apps/${appName}/pages/index.tsx`;
|
const mainPath = `apps/${appName}/pages/index.tsx`;
|
||||||
const content = readFile(mainPath);
|
const content = readFile(mainPath);
|
||||||
|
|
||||||
updateFile(
|
updateFile(
|
||||||
mainPath,
|
mainPath,
|
||||||
`
|
`
|
||||||
import { testFn } from '@proj/${tsLibName}';
|
import { testFn } from '@proj/${tsLibName}';
|
||||||
import { TestComponent } from '@proj/${tsxLibName}';\n\n
|
import { TestComponent } from '@proj/${tsxLibName}';\n\n
|
||||||
` +
|
` +
|
||||||
content.replace(
|
content.replace(
|
||||||
`</h2>`,
|
`</h2>`,
|
||||||
`</h2>
|
`</h2>
|
||||||
<div>
|
<div>
|
||||||
{testFn()}
|
{testFn()}
|
||||||
<TestComponent text="Hello Next.JS" />
|
<TestComponent text="Hello Next.JS" />
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
await checkApp(appName, {
|
await checkApp(appName, {
|
||||||
checkUnitTest: true,
|
checkUnitTest: true,
|
||||||
checkLint: true,
|
checkLint: true,
|
||||||
checkE2E: false,
|
checkE2E: false,
|
||||||
});
|
});
|
||||||
}, 120000);
|
}, 120000);
|
||||||
|
|
||||||
it('should support --style=styled-components', async () => {
|
it('should support --style=styled-components', async () => {
|
||||||
const appName = uniq('app');
|
const appName = uniq('app');
|
||||||
|
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/next:app ${appName} --no-interactive --style=styled-components`
|
`generate @nrwl/next:app ${appName} --no-interactive --style=styled-components`
|
||||||
);
|
);
|
||||||
|
|
||||||
await checkApp(appName, {
|
await checkApp(appName, {
|
||||||
checkUnitTest: true,
|
checkUnitTest: true,
|
||||||
checkLint: false,
|
checkLint: false,
|
||||||
checkE2E: false,
|
checkE2E: false,
|
||||||
});
|
});
|
||||||
}, 120000);
|
}, 120000);
|
||||||
|
|
||||||
it('should support --style=@emotion/styled', async () => {
|
it('should support --style=@emotion/styled', async () => {
|
||||||
const appName = uniq('app');
|
const appName = uniq('app');
|
||||||
|
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/next:app ${appName} --no-interactive --style=@emotion/styled`
|
`generate @nrwl/next:app ${appName} --no-interactive --style=@emotion/styled`
|
||||||
);
|
);
|
||||||
|
|
||||||
await checkApp(appName, {
|
await checkApp(appName, {
|
||||||
checkUnitTest: true,
|
checkUnitTest: true,
|
||||||
checkLint: false,
|
checkLint: false,
|
||||||
checkE2E: false,
|
checkE2E: false,
|
||||||
});
|
});
|
||||||
}, 120000);
|
}, 120000);
|
||||||
|
|
||||||
it('should build with public folder', async () => {
|
it('should build with public folder', async () => {
|
||||||
const appName = uniq('app');
|
const appName = uniq('app');
|
||||||
|
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/next:app ${appName} --no-interactive --style=@emotion/styled`
|
`generate @nrwl/next:app ${appName} --no-interactive --style=@emotion/styled`
|
||||||
);
|
);
|
||||||
|
|
||||||
updateFile(`apps/${appName}/public/a/b.txt`, `Hello World!`);
|
updateFile(`apps/${appName}/public/a/b.txt`, `Hello World!`);
|
||||||
|
|
||||||
runCLI(`build ${appName}`);
|
runCLI(`build ${appName}`);
|
||||||
|
|
||||||
checkFilesExist(`dist/apps/${appName}/public/a/b.txt`);
|
checkFilesExist(`dist/apps/${appName}/public/a/b.txt`);
|
||||||
}, 120000);
|
}, 120000);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async function checkApp(
|
async function checkApp(
|
||||||
@ -279,12 +272,6 @@ async function checkApp(
|
|||||||
expect(packageJson.dependencies['react-dom']).toBeDefined();
|
expect(packageJson.dependencies['react-dom']).toBeDefined();
|
||||||
expect(packageJson.dependencies.next).toBeDefined();
|
expect(packageJson.dependencies.next).toBeDefined();
|
||||||
|
|
||||||
const exportResult = runCLI(`export ${appName}`);
|
runCLI(`export ${appName}`);
|
||||||
checkFilesExist(`dist/apps/${appName}/exported/index.html`);
|
checkFilesExist(`dist/apps/${appName}/exported/index.html`);
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachCli('angular', () => {
|
|
||||||
describe('next', () => {
|
|
||||||
it('is not supported', () => {});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|||||||
@ -1,25 +1,20 @@
|
|||||||
import { stripIndents } from '@angular-devkit/core/src/utils/literals';
|
import { stripIndents } from '@angular-devkit/core/src/utils/literals';
|
||||||
import { execSync, fork, spawn } from 'child_process';
|
import { execSync, fork, spawn } from 'child_process';
|
||||||
import * as http from 'http';
|
import * as http from 'http';
|
||||||
import * as path from 'path';
|
|
||||||
import * as treeKill from 'tree-kill';
|
import * as treeKill from 'tree-kill';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
import {
|
import {
|
||||||
checkFilesDoNotExist,
|
checkFilesDoNotExist,
|
||||||
checkFilesExist,
|
checkFilesExist,
|
||||||
ensureProject,
|
newProject,
|
||||||
forEachCli,
|
|
||||||
readFile,
|
readFile,
|
||||||
readJson,
|
readJson,
|
||||||
runCLI,
|
runCLI,
|
||||||
runCLIAsync,
|
runCLIAsync,
|
||||||
runNgNew,
|
|
||||||
runNgAdd,
|
|
||||||
tmpProjPath,
|
tmpProjPath,
|
||||||
uniq,
|
uniq,
|
||||||
updateFile,
|
updateFile,
|
||||||
workspaceConfigName,
|
workspaceConfigName,
|
||||||
yarnAdd,
|
|
||||||
} from '@nrwl/e2e/utils';
|
} from '@nrwl/e2e/utils';
|
||||||
|
|
||||||
function getData(): Promise<any> {
|
function getData(): Promise<any> {
|
||||||
@ -37,306 +32,272 @@ function getData(): Promise<any> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachCli((currentCLIName) => {
|
describe('Node Applications', () => {
|
||||||
const linter = currentCLIName === 'angular' ? 'tslint' : 'eslint';
|
it('should be able to generate an empty application', async () => {
|
||||||
|
newProject();
|
||||||
|
const nodeapp = uniq('nodeapp');
|
||||||
|
|
||||||
describe('Node Applications', () => {
|
runCLI(`generate @nrwl/node:app ${nodeapp} --linter=eslint`);
|
||||||
it('should be able to generate an empty application', async () => {
|
|
||||||
ensureProject();
|
|
||||||
const nodeapp = uniq('nodeapp');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/node:app ${nodeapp} --linter=${linter}`);
|
const lintResults = runCLI(`lint ${nodeapp}`);
|
||||||
|
expect(lintResults).toContain('All files pass linting.');
|
||||||
|
|
||||||
const lintResults = runCLI(`lint ${nodeapp}`);
|
updateFile(`apps/${nodeapp}/src/main.ts`, `console.log('Hello World!');`);
|
||||||
expect(lintResults).toContain('All files pass linting.');
|
await runCLIAsync(`build ${nodeapp}`);
|
||||||
|
|
||||||
updateFile(`apps/${nodeapp}/src/main.ts`, `console.log('Hello World!');`);
|
checkFilesExist(`dist/apps/${nodeapp}/main.js`);
|
||||||
await runCLIAsync(`build ${nodeapp}`);
|
const result = execSync(`node dist/apps/${nodeapp}/main.js`, {
|
||||||
|
cwd: tmpProjPath(),
|
||||||
|
}).toString();
|
||||||
|
expect(result).toContain('Hello World!');
|
||||||
|
}, 60000);
|
||||||
|
|
||||||
checkFilesExist(`dist/apps/${nodeapp}/main.js`);
|
it('should be able to generate an express application', async (done) => {
|
||||||
const result = execSync(`node dist/apps/${nodeapp}/main.js`, {
|
newProject();
|
||||||
cwd: tmpProjPath(),
|
const nodeapp = uniq('nodeapp');
|
||||||
}).toString();
|
|
||||||
expect(result).toContain('Hello World!');
|
|
||||||
}, 60000);
|
|
||||||
|
|
||||||
it('should be able to generate an express application', async (done) => {
|
runCLI(`generate @nrwl/express:app ${nodeapp} --linter=eslint`);
|
||||||
ensureProject();
|
const lintResults = runCLI(`lint ${nodeapp}`);
|
||||||
const nodeapp = uniq('nodeapp');
|
expect(lintResults).toContain('All files pass linting.');
|
||||||
|
|
||||||
runCLI(`generate @nrwl/express:app ${nodeapp} --linter=${linter}`);
|
updateFile(
|
||||||
const lintResults = runCLI(`lint ${nodeapp}`);
|
`apps/${nodeapp}/src/app/test.spec.ts`,
|
||||||
expect(lintResults).toContain('All files pass linting.');
|
`
|
||||||
|
|
||||||
updateFile(
|
|
||||||
`apps/${nodeapp}/src/app/test.spec.ts`,
|
|
||||||
`
|
|
||||||
describe('test', () => {
|
describe('test', () => {
|
||||||
it('should work', () => {
|
it('should work', () => {
|
||||||
expect(true).toEqual(true);
|
expect(true).toEqual(true);
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
updateFile(`apps/${nodeapp}/src/assets/file.txt`, ``);
|
updateFile(`apps/${nodeapp}/src/assets/file.txt`, ``);
|
||||||
const jestResult = await runCLIAsync(`test ${nodeapp}`);
|
const jestResult = await runCLIAsync(`test ${nodeapp}`);
|
||||||
expect(jestResult.combinedOutput).toContain(
|
expect(jestResult.combinedOutput).toContain(
|
||||||
'Test Suites: 1 passed, 1 total'
|
'Test Suites: 1 passed, 1 total'
|
||||||
);
|
);
|
||||||
await runCLIAsync(`build ${nodeapp}`);
|
await runCLIAsync(`build ${nodeapp}`);
|
||||||
|
|
||||||
checkFilesExist(
|
checkFilesExist(
|
||||||
`dist/apps/${nodeapp}/main.js`,
|
`dist/apps/${nodeapp}/main.js`,
|
||||||
`dist/apps/${nodeapp}/assets/file.txt`,
|
`dist/apps/${nodeapp}/assets/file.txt`,
|
||||||
`dist/apps/${nodeapp}/main.js.map`
|
`dist/apps/${nodeapp}/main.js.map`
|
||||||
);
|
);
|
||||||
|
|
||||||
const server = fork(`./dist/apps/${nodeapp}/main.js`, [], {
|
const server = fork(`./dist/apps/${nodeapp}/main.js`, [], {
|
||||||
cwd: tmpProjPath(),
|
cwd: tmpProjPath(),
|
||||||
silent: true,
|
silent: true,
|
||||||
|
});
|
||||||
|
expect(server).toBeTruthy();
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
server.stdout.once('data', async (data) => {
|
||||||
|
expect(data.toString()).toContain('Listening at http://localhost:3333');
|
||||||
|
const result = await getData();
|
||||||
|
|
||||||
|
expect(result.message).toEqual(`Welcome to ${nodeapp}!`);
|
||||||
|
treeKill(server.pid, 'SIGTERM', (err) => {
|
||||||
|
expect(err).toBeFalsy();
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
expect(server).toBeTruthy();
|
});
|
||||||
await new Promise((resolve) => {
|
const process = spawn(
|
||||||
server.stdout.once('data', async (data) => {
|
'node',
|
||||||
expect(data.toString()).toContain(
|
['./node_modules/.bin/nx', 'serve', nodeapp],
|
||||||
'Listening at http://localhost:3333'
|
{
|
||||||
);
|
cwd: tmpProjPath(),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
let collectedOutput = '';
|
||||||
|
process.stdout.on('data', async (data: Buffer) => {
|
||||||
|
collectedOutput += data.toString();
|
||||||
|
if (!data.toString().includes('Listening at http://localhost:3333')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await getData();
|
||||||
|
expect(result.message).toEqual(`Welcome to ${nodeapp}!`);
|
||||||
|
treeKill(process.pid, 'SIGTERM', (err) => {
|
||||||
|
expect(err).toBeFalsy();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, 120000);
|
||||||
|
|
||||||
|
it('should be able to generate a nest application', async (done) => {
|
||||||
|
newProject();
|
||||||
|
const nestapp = uniq('nestapp');
|
||||||
|
runCLI(`generate @nrwl/nest:app ${nestapp} --linter=eslint`);
|
||||||
|
|
||||||
|
const lintResults = runCLI(`lint ${nestapp}`);
|
||||||
|
expect(lintResults).toContain('All files pass linting.');
|
||||||
|
|
||||||
|
updateFile(`apps/${nestapp}/src/assets/file.txt`, ``);
|
||||||
|
const jestResult = await runCLIAsync(`test ${nestapp}`);
|
||||||
|
expect(jestResult.combinedOutput).toContain(
|
||||||
|
'Test Suites: 2 passed, 2 total'
|
||||||
|
);
|
||||||
|
|
||||||
|
await runCLIAsync(`build ${nestapp}`);
|
||||||
|
|
||||||
|
checkFilesExist(
|
||||||
|
`dist/apps/${nestapp}/main.js`,
|
||||||
|
`dist/apps/${nestapp}/assets/file.txt`,
|
||||||
|
`dist/apps/${nestapp}/main.js.map`
|
||||||
|
);
|
||||||
|
|
||||||
|
const server = fork(`./dist/apps/${nestapp}/main.js`, [], {
|
||||||
|
cwd: tmpProjPath(),
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
|
expect(server).toBeTruthy();
|
||||||
|
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
server.stdout.on('data', async (data) => {
|
||||||
|
const message = data.toString();
|
||||||
|
if (message.includes('Listening at http://localhost:3333')) {
|
||||||
const result = await getData();
|
const result = await getData();
|
||||||
|
|
||||||
expect(result.message).toEqual(`Welcome to ${nodeapp}!`);
|
expect(result.message).toEqual(`Welcome to ${nestapp}!`);
|
||||||
treeKill(server.pid, 'SIGTERM', (err) => {
|
treeKill(server.pid, 'SIGTERM', (err) => {
|
||||||
expect(err).toBeFalsy();
|
expect(err).toBeFalsy();
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
|
||||||
const process = spawn(
|
|
||||||
'node',
|
|
||||||
['./node_modules/.bin/nx', 'serve', nodeapp],
|
|
||||||
{
|
|
||||||
cwd: tmpProjPath(),
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
let collectedOutput = '';
|
|
||||||
process.stdout.on('data', async (data: Buffer) => {
|
|
||||||
collectedOutput += data.toString();
|
|
||||||
if (!data.toString().includes('Listening at http://localhost:3333')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await getData();
|
|
||||||
expect(result.message).toEqual(`Welcome to ${nodeapp}!`);
|
|
||||||
treeKill(process.pid, 'SIGTERM', (err) => {
|
|
||||||
expect(err).toBeFalsy();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}, 120000);
|
});
|
||||||
|
|
||||||
xit('should have correct ts options for nest application', async () => {
|
const process = spawn(
|
||||||
if (currentCLIName === 'angular') {
|
'node',
|
||||||
// Usually the tests use ensureProject() to setup the test workspace. But it will trigger
|
['./node_modules/@nrwl/cli/bin/nx', 'serve', nestapp],
|
||||||
// the nx workspace schematic which creates a tsconfig file containing the parameters
|
{
|
||||||
// required by nest.
|
|
||||||
// However, when creating an Angular workspace and adding the workspace capability (as
|
|
||||||
// described in the docs) the tsconfig file could miss required options if Angular removes
|
|
||||||
// them from their config files as happened with emitDecoratorMetadata.
|
|
||||||
runNgNew();
|
|
||||||
runNgAdd('--npmScope projscope');
|
|
||||||
yarnAdd('@nrwl/nest');
|
|
||||||
} else {
|
|
||||||
ensureProject();
|
|
||||||
}
|
|
||||||
|
|
||||||
const nestapp = uniq('nestapp');
|
|
||||||
runCLI(`generate @nrwl/nest:app ${nestapp} --linter=${linter}`);
|
|
||||||
const configPath = tmpProjPath(`apps/${nestapp}/tsconfig.app.json`);
|
|
||||||
const json = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
||||||
const config = ts.parseJsonConfigFileContent(
|
|
||||||
json.config,
|
|
||||||
ts.sys,
|
|
||||||
path.dirname(configPath)
|
|
||||||
); // respects "extends" inside tsconfigs
|
|
||||||
|
|
||||||
expect(config.options.emitDecoratorMetadata).toEqual(true); // required by nest to function properly
|
|
||||||
expect(config.options.target).toEqual(ts.ScriptTarget.ES2015); // required by nest swagger to function properly
|
|
||||||
}, 180000);
|
|
||||||
|
|
||||||
it('should be able to generate a nest application', async (done) => {
|
|
||||||
ensureProject();
|
|
||||||
const nestapp = uniq('nestapp');
|
|
||||||
runCLI(`generate @nrwl/nest:app ${nestapp} --linter=${linter}`);
|
|
||||||
|
|
||||||
const lintResults = runCLI(`lint ${nestapp}`);
|
|
||||||
expect(lintResults).toContain('All files pass linting.');
|
|
||||||
|
|
||||||
updateFile(`apps/${nestapp}/src/assets/file.txt`, ``);
|
|
||||||
const jestResult = await runCLIAsync(`test ${nestapp}`);
|
|
||||||
expect(jestResult.combinedOutput).toContain(
|
|
||||||
'Test Suites: 2 passed, 2 total'
|
|
||||||
);
|
|
||||||
|
|
||||||
await runCLIAsync(`build ${nestapp}`);
|
|
||||||
|
|
||||||
checkFilesExist(
|
|
||||||
`dist/apps/${nestapp}/main.js`,
|
|
||||||
`dist/apps/${nestapp}/assets/file.txt`,
|
|
||||||
`dist/apps/${nestapp}/main.js.map`
|
|
||||||
);
|
|
||||||
|
|
||||||
const server = fork(`./dist/apps/${nestapp}/main.js`, [], {
|
|
||||||
cwd: tmpProjPath(),
|
cwd: tmpProjPath(),
|
||||||
silent: true,
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
process.stdout.on('data', async (data: Buffer) => {
|
||||||
|
if (!data.toString().includes('Listening at http://localhost:3333')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const result = await getData();
|
||||||
|
expect(result.message).toEqual(`Welcome to ${nestapp}!`);
|
||||||
|
treeKill(process.pid, 'SIGTERM', (err) => {
|
||||||
|
expect(err).toBeFalsy();
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
expect(server).toBeTruthy();
|
});
|
||||||
|
}, 120000);
|
||||||
|
});
|
||||||
|
|
||||||
await new Promise((resolve) => {
|
describe('Node Libraries', () => {
|
||||||
server.stdout.on('data', async (data) => {
|
it('should be able to generate a node library', async () => {
|
||||||
const message = data.toString();
|
newProject();
|
||||||
if (message.includes('Listening at http://localhost:3333')) {
|
const nodelib = uniq('nodelib');
|
||||||
const result = await getData();
|
|
||||||
|
|
||||||
expect(result.message).toEqual(`Welcome to ${nestapp}!`);
|
runCLI(`generate @nrwl/node:lib ${nodelib}`);
|
||||||
treeKill(server.pid, 'SIGTERM', (err) => {
|
|
||||||
expect(err).toBeFalsy();
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const process = spawn(
|
const lintResults = runCLI(`lint ${nodelib}`);
|
||||||
'node',
|
expect(lintResults).toContain('All files pass linting.');
|
||||||
['./node_modules/@nrwl/cli/bin/nx', 'serve', nestapp],
|
|
||||||
{
|
|
||||||
cwd: tmpProjPath(),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
process.stdout.on('data', async (data: Buffer) => {
|
const jestResult = await runCLIAsync(`test ${nodelib}`);
|
||||||
if (!data.toString().includes('Listening at http://localhost:3333')) {
|
expect(jestResult.combinedOutput).toContain(
|
||||||
return;
|
'Test Suites: 1 passed, 1 total'
|
||||||
}
|
);
|
||||||
const result = await getData();
|
}, 60000);
|
||||||
expect(result.message).toEqual(`Welcome to ${nestapp}!`);
|
|
||||||
treeKill(process.pid, 'SIGTERM', (err) => {
|
|
||||||
expect(err).toBeFalsy();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}, 120000);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Node Libraries', () => {
|
it('should be able to generate a publishable node library', async () => {
|
||||||
it('should be able to generate a node library', async () => {
|
newProject();
|
||||||
ensureProject();
|
|
||||||
const nodelib = uniq('nodelib');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/node:lib ${nodelib}`);
|
const nodeLib = uniq('nodelib');
|
||||||
|
runCLI(
|
||||||
|
`generate @nrwl/node:lib ${nodeLib} --publishable --importPath=@proj/${nodeLib}`
|
||||||
|
);
|
||||||
|
checkFilesExist(`libs/${nodeLib}/package.json`);
|
||||||
|
const tslibConfig = readJson(`libs/${nodeLib}/tsconfig.lib.json`);
|
||||||
|
expect(tslibConfig).toEqual({
|
||||||
|
extends: './tsconfig.json',
|
||||||
|
compilerOptions: {
|
||||||
|
module: 'commonjs',
|
||||||
|
outDir: '../../dist/out-tsc',
|
||||||
|
declaration: true,
|
||||||
|
types: ['node'],
|
||||||
|
},
|
||||||
|
exclude: ['**/*.spec.ts'],
|
||||||
|
include: ['**/*.ts'],
|
||||||
|
});
|
||||||
|
await runCLIAsync(`build ${nodeLib}`);
|
||||||
|
checkFilesExist(
|
||||||
|
`dist/libs/${nodeLib}/src/index.js`,
|
||||||
|
`dist/libs/${nodeLib}/src/index.d.ts`,
|
||||||
|
`dist/libs/${nodeLib}/package.json`
|
||||||
|
);
|
||||||
|
|
||||||
const lintResults = runCLI(`lint ${nodelib}`);
|
const packageJson = readJson(`dist/libs/${nodeLib}/package.json`);
|
||||||
expect(lintResults).toContain('All files pass linting.');
|
expect(packageJson).toEqual({
|
||||||
|
name: `@proj/${nodeLib}`,
|
||||||
|
version: '0.0.1',
|
||||||
|
main: 'src/index.js',
|
||||||
|
typings: 'src/index.d.ts',
|
||||||
|
});
|
||||||
|
}, 60000);
|
||||||
|
|
||||||
const jestResult = await runCLIAsync(`test ${nodelib}`);
|
it('should be able to copy assets', () => {
|
||||||
expect(jestResult.combinedOutput).toContain(
|
newProject();
|
||||||
'Test Suites: 1 passed, 1 total'
|
const nodelib = uniq('nodelib');
|
||||||
);
|
const nglib = uniq('nglib');
|
||||||
}, 60000);
|
|
||||||
|
|
||||||
it('should be able to generate a publishable node library', async () => {
|
// Generating two libraries just to have a lot of files to copy
|
||||||
ensureProject();
|
runCLI(
|
||||||
|
`generate @nrwl/node:lib ${nodelib} --publishable --importPath=@proj/${nodelib}`
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* The angular lib contains a lot sub directories that would fail without
|
||||||
|
* `nodir: true` in the package.impl.ts
|
||||||
|
*/
|
||||||
|
runCLI(
|
||||||
|
`generate @nrwl/angular:lib ${nglib} --publishable --importPath=@proj/${nglib}`
|
||||||
|
);
|
||||||
|
const workspace = readJson(workspaceConfigName());
|
||||||
|
workspace.projects[nodelib].architect.build.options.assets.push({
|
||||||
|
input: `./dist/libs/${nglib}`,
|
||||||
|
glob: '**/*',
|
||||||
|
output: '.',
|
||||||
|
});
|
||||||
|
|
||||||
const nodeLib = uniq('nodelib');
|
updateFile(workspaceConfigName(), JSON.stringify(workspace));
|
||||||
runCLI(
|
|
||||||
`generate @nrwl/node:lib ${nodeLib} --publishable --importPath=@proj/${nodeLib}`
|
|
||||||
);
|
|
||||||
checkFilesExist(`libs/${nodeLib}/package.json`);
|
|
||||||
const tslibConfig = readJson(`libs/${nodeLib}/tsconfig.lib.json`);
|
|
||||||
expect(tslibConfig).toEqual({
|
|
||||||
extends: './tsconfig.json',
|
|
||||||
compilerOptions: {
|
|
||||||
module: 'commonjs',
|
|
||||||
outDir: '../../dist/out-tsc',
|
|
||||||
declaration: true,
|
|
||||||
types: ['node'],
|
|
||||||
},
|
|
||||||
exclude: ['**/*.spec.ts'],
|
|
||||||
include: ['**/*.ts'],
|
|
||||||
});
|
|
||||||
await runCLIAsync(`build ${nodeLib}`);
|
|
||||||
checkFilesExist(
|
|
||||||
`dist/libs/${nodeLib}/src/index.js`,
|
|
||||||
`dist/libs/${nodeLib}/src/index.d.ts`,
|
|
||||||
`dist/libs/${nodeLib}/package.json`
|
|
||||||
);
|
|
||||||
|
|
||||||
const packageJson = readJson(`dist/libs/${nodeLib}/package.json`);
|
runCLI(`build ${nglib}`);
|
||||||
expect(packageJson).toEqual({
|
runCLI(`build ${nodelib}`);
|
||||||
name: `@proj/${nodeLib}`,
|
checkFilesExist(`./dist/libs/${nodelib}/esm2015/index.js`);
|
||||||
version: '0.0.1',
|
}, 60000);
|
||||||
main: 'src/index.js',
|
|
||||||
typings: 'src/index.d.ts',
|
|
||||||
});
|
|
||||||
}, 60000);
|
|
||||||
|
|
||||||
it('should be able to copy assets', () => {
|
it('should fail when trying to compile typescript files that are invalid', () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const nodelib = uniq('nodelib');
|
const nodeLib = uniq('nodelib');
|
||||||
const nglib = uniq('nglib');
|
runCLI(
|
||||||
|
`generate @nrwl/node:lib ${nodeLib} --publishable --importPath=@proj/${nodeLib}`
|
||||||
// Generating two libraries just to have a lot of files to copy
|
);
|
||||||
runCLI(
|
updateFile(
|
||||||
`generate @nrwl/node:lib ${nodelib} --publishable --importPath=@proj/${nodelib}`
|
`libs/${nodeLib}/src/index.ts`,
|
||||||
);
|
stripIndents`
|
||||||
/**
|
|
||||||
* The angular lib contains a lot sub directories that would fail without
|
|
||||||
* `nodir: true` in the package.impl.ts
|
|
||||||
*/
|
|
||||||
runCLI(
|
|
||||||
`generate @nrwl/angular:lib ${nglib} --publishable --importPath=@proj/${nglib}`
|
|
||||||
);
|
|
||||||
const workspace = readJson(workspaceConfigName());
|
|
||||||
workspace.projects[nodelib].architect.build.options.assets.push({
|
|
||||||
input: `./dist/libs/${nglib}`,
|
|
||||||
glob: '**/*',
|
|
||||||
output: '.',
|
|
||||||
});
|
|
||||||
|
|
||||||
updateFile(workspaceConfigName(), JSON.stringify(workspace));
|
|
||||||
|
|
||||||
runCLI(`build ${nglib}`);
|
|
||||||
runCLI(`build ${nodelib}`);
|
|
||||||
checkFilesExist(`./dist/libs/${nodelib}/esm2015/index.js`);
|
|
||||||
}, 60000);
|
|
||||||
|
|
||||||
it('should fail when trying to compile typescript files that are invalid', () => {
|
|
||||||
ensureProject();
|
|
||||||
const nodeLib = uniq('nodelib');
|
|
||||||
runCLI(
|
|
||||||
`generate @nrwl/node:lib ${nodeLib} --publishable --importPath=@proj/${nodeLib}`
|
|
||||||
);
|
|
||||||
updateFile(
|
|
||||||
`libs/${nodeLib}/src/index.ts`,
|
|
||||||
stripIndents`
|
|
||||||
const temp: number = 'should fail'
|
const temp: number = 'should fail'
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
expect(() => runCLI(`build ${nodeLib}`)).toThrow();
|
expect(() => runCLI(`build ${nodeLib}`)).toThrow();
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('nest libraries', function () {
|
describe('nest libraries', function () {
|
||||||
it('should be able to generate a nest library', async () => {
|
it('should be able to generate a nest library', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const nestlib = uniq('nestlib');
|
const nestlib = uniq('nestlib');
|
||||||
|
|
||||||
runCLI(`generate @nrwl/nest:lib ${nestlib}`);
|
runCLI(`generate @nrwl/nest:lib ${nestlib}`);
|
||||||
|
|
||||||
const jestConfigContent = readFile(`libs/${nestlib}/jest.config.js`);
|
const jestConfigContent = readFile(`libs/${nestlib}/jest.config.js`);
|
||||||
|
|
||||||
expect(stripIndents`${jestConfigContent}`).toEqual(
|
expect(stripIndents`${jestConfigContent}`).toEqual(
|
||||||
stripIndents`module.exports = {
|
stripIndents`module.exports = {
|
||||||
displayName: '${nestlib}',
|
displayName: '${nestlib}',
|
||||||
preset: '../../jest.preset.js',
|
preset: '../../jest.preset.js',
|
||||||
globals: {
|
globals: {
|
||||||
@ -352,189 +313,186 @@ forEachCli((currentCLIName) => {
|
|||||||
coverageDirectory: '../../coverage/libs/${nestlib}',
|
coverageDirectory: '../../coverage/libs/${nestlib}',
|
||||||
};
|
};
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
const lintResults = runCLI(`lint ${nestlib}`);
|
const lintResults = runCLI(`lint ${nestlib}`);
|
||||||
expect(lintResults).toContain('All files pass linting.');
|
expect(lintResults).toContain('All files pass linting.');
|
||||||
}, 60000);
|
}, 60000);
|
||||||
|
|
||||||
it('should be able to generate a nest library w/ service', async () => {
|
it('should be able to generate a nest library w/ service', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const nestlib = uniq('nestlib');
|
const nestlib = uniq('nestlib');
|
||||||
|
|
||||||
runCLI(`generate @nrwl/nest:lib ${nestlib} --service`);
|
runCLI(`generate @nrwl/nest:lib ${nestlib} --service`);
|
||||||
|
|
||||||
const lintResults = runCLI(`lint ${nestlib}`);
|
const lintResults = runCLI(`lint ${nestlib}`);
|
||||||
expect(lintResults).toContain('All files pass linting.');
|
expect(lintResults).toContain('All files pass linting.');
|
||||||
|
|
||||||
const jestResult = await runCLIAsync(`test ${nestlib}`);
|
const jestResult = await runCLIAsync(`test ${nestlib}`);
|
||||||
expect(jestResult.combinedOutput).toContain(
|
expect(jestResult.combinedOutput).toContain(
|
||||||
'Test Suites: 1 passed, 1 total'
|
'Test Suites: 1 passed, 1 total'
|
||||||
);
|
);
|
||||||
}, 60000);
|
}, 60000);
|
||||||
|
|
||||||
it('should be able to generate a nest library w/ controller', async () => {
|
it('should be able to generate a nest library w/ controller', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const nestlib = uniq('nestlib');
|
const nestlib = uniq('nestlib');
|
||||||
|
|
||||||
runCLI(`generate @nrwl/nest:lib ${nestlib} --controller`);
|
runCLI(`generate @nrwl/nest:lib ${nestlib} --controller`);
|
||||||
|
|
||||||
const lintResults = runCLI(`lint ${nestlib}`);
|
const lintResults = runCLI(`lint ${nestlib}`);
|
||||||
expect(lintResults).toContain('All files pass linting.');
|
expect(lintResults).toContain('All files pass linting.');
|
||||||
|
|
||||||
const jestResult = await runCLIAsync(`test ${nestlib}`);
|
const jestResult = await runCLIAsync(`test ${nestlib}`);
|
||||||
expect(jestResult.combinedOutput).toContain(
|
expect(jestResult.combinedOutput).toContain(
|
||||||
'Test Suites: 1 passed, 1 total'
|
'Test Suites: 1 passed, 1 total'
|
||||||
);
|
);
|
||||||
}, 60000);
|
}, 60000);
|
||||||
|
|
||||||
it('should be able to generate a nest library w/ controller and service', async () => {
|
it('should be able to generate a nest library w/ controller and service', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const nestlib = uniq('nestlib');
|
const nestlib = uniq('nestlib');
|
||||||
|
|
||||||
runCLI(`generate @nrwl/nest:lib ${nestlib} --controller --service`);
|
runCLI(`generate @nrwl/nest:lib ${nestlib} --controller --service`);
|
||||||
|
|
||||||
const lintResults = runCLI(`lint ${nestlib}`);
|
const lintResults = runCLI(`lint ${nestlib}`);
|
||||||
expect(lintResults).toContain('All files pass linting.');
|
expect(lintResults).toContain('All files pass linting.');
|
||||||
|
|
||||||
const jestResult = await runCLIAsync(`test ${nestlib}`);
|
const jestResult = await runCLIAsync(`test ${nestlib}`);
|
||||||
expect(jestResult.combinedOutput).toContain(
|
expect(jestResult.combinedOutput).toContain(
|
||||||
'Test Suites: 2 passed, 2 total'
|
'Test Suites: 2 passed, 2 total'
|
||||||
);
|
);
|
||||||
}, 60000);
|
}, 60000);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with dependencies', () => {
|
describe('with dependencies', () => {
|
||||||
/**
|
/**
|
||||||
* Graph:
|
* Graph:
|
||||||
*
|
*
|
||||||
* childLib
|
* childLib
|
||||||
* /
|
* /
|
||||||
* app => parentLib =>
|
* app => parentLib =>
|
||||||
* \
|
* \
|
||||||
* \
|
* \
|
||||||
* childLib2
|
* childLib2
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
let app: string;
|
let app: string;
|
||||||
let parentLib: string;
|
let parentLib: string;
|
||||||
let childLib: string;
|
let childLib: string;
|
||||||
let childLib2: string;
|
let childLib2: string;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
app = uniq('app');
|
app = uniq('app');
|
||||||
parentLib = uniq('parentlib');
|
parentLib = uniq('parentlib');
|
||||||
childLib = uniq('childlib');
|
childLib = uniq('childlib');
|
||||||
childLib2 = uniq('childlib2');
|
childLib2 = uniq('childlib2');
|
||||||
|
|
||||||
ensureProject();
|
newProject();
|
||||||
|
|
||||||
runCLI(`generate @nrwl/express:app ${app}`);
|
runCLI(`generate @nrwl/express:app ${app}`);
|
||||||
runCLI(`generate @nrwl/node:lib ${parentLib} --buildable=true`);
|
runCLI(`generate @nrwl/node:lib ${parentLib} --buildable=true`);
|
||||||
runCLI(`generate @nrwl/node:lib ${childLib} --buildable=true`);
|
runCLI(`generate @nrwl/node:lib ${childLib} --buildable=true`);
|
||||||
runCLI(`generate @nrwl/node:lib ${childLib2} --buildable=true`);
|
runCLI(`generate @nrwl/node:lib ${childLib2} --buildable=true`);
|
||||||
|
|
||||||
// create dependencies by importing
|
// create dependencies by importing
|
||||||
const createDep = (parent, children: string[]) => {
|
const createDep = (parent, children: string[]) => {
|
||||||
updateFile(
|
updateFile(
|
||||||
`libs/${parent}/src/lib/${parent}.ts`,
|
`libs/${parent}/src/lib/${parent}.ts`,
|
||||||
`
|
`
|
||||||
${children
|
${children
|
||||||
.map((entry) => `import { ${entry} } from '@proj/${entry}';`)
|
.map((entry) => `import { ${entry} } from '@proj/${entry}';`)
|
||||||
.join('\n')}
|
.join('\n')}
|
||||||
|
|
||||||
export function ${parent}(): string {
|
export function ${parent}(): string {
|
||||||
return '${parent}' + ' ' + ${children
|
return '${parent}' + ' ' + ${children
|
||||||
.map((entry) => `${entry}()`)
|
.map((entry) => `${entry}()`)
|
||||||
.join('+')}
|
.join('+')}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
createDep(parentLib, [childLib, childLib2]);
|
createDep(parentLib, [childLib, childLib2]);
|
||||||
|
|
||||||
updateFile(
|
updateFile(
|
||||||
`apps/${app}/src/main.ts`,
|
`apps/${app}/src/main.ts`,
|
||||||
`
|
`
|
||||||
import "@proj/${parentLib}";
|
import "@proj/${parentLib}";
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
// we are setting paths to {} to make sure built libs are read from dist
|
// we are setting paths to {} to make sure built libs are read from dist
|
||||||
updateFile('tsconfig.base.json', (c) => {
|
updateFile('tsconfig.base.json', (c) => {
|
||||||
const json = JSON.parse(c);
|
const json = JSON.parse(c);
|
||||||
json.compilerOptions.paths = {};
|
json.compilerOptions.paths = {};
|
||||||
return JSON.stringify(json, null, 2);
|
return JSON.stringify(json, null, 2);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should throw an error if the dependent library has not been built before building the parent lib', () => {
|
it('should throw an error if the dependent library has not been built before building the parent lib', () => {
|
||||||
expect.assertions(2);
|
expect.assertions(2);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
runCLI(`build ${parentLib}`);
|
runCLI(`build ${parentLib}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
expect(e.stderr.toString()).toContain(
|
expect(e.stderr.toString()).toContain(
|
||||||
`Some of the project ${parentLib}'s dependencies have not been built yet. Please build these libraries before:`
|
`Some of the project ${parentLib}'s dependencies have not been built yet. Please build these libraries before:`
|
||||||
);
|
|
||||||
expect(e.stderr.toString()).toContain(`${childLib}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should build a library without dependencies', () => {
|
|
||||||
const childLibOutput = runCLI(`build ${childLib}`);
|
|
||||||
|
|
||||||
expect(childLibOutput).toContain(
|
|
||||||
`Done compiling TypeScript files for library ${childLib}`
|
|
||||||
);
|
);
|
||||||
});
|
expect(e.stderr.toString()).toContain(`${childLib}`);
|
||||||
|
|
||||||
it('should build a parent library if the dependent libraries have been built before', () => {
|
|
||||||
const childLibOutput = runCLI(`build ${childLib}`);
|
|
||||||
expect(childLibOutput).toContain(
|
|
||||||
`Done compiling TypeScript files for library ${childLib}`
|
|
||||||
);
|
|
||||||
|
|
||||||
const childLib2Output = runCLI(`build ${childLib2}`);
|
|
||||||
expect(childLib2Output).toContain(
|
|
||||||
`Done compiling TypeScript files for library ${childLib2}`
|
|
||||||
);
|
|
||||||
|
|
||||||
const parentLibOutput = runCLI(`build ${parentLib}`);
|
|
||||||
expect(parentLibOutput).toContain(
|
|
||||||
`Done compiling TypeScript files for library ${parentLib}`
|
|
||||||
);
|
|
||||||
|
|
||||||
// assert package.json deps have been set
|
|
||||||
const assertPackageJson = (
|
|
||||||
parent: string,
|
|
||||||
lib: string,
|
|
||||||
version: string
|
|
||||||
) => {
|
|
||||||
const jsonFile = readJson(`dist/libs/${parent}/package.json`);
|
|
||||||
const childDependencyVersion = jsonFile.dependencies[`@proj/${lib}`];
|
|
||||||
expect(childDependencyVersion).toBe(version);
|
|
||||||
};
|
|
||||||
|
|
||||||
assertPackageJson(parentLib, childLib, '0.0.1');
|
|
||||||
assertPackageJson(parentLib, childLib2, '0.0.1');
|
|
||||||
});
|
|
||||||
|
|
||||||
if (currentCLIName === 'nx') {
|
|
||||||
it('should build an app composed out of buildable libs', () => {
|
|
||||||
const buildWithDeps = runCLI(`build ${app} --with-deps`);
|
|
||||||
expect(buildWithDeps).toContain(`Running target "build" succeeded`);
|
|
||||||
checkFilesDoNotExist(`apps/${app}/tsconfig/tsconfig.nx-tmp`);
|
|
||||||
|
|
||||||
// we remove all path mappings from the root tsconfig, so when trying to build
|
|
||||||
// libs from source, the builder will throw
|
|
||||||
const failedBuild = runCLI(
|
|
||||||
`build ${app} --with-deps --buildLibsFromSource`,
|
|
||||||
{ silenceError: true }
|
|
||||||
);
|
|
||||||
expect(failedBuild).toContain(`Can't resolve`);
|
|
||||||
}, 1000000);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should build a library without dependencies', () => {
|
||||||
|
const childLibOutput = runCLI(`build ${childLib}`);
|
||||||
|
|
||||||
|
expect(childLibOutput).toContain(
|
||||||
|
`Done compiling TypeScript files for library ${childLib}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should build a parent library if the dependent libraries have been built before', () => {
|
||||||
|
const childLibOutput = runCLI(`build ${childLib}`);
|
||||||
|
expect(childLibOutput).toContain(
|
||||||
|
`Done compiling TypeScript files for library ${childLib}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const childLib2Output = runCLI(`build ${childLib2}`);
|
||||||
|
expect(childLib2Output).toContain(
|
||||||
|
`Done compiling TypeScript files for library ${childLib2}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const parentLibOutput = runCLI(`build ${parentLib}`);
|
||||||
|
expect(parentLibOutput).toContain(
|
||||||
|
`Done compiling TypeScript files for library ${parentLib}`
|
||||||
|
);
|
||||||
|
|
||||||
|
// assert package.json deps have been set
|
||||||
|
const assertPackageJson = (
|
||||||
|
parent: string,
|
||||||
|
lib: string,
|
||||||
|
version: string
|
||||||
|
) => {
|
||||||
|
const jsonFile = readJson(`dist/libs/${parent}/package.json`);
|
||||||
|
const childDependencyVersion = jsonFile.dependencies[`@proj/${lib}`];
|
||||||
|
expect(childDependencyVersion).toBe(version);
|
||||||
|
};
|
||||||
|
|
||||||
|
assertPackageJson(parentLib, childLib, '0.0.1');
|
||||||
|
assertPackageJson(parentLib, childLib2, '0.0.1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should build an app composed out of buildable libs', () => {
|
||||||
|
const buildWithDeps = runCLI(`build ${app} --with-deps`);
|
||||||
|
expect(buildWithDeps).toContain(`Running target "build" succeeded`);
|
||||||
|
checkFilesDoNotExist(`apps/${app}/tsconfig/tsconfig.nx-tmp`);
|
||||||
|
|
||||||
|
// we remove all path mappings from the root tsconfig, so when trying to build
|
||||||
|
// libs from source, the builder will throw
|
||||||
|
const failedBuild = runCLI(
|
||||||
|
`build ${app} --with-deps --buildLibsFromSource`,
|
||||||
|
{ silenceError: true }
|
||||||
|
);
|
||||||
|
expect(failedBuild).toContain(`Can't resolve`);
|
||||||
|
}, 1000000);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,226 +1,220 @@
|
|||||||
import {
|
import {
|
||||||
forEachCli,
|
|
||||||
ensureProject,
|
|
||||||
uniq,
|
|
||||||
runCLI,
|
|
||||||
updateFile,
|
|
||||||
expectTestsPass,
|
|
||||||
runCLIAsync,
|
|
||||||
checkFilesExist,
|
checkFilesExist,
|
||||||
|
expectTestsPass,
|
||||||
|
newProject,
|
||||||
readJson,
|
readJson,
|
||||||
|
runCLI,
|
||||||
|
runCLIAsync,
|
||||||
|
uniq,
|
||||||
workspaceConfigName,
|
workspaceConfigName,
|
||||||
} from '@nrwl/e2e/utils';
|
} from '@nrwl/e2e/utils';
|
||||||
|
|
||||||
forEachCli((currentCLIName) => {
|
describe('Nx Plugin', () => {
|
||||||
const linter = currentCLIName === 'angular' ? 'tslint' : 'eslint';
|
it('should be able to generate a Nx Plugin ', async (done) => {
|
||||||
|
newProject();
|
||||||
|
const plugin = uniq('plugin');
|
||||||
|
|
||||||
describe('Nx Plugin', () => {
|
runCLI(
|
||||||
it('should be able to generate a Nx Plugin ', async (done) => {
|
`generate @nrwl/nx-plugin:plugin ${plugin} --linter=eslint --importPath=@proj/${plugin}`
|
||||||
ensureProject();
|
);
|
||||||
|
const lintResults = runCLI(`lint ${plugin}`);
|
||||||
|
expect(lintResults).toContain('All files pass linting.');
|
||||||
|
|
||||||
|
expectTestsPass(await runCLIAsync(`test ${plugin}`));
|
||||||
|
|
||||||
|
const buildResults = runCLI(`build ${plugin}`);
|
||||||
|
expect(buildResults).toContain('Done compiling TypeScript files');
|
||||||
|
checkFilesExist(
|
||||||
|
`dist/libs/${plugin}/package.json`,
|
||||||
|
`dist/libs/${plugin}/collection.json`,
|
||||||
|
`dist/libs/${plugin}/builders.json`,
|
||||||
|
`dist/libs/${plugin}/src/index.js`,
|
||||||
|
`dist/libs/${plugin}/src/schematics/${plugin}/schema.json`,
|
||||||
|
`dist/libs/${plugin}/src/schematics/${plugin}/schema.d.ts`,
|
||||||
|
`dist/libs/${plugin}/src/schematics/${plugin}/schematic.js`,
|
||||||
|
`dist/libs/${plugin}/src/schematics/${plugin}/files/src/index.ts.template`,
|
||||||
|
`dist/libs/${plugin}/src/builders/build/builder.js`,
|
||||||
|
`dist/libs/${plugin}/src/builders/build/schema.d.ts`,
|
||||||
|
`dist/libs/${plugin}/src/builders/build/schema.json`
|
||||||
|
);
|
||||||
|
const nxJson = readJson('nx.json');
|
||||||
|
expect(nxJson).toMatchObject({
|
||||||
|
projects: expect.objectContaining({
|
||||||
|
[plugin]: {
|
||||||
|
tags: [],
|
||||||
|
},
|
||||||
|
[`${plugin}-e2e`]: {
|
||||||
|
tags: [],
|
||||||
|
implicitDependencies: [`${plugin}`],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
}, 45000);
|
||||||
|
|
||||||
|
// the test invoke ensureNxProject, which points to @nrwl/workspace collection
|
||||||
|
// which walks up the directory to find it in the next repo itself, so it
|
||||||
|
// doesn't use the collection we are building
|
||||||
|
// we should change it to point to the right collection using relative path
|
||||||
|
it(`should run the plugin's e2e tests`, async (done) => {
|
||||||
|
newProject();
|
||||||
|
const plugin = uniq('plugin-name');
|
||||||
|
runCLI(
|
||||||
|
`generate @nrwl/nx-plugin:plugin ${plugin} --linter=eslint --importPath=@proj/${plugin}`
|
||||||
|
);
|
||||||
|
const results = await runCLIAsync(`e2e ${plugin}-e2e`);
|
||||||
|
expect(results.stdout).toContain('Compiling TypeScript files');
|
||||||
|
expectTestsPass(results);
|
||||||
|
|
||||||
|
done();
|
||||||
|
}, 250000);
|
||||||
|
|
||||||
|
it('should be able to generate a migration', async (done) => {
|
||||||
|
newProject();
|
||||||
|
const plugin = uniq('plugin');
|
||||||
|
const version = '1.0.0';
|
||||||
|
|
||||||
|
runCLI(
|
||||||
|
`generate @nrwl/nx-plugin:plugin ${plugin} --linter=eslint --importPath=@proj/${plugin}`
|
||||||
|
);
|
||||||
|
runCLI(
|
||||||
|
`generate @nrwl/nx-plugin:migration --project=${plugin} --version=${version} --packageJsonUpdates=false`
|
||||||
|
);
|
||||||
|
|
||||||
|
const lintResults = runCLI(`lint ${plugin}`);
|
||||||
|
expect(lintResults).toContain('All files pass linting.');
|
||||||
|
|
||||||
|
expectTestsPass(await runCLIAsync(`test ${plugin}`));
|
||||||
|
|
||||||
|
const buildResults = runCLI(`build ${plugin}`);
|
||||||
|
expect(buildResults).toContain('Done compiling TypeScript files');
|
||||||
|
checkFilesExist(
|
||||||
|
`dist/libs/${plugin}/src/migrations/update-${version}/update-${version}.js`,
|
||||||
|
`dist/libs/${plugin}/src/migrations/update-${version}/update-${version}.ts`,
|
||||||
|
`dist/libs/${plugin}/src/migrations/update-${version}/update-${version}.spec.ts`,
|
||||||
|
`libs/${plugin}/src/migrations/update-${version}/update-${version}.ts`,
|
||||||
|
`libs/${plugin}/src/migrations/update-${version}/update-${version}.spec.ts`
|
||||||
|
);
|
||||||
|
const migrationsJson = readJson(`libs/${plugin}/migrations.json`);
|
||||||
|
expect(migrationsJson).toMatchObject({
|
||||||
|
schematics: expect.objectContaining({
|
||||||
|
[`update-${version}`]: {
|
||||||
|
version: version,
|
||||||
|
description: `update-${version}`,
|
||||||
|
factory: `./src/migrations/update-${version}/update-${version}`,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
}, 45000);
|
||||||
|
|
||||||
|
it('should be able to generate a schematic', async (done) => {
|
||||||
|
newProject();
|
||||||
|
const plugin = uniq('plugin');
|
||||||
|
const schematic = uniq('schematic');
|
||||||
|
|
||||||
|
runCLI(
|
||||||
|
`generate @nrwl/nx-plugin:plugin ${plugin} --linter=eslint --importPath=@proj/${plugin}`
|
||||||
|
);
|
||||||
|
runCLI(
|
||||||
|
`generate @nrwl/nx-plugin:schematic ${schematic} --project=${plugin}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const lintResults = runCLI(`lint ${plugin}`);
|
||||||
|
expect(lintResults).toContain('All files pass linting.');
|
||||||
|
|
||||||
|
expectTestsPass(await runCLIAsync(`test ${plugin}`));
|
||||||
|
|
||||||
|
const buildResults = runCLI(`build ${plugin}`);
|
||||||
|
expect(buildResults).toContain('Done compiling TypeScript files');
|
||||||
|
checkFilesExist(
|
||||||
|
`libs/${plugin}/src/schematics/${schematic}/schema.d.ts`,
|
||||||
|
`libs/${plugin}/src/schematics/${schematic}/schema.json`,
|
||||||
|
`libs/${plugin}/src/schematics/${schematic}/schematic.ts`,
|
||||||
|
`libs/${plugin}/src/schematics/${schematic}/schematic.spec.ts`,
|
||||||
|
`dist/libs/${plugin}/src/schematics/${schematic}/schema.d.ts`,
|
||||||
|
`dist/libs/${plugin}/src/schematics/${schematic}/schema.json`,
|
||||||
|
`dist/libs/${plugin}/src/schematics/${schematic}/schematic.js`,
|
||||||
|
`dist/libs/${plugin}/src/schematics/${schematic}/schematic.spec.ts`
|
||||||
|
);
|
||||||
|
const collectionJson = readJson(`libs/${plugin}/collection.json`);
|
||||||
|
expect(collectionJson).toMatchObject({
|
||||||
|
schematics: expect.objectContaining({
|
||||||
|
[schematic]: {
|
||||||
|
factory: `./src/schematics/${schematic}/schematic`,
|
||||||
|
schema: `./src/schematics/${schematic}/schema.json`,
|
||||||
|
description: `${schematic} schematic`,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
}, 45000);
|
||||||
|
|
||||||
|
it('should be able to generate a builder', async (done) => {
|
||||||
|
newProject();
|
||||||
|
const plugin = uniq('plugin');
|
||||||
|
const builder = uniq('builder');
|
||||||
|
|
||||||
|
runCLI(
|
||||||
|
`generate @nrwl/nx-plugin:plugin ${plugin} --linter=eslint --importPath=@proj/${plugin}`
|
||||||
|
);
|
||||||
|
runCLI(`generate @nrwl/nx-plugin:builder ${builder} --project=${plugin}`);
|
||||||
|
|
||||||
|
const lintResults = runCLI(`lint ${plugin}`);
|
||||||
|
expect(lintResults).toContain('All files pass linting.');
|
||||||
|
|
||||||
|
expectTestsPass(await runCLIAsync(`test ${plugin}`));
|
||||||
|
|
||||||
|
const buildResults = runCLI(`build ${plugin}`);
|
||||||
|
expect(buildResults).toContain('Done compiling TypeScript files');
|
||||||
|
checkFilesExist(
|
||||||
|
`libs/${plugin}/src/builders/${builder}/schema.d.ts`,
|
||||||
|
`libs/${plugin}/src/builders/${builder}/schema.json`,
|
||||||
|
`libs/${plugin}/src/builders/${builder}/builder.ts`,
|
||||||
|
`libs/${plugin}/src/builders/${builder}/builder.spec.ts`,
|
||||||
|
`dist/libs/${plugin}/src/builders/${builder}/schema.d.ts`,
|
||||||
|
`dist/libs/${plugin}/src/builders/${builder}/schema.json`,
|
||||||
|
`dist/libs/${plugin}/src/builders/${builder}/builder.js`,
|
||||||
|
`dist/libs/${plugin}/src/builders/${builder}/builder.spec.ts`
|
||||||
|
);
|
||||||
|
const buildersJson = readJson(`libs/${plugin}/builders.json`);
|
||||||
|
expect(buildersJson).toMatchObject({
|
||||||
|
builders: expect.objectContaining({
|
||||||
|
[builder]: {
|
||||||
|
implementation: `./src/builders/${builder}/builder`,
|
||||||
|
schema: `./src/builders/${builder}/schema.json`,
|
||||||
|
description: `${builder} builder`,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
}, 45000);
|
||||||
|
|
||||||
|
describe('--directory', () => {
|
||||||
|
it('should create a plugin in the specified directory', () => {
|
||||||
|
newProject();
|
||||||
const plugin = uniq('plugin');
|
const plugin = uniq('plugin');
|
||||||
|
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/nx-plugin:plugin ${plugin} --linter=${linter} --importPath=@proj/${plugin}`
|
`generate @nrwl/nx-plugin:plugin ${plugin} --linter=eslint --directory subdir --importPath=@proj/${plugin}`
|
||||||
);
|
);
|
||||||
const lintResults = runCLI(`lint ${plugin}`);
|
checkFilesExist(`libs/subdir/${plugin}/package.json`);
|
||||||
expect(lintResults).toContain('All files pass linting.');
|
const workspace = readJson(workspaceConfigName());
|
||||||
|
expect(workspace.projects[`subdir-${plugin}`]).toBeTruthy();
|
||||||
expectTestsPass(await runCLIAsync(`test ${plugin}`));
|
expect(workspace.projects[`subdir-${plugin}`].root).toBe(
|
||||||
|
`libs/subdir/${plugin}`
|
||||||
const buildResults = runCLI(`build ${plugin}`);
|
);
|
||||||
expect(buildResults).toContain('Done compiling TypeScript files');
|
expect(workspace.projects[`subdir-${plugin}-e2e`]).toBeTruthy();
|
||||||
checkFilesExist(
|
}, 45000);
|
||||||
`dist/libs/${plugin}/package.json`,
|
});
|
||||||
`dist/libs/${plugin}/collection.json`,
|
describe('--tags', () => {
|
||||||
`dist/libs/${plugin}/builders.json`,
|
it('should add tags to nx.json', async () => {
|
||||||
`dist/libs/${plugin}/src/index.js`,
|
newProject();
|
||||||
`dist/libs/${plugin}/src/schematics/${plugin}/schema.json`,
|
const plugin = uniq('plugin');
|
||||||
`dist/libs/${plugin}/src/schematics/${plugin}/schema.d.ts`,
|
runCLI(
|
||||||
`dist/libs/${plugin}/src/schematics/${plugin}/schematic.js`,
|
`generate @nrwl/nx-plugin:plugin ${plugin} --linter=eslint --tags=e2etag,e2ePackage --importPath=@proj/${plugin}`
|
||||||
`dist/libs/${plugin}/src/schematics/${plugin}/files/src/index.ts.template`,
|
|
||||||
`dist/libs/${plugin}/src/builders/build/builder.js`,
|
|
||||||
`dist/libs/${plugin}/src/builders/build/schema.d.ts`,
|
|
||||||
`dist/libs/${plugin}/src/builders/build/schema.json`
|
|
||||||
);
|
);
|
||||||
const nxJson = readJson('nx.json');
|
const nxJson = readJson('nx.json');
|
||||||
expect(nxJson).toMatchObject({
|
expect(nxJson.projects[plugin].tags).toEqual(['e2etag', 'e2ePackage']);
|
||||||
projects: expect.objectContaining({
|
|
||||||
[plugin]: {
|
|
||||||
tags: [],
|
|
||||||
},
|
|
||||||
[`${plugin}-e2e`]: {
|
|
||||||
tags: [],
|
|
||||||
implicitDependencies: [`${plugin}`],
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
done();
|
|
||||||
}, 45000);
|
}, 45000);
|
||||||
|
|
||||||
// the test invoke ensureNxProject, which points to @nrwl/workspace collection
|
|
||||||
// which walks up the directory to find it in the next repo itself, so it
|
|
||||||
// doesn't use the collection we are building
|
|
||||||
// we should change it to point to the right collection using relative path
|
|
||||||
it(`should run the plugin's e2e tests`, async (done) => {
|
|
||||||
ensureProject();
|
|
||||||
const plugin = uniq('plugin-name');
|
|
||||||
runCLI(
|
|
||||||
`generate @nrwl/nx-plugin:plugin ${plugin} --linter=${linter} --importPath=@proj/${plugin}`
|
|
||||||
);
|
|
||||||
const results = await runCLIAsync(`e2e ${plugin}-e2e`);
|
|
||||||
expect(results.stdout).toContain('Compiling TypeScript files');
|
|
||||||
expectTestsPass(results);
|
|
||||||
|
|
||||||
done();
|
|
||||||
}, 250000);
|
|
||||||
|
|
||||||
it('should be able to generate a migration', async (done) => {
|
|
||||||
ensureProject();
|
|
||||||
const plugin = uniq('plugin');
|
|
||||||
const version = '1.0.0';
|
|
||||||
|
|
||||||
runCLI(
|
|
||||||
`generate @nrwl/nx-plugin:plugin ${plugin} --linter=${linter} --importPath=@proj/${plugin}`
|
|
||||||
);
|
|
||||||
runCLI(
|
|
||||||
`generate @nrwl/nx-plugin:migration --project=${plugin} --version=${version} --packageJsonUpdates=false`
|
|
||||||
);
|
|
||||||
|
|
||||||
const lintResults = runCLI(`lint ${plugin}`);
|
|
||||||
expect(lintResults).toContain('All files pass linting.');
|
|
||||||
|
|
||||||
expectTestsPass(await runCLIAsync(`test ${plugin}`));
|
|
||||||
|
|
||||||
const buildResults = runCLI(`build ${plugin}`);
|
|
||||||
expect(buildResults).toContain('Done compiling TypeScript files');
|
|
||||||
checkFilesExist(
|
|
||||||
`dist/libs/${plugin}/src/migrations/update-${version}/update-${version}.js`,
|
|
||||||
`dist/libs/${plugin}/src/migrations/update-${version}/update-${version}.ts`,
|
|
||||||
`dist/libs/${plugin}/src/migrations/update-${version}/update-${version}.spec.ts`,
|
|
||||||
`libs/${plugin}/src/migrations/update-${version}/update-${version}.ts`,
|
|
||||||
`libs/${plugin}/src/migrations/update-${version}/update-${version}.spec.ts`
|
|
||||||
);
|
|
||||||
const migrationsJson = readJson(`libs/${plugin}/migrations.json`);
|
|
||||||
expect(migrationsJson).toMatchObject({
|
|
||||||
schematics: expect.objectContaining({
|
|
||||||
[`update-${version}`]: {
|
|
||||||
version: version,
|
|
||||||
description: `update-${version}`,
|
|
||||||
factory: `./src/migrations/update-${version}/update-${version}`,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
done();
|
|
||||||
}, 45000);
|
|
||||||
|
|
||||||
it('should be able to generate a schematic', async (done) => {
|
|
||||||
ensureProject();
|
|
||||||
const plugin = uniq('plugin');
|
|
||||||
const schematic = uniq('schematic');
|
|
||||||
|
|
||||||
runCLI(
|
|
||||||
`generate @nrwl/nx-plugin:plugin ${plugin} --linter=${linter} --importPath=@proj/${plugin}`
|
|
||||||
);
|
|
||||||
runCLI(
|
|
||||||
`generate @nrwl/nx-plugin:schematic ${schematic} --project=${plugin}`
|
|
||||||
);
|
|
||||||
|
|
||||||
const lintResults = runCLI(`lint ${plugin}`);
|
|
||||||
expect(lintResults).toContain('All files pass linting.');
|
|
||||||
|
|
||||||
expectTestsPass(await runCLIAsync(`test ${plugin}`));
|
|
||||||
|
|
||||||
const buildResults = runCLI(`build ${plugin}`);
|
|
||||||
expect(buildResults).toContain('Done compiling TypeScript files');
|
|
||||||
checkFilesExist(
|
|
||||||
`libs/${plugin}/src/schematics/${schematic}/schema.d.ts`,
|
|
||||||
`libs/${plugin}/src/schematics/${schematic}/schema.json`,
|
|
||||||
`libs/${plugin}/src/schematics/${schematic}/schematic.ts`,
|
|
||||||
`libs/${plugin}/src/schematics/${schematic}/schematic.spec.ts`,
|
|
||||||
`dist/libs/${plugin}/src/schematics/${schematic}/schema.d.ts`,
|
|
||||||
`dist/libs/${plugin}/src/schematics/${schematic}/schema.json`,
|
|
||||||
`dist/libs/${plugin}/src/schematics/${schematic}/schematic.js`,
|
|
||||||
`dist/libs/${plugin}/src/schematics/${schematic}/schematic.spec.ts`
|
|
||||||
);
|
|
||||||
const collectionJson = readJson(`libs/${plugin}/collection.json`);
|
|
||||||
expect(collectionJson).toMatchObject({
|
|
||||||
schematics: expect.objectContaining({
|
|
||||||
[schematic]: {
|
|
||||||
factory: `./src/schematics/${schematic}/schematic`,
|
|
||||||
schema: `./src/schematics/${schematic}/schema.json`,
|
|
||||||
description: `${schematic} schematic`,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
done();
|
|
||||||
}, 45000);
|
|
||||||
|
|
||||||
it('should be able to generate a builder', async (done) => {
|
|
||||||
ensureProject();
|
|
||||||
const plugin = uniq('plugin');
|
|
||||||
const builder = uniq('builder');
|
|
||||||
|
|
||||||
runCLI(
|
|
||||||
`generate @nrwl/nx-plugin:plugin ${plugin} --linter=${linter} --importPath=@proj/${plugin}`
|
|
||||||
);
|
|
||||||
runCLI(`generate @nrwl/nx-plugin:builder ${builder} --project=${plugin}`);
|
|
||||||
|
|
||||||
const lintResults = runCLI(`lint ${plugin}`);
|
|
||||||
expect(lintResults).toContain('All files pass linting.');
|
|
||||||
|
|
||||||
expectTestsPass(await runCLIAsync(`test ${plugin}`));
|
|
||||||
|
|
||||||
const buildResults = runCLI(`build ${plugin}`);
|
|
||||||
expect(buildResults).toContain('Done compiling TypeScript files');
|
|
||||||
checkFilesExist(
|
|
||||||
`libs/${plugin}/src/builders/${builder}/schema.d.ts`,
|
|
||||||
`libs/${plugin}/src/builders/${builder}/schema.json`,
|
|
||||||
`libs/${plugin}/src/builders/${builder}/builder.ts`,
|
|
||||||
`libs/${plugin}/src/builders/${builder}/builder.spec.ts`,
|
|
||||||
`dist/libs/${plugin}/src/builders/${builder}/schema.d.ts`,
|
|
||||||
`dist/libs/${plugin}/src/builders/${builder}/schema.json`,
|
|
||||||
`dist/libs/${plugin}/src/builders/${builder}/builder.js`,
|
|
||||||
`dist/libs/${plugin}/src/builders/${builder}/builder.spec.ts`
|
|
||||||
);
|
|
||||||
const buildersJson = readJson(`libs/${plugin}/builders.json`);
|
|
||||||
expect(buildersJson).toMatchObject({
|
|
||||||
builders: expect.objectContaining({
|
|
||||||
[builder]: {
|
|
||||||
implementation: `./src/builders/${builder}/builder`,
|
|
||||||
schema: `./src/builders/${builder}/schema.json`,
|
|
||||||
description: `${builder} builder`,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
done();
|
|
||||||
}, 45000);
|
|
||||||
|
|
||||||
describe('--directory', () => {
|
|
||||||
it('should create a plugin in the specified directory', () => {
|
|
||||||
ensureProject();
|
|
||||||
const plugin = uniq('plugin');
|
|
||||||
runCLI(
|
|
||||||
`generate @nrwl/nx-plugin:plugin ${plugin} --linter=${linter} --directory subdir --importPath=@proj/${plugin}`
|
|
||||||
);
|
|
||||||
checkFilesExist(`libs/subdir/${plugin}/package.json`);
|
|
||||||
const workspace = readJson(workspaceConfigName());
|
|
||||||
expect(workspace.projects[`subdir-${plugin}`]).toBeTruthy();
|
|
||||||
expect(workspace.projects[`subdir-${plugin}`].root).toBe(
|
|
||||||
`libs/subdir/${plugin}`
|
|
||||||
);
|
|
||||||
expect(workspace.projects[`subdir-${plugin}-e2e`]).toBeTruthy();
|
|
||||||
}, 45000);
|
|
||||||
});
|
|
||||||
describe('--tags', () => {
|
|
||||||
it('should add tags to nx.json', async () => {
|
|
||||||
ensureProject();
|
|
||||||
const plugin = uniq('plugin');
|
|
||||||
runCLI(
|
|
||||||
`generate @nrwl/nx-plugin:plugin ${plugin} --linter=${linter} --tags=e2etag,e2ePackage --importPath=@proj/${plugin}`
|
|
||||||
);
|
|
||||||
const nxJson = readJson('nx.json');
|
|
||||||
expect(nxJson.projects[plugin].tags).toEqual(['e2etag', 'e2ePackage']);
|
|
||||||
}, 45000);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,206 +1,203 @@
|
|||||||
import {
|
import {
|
||||||
checkFilesDoNotExist,
|
checkFilesDoNotExist,
|
||||||
checkFilesExist,
|
checkFilesExist,
|
||||||
ensureProject,
|
newProject,
|
||||||
forEachCli,
|
readFile,
|
||||||
readJson,
|
readJson,
|
||||||
runCLI,
|
runCLI,
|
||||||
uniq,
|
uniq,
|
||||||
updateFile,
|
updateFile,
|
||||||
readFile,
|
|
||||||
} from '@nrwl/e2e/utils';
|
} from '@nrwl/e2e/utils';
|
||||||
|
|
||||||
forEachCli('nx', (cli) => {
|
describe('Build React libraries and apps', () => {
|
||||||
describe('Build React libraries and apps', () => {
|
/**
|
||||||
/**
|
* Graph:
|
||||||
* Graph:
|
*
|
||||||
*
|
* childLib
|
||||||
* childLib
|
* /
|
||||||
* /
|
* app => parentLib =>
|
||||||
* app => parentLib =>
|
* \
|
||||||
* \
|
* childLib2
|
||||||
* childLib2
|
*
|
||||||
*
|
*/
|
||||||
*/
|
let app: string;
|
||||||
let app: string;
|
let parentLib: string;
|
||||||
let parentLib: string;
|
let childLib: string;
|
||||||
let childLib: string;
|
let childLib2: string;
|
||||||
let childLib2: string;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
app = uniq('app');
|
app = uniq('app');
|
||||||
parentLib = uniq('parentlib');
|
parentLib = uniq('parentlib');
|
||||||
childLib = uniq('childlib');
|
childLib = uniq('childlib');
|
||||||
childLib2 = uniq('childlib2');
|
childLib2 = uniq('childlib2');
|
||||||
|
|
||||||
ensureProject();
|
newProject();
|
||||||
|
|
||||||
runCLI(`generate @nrwl/react:app ${app}`);
|
runCLI(`generate @nrwl/react:app ${app}`);
|
||||||
|
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/react:library ${parentLib} --publishable --importPath=@proj/${parentLib} --no-interactive`
|
`generate @nrwl/react:library ${parentLib} --publishable --importPath=@proj/${parentLib} --no-interactive`
|
||||||
);
|
);
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/react:library ${childLib} --publishable --importPath=@proj/${childLib} --no-interactive`
|
`generate @nrwl/react:library ${childLib} --publishable --importPath=@proj/${childLib} --no-interactive`
|
||||||
);
|
);
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/react:library ${childLib2} --publishable --importPath=@proj/${childLib2} --no-interactive`
|
`generate @nrwl/react:library ${childLib2} --publishable --importPath=@proj/${childLib2} --no-interactive`
|
||||||
);
|
);
|
||||||
|
|
||||||
// create dependencies by importing
|
// create dependencies by importing
|
||||||
const createDep = (parent, children: string[]) => {
|
const createDep = (parent, children: string[]) => {
|
||||||
updateFile(
|
updateFile(
|
||||||
`libs/${parent}/src/lib/${parent}.tsx`,
|
`libs/${parent}/src/lib/${parent}.tsx`,
|
||||||
`
|
`
|
||||||
${children.map((entry) => `import '@proj/${entry}';`).join('\n')}
|
${children.map((entry) => `import '@proj/${entry}';`).join('\n')}
|
||||||
|
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
createDep(parentLib, [childLib, childLib2]);
|
createDep(parentLib, [childLib, childLib2]);
|
||||||
|
|
||||||
updateFile(
|
updateFile(
|
||||||
`apps/${app}/src/main.tsx`,
|
`apps/${app}/src/main.tsx`,
|
||||||
`
|
`
|
||||||
import "@proj/${parentLib}";
|
import "@proj/${parentLib}";
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
// we are setting paths to {} to make sure built libs are read from dist
|
// we are setting paths to {} to make sure built libs are read from dist
|
||||||
updateFile('tsconfig.base.json', (c) => {
|
updateFile('tsconfig.base.json', (c) => {
|
||||||
const json = JSON.parse(c);
|
const json = JSON.parse(c);
|
||||||
json.compilerOptions.paths = {};
|
json.compilerOptions.paths = {};
|
||||||
return JSON.stringify(json, null, 2);
|
return JSON.stringify(json, null, 2);
|
||||||
});
|
|
||||||
|
|
||||||
// Add assets to child lib
|
|
||||||
updateFile(cli === 'angular' ? 'angular.json' : 'workspace.json', (c) => {
|
|
||||||
const json = JSON.parse(c);
|
|
||||||
json.projects[childLib].architect.build.options.assets = [
|
|
||||||
`libs/${childLib}/src/assets`,
|
|
||||||
];
|
|
||||||
return JSON.stringify(json, null, 2);
|
|
||||||
});
|
|
||||||
updateFile(`libs/${childLib}/src/assets/hello.txt`, 'Hello World!');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if the dependent library has not been built before building the parent lib', () => {
|
// Add assets to child lib
|
||||||
expect.assertions(2);
|
updateFile('workspace.json', (c) => {
|
||||||
|
const json = JSON.parse(c);
|
||||||
try {
|
json.projects[childLib].architect.build.options.assets = [
|
||||||
runCLI(`build ${parentLib}`);
|
`libs/${childLib}/src/assets`,
|
||||||
} catch (e) {
|
];
|
||||||
expect(e.stderr.toString()).toContain(
|
return JSON.stringify(json, null, 2);
|
||||||
`Some of the project ${parentLib}'s dependencies have not been built yet. Please build these libraries before:`
|
|
||||||
);
|
|
||||||
expect(e.stderr.toString()).toContain(`${childLib}`);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
updateFile(`libs/${childLib}/src/assets/hello.txt`, 'Hello World!');
|
||||||
|
});
|
||||||
|
|
||||||
it('should preserve the tsconfig target set by user', () => {
|
it('should throw an error if the dependent library has not been built before building the parent lib', () => {
|
||||||
// Setup
|
expect.assertions(2);
|
||||||
const myLib = uniq('my-lib');
|
|
||||||
runCLI(
|
try {
|
||||||
`generate @nrwl/react:library ${myLib} --publishable=true --importPath="@mproj/${myLib}" --no-interactive`
|
runCLI(`build ${parentLib}`);
|
||||||
|
} catch (e) {
|
||||||
|
expect(e.stderr.toString()).toContain(
|
||||||
|
`Some of the project ${parentLib}'s dependencies have not been built yet. Please build these libraries before:`
|
||||||
);
|
);
|
||||||
|
expect(e.stderr.toString()).toContain(`${childLib}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
it('should preserve the tsconfig target set by user', () => {
|
||||||
*
|
// Setup
|
||||||
* Here I update my library file
|
const myLib = uniq('my-lib');
|
||||||
* I am just adding this in the end:
|
runCLI(
|
||||||
*
|
`generate @nrwl/react:library ${myLib} --publishable=true --importPath="@mproj/${myLib}" --no-interactive`
|
||||||
* export const TestFunction = async () => {
|
);
|
||||||
* return await Promise.resolve('Done!')
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* So that I can see the change in the Promise.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
updateFile(`libs/${myLib}/src/lib/${myLib}.tsx`, (content) => {
|
/**
|
||||||
return `
|
*
|
||||||
|
* Here I update my library file
|
||||||
|
* I am just adding this in the end:
|
||||||
|
*
|
||||||
|
* export const TestFunction = async () => {
|
||||||
|
* return await Promise.resolve('Done!')
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* So that I can see the change in the Promise.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
updateFile(`libs/${myLib}/src/lib/${myLib}.tsx`, (content) => {
|
||||||
|
return `
|
||||||
${content} \n
|
${content} \n
|
||||||
export const TestFunction = async () => {
|
export const TestFunction = async () => {
|
||||||
return await Promise.resolve('Done!')
|
return await Promise.resolve('Done!')
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
});
|
});
|
||||||
|
|
||||||
updateFile(`libs/${myLib}/tsconfig.json`, (content) => {
|
updateFile(`libs/${myLib}/tsconfig.json`, (content) => {
|
||||||
const json = JSON.parse(content);
|
const json = JSON.parse(content);
|
||||||
|
|
||||||
/**
|
|
||||||
* Set target as es3!!
|
|
||||||
*/
|
|
||||||
|
|
||||||
json.compilerOptions.target = 'es3';
|
|
||||||
return JSON.stringify(json, null, 2);
|
|
||||||
});
|
|
||||||
// What we're testing
|
|
||||||
runCLI(`build ${myLib}`);
|
|
||||||
// Assertion
|
|
||||||
const content = readFile(`dist/libs/${myLib}/${myLib}.esm.js`);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Then check if the result contains this "promise" polyfill?
|
* Set target as es3!!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
expect(content).toContain('function __generator(thisArg, body) {');
|
json.compilerOptions.target = 'es3';
|
||||||
|
return JSON.stringify(json, null, 2);
|
||||||
});
|
});
|
||||||
|
// What we're testing
|
||||||
|
runCLI(`build ${myLib}`);
|
||||||
|
// Assertion
|
||||||
|
const content = readFile(`dist/libs/${myLib}/${myLib}.esm.js`);
|
||||||
|
|
||||||
it('should build the library when it does not have any deps', () => {
|
/**
|
||||||
const output = runCLI(`build ${childLib}`);
|
* Then check if the result contains this "promise" polyfill?
|
||||||
expect(output).toContain(`${childLib}.esm.js`);
|
*/
|
||||||
expect(output).toContain(`Bundle complete`);
|
|
||||||
checkFilesExist(`dist/libs/${childLib}/assets/hello.txt`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should copy the README to dist', () => {
|
expect(content).toContain('function __generator(thisArg, body) {');
|
||||||
const output = runCLI(`build ${childLib2}`);
|
|
||||||
expect(output).toContain(`Bundle complete`);
|
|
||||||
checkFilesExist(`dist/libs/${childLib2}/README.md`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should properly add references to any dependency into the parent package.json', () => {
|
|
||||||
const childLibOutput = runCLI(`build ${childLib}`);
|
|
||||||
const childLib2Output = runCLI(`build ${childLib2}`);
|
|
||||||
const parentLibOutput = runCLI(`build ${parentLib}`);
|
|
||||||
|
|
||||||
expect(childLibOutput).toContain(`${childLib}.esm.js`);
|
|
||||||
expect(childLibOutput).toContain(`${childLib}.umd.js`);
|
|
||||||
expect(childLibOutput).toContain(`Bundle complete`);
|
|
||||||
|
|
||||||
expect(childLib2Output).toContain(`${childLib2}.esm.js`);
|
|
||||||
expect(childLib2Output).toContain(`${childLib2}.umd.js`);
|
|
||||||
expect(childLib2Output).toContain(`Bundle complete`);
|
|
||||||
|
|
||||||
expect(parentLibOutput).toContain(`${parentLib}.esm.js`);
|
|
||||||
expect(parentLibOutput).toContain(`${parentLib}.umd.js`);
|
|
||||||
expect(parentLibOutput).toContain(`Bundle complete`);
|
|
||||||
|
|
||||||
const jsonFile = readJson(`dist/libs/${parentLib}/package.json`);
|
|
||||||
expect(jsonFile.peerDependencies).toEqual(
|
|
||||||
expect.objectContaining({
|
|
||||||
[`@proj/${childLib}`]: '0.0.1',
|
|
||||||
[`@proj/${childLib2}`]: '0.0.1',
|
|
||||||
react: expect.anything(),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should build an app composed out of buildable libs', () => {
|
|
||||||
const buildWithDeps = runCLI(`build ${app} --with-deps`);
|
|
||||||
expect(buildWithDeps).toContain(`Running target "build" succeeded`);
|
|
||||||
checkFilesDoNotExist(`apps/${app}/tsconfig/tsconfig.nx-tmp`);
|
|
||||||
|
|
||||||
// we remove all path mappings from the root tsconfig, so when trying to build
|
|
||||||
// libs from source, the builder will throw
|
|
||||||
const failedBuild = runCLI(
|
|
||||||
`build ${app} --with-deps --buildLibsFromSource`,
|
|
||||||
{ silenceError: true }
|
|
||||||
);
|
|
||||||
expect(failedBuild).toContain(`Can't resolve`);
|
|
||||||
}, 1000000);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should build the library when it does not have any deps', () => {
|
||||||
|
const output = runCLI(`build ${childLib}`);
|
||||||
|
expect(output).toContain(`${childLib}.esm.js`);
|
||||||
|
expect(output).toContain(`Bundle complete`);
|
||||||
|
checkFilesExist(`dist/libs/${childLib}/assets/hello.txt`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should copy the README to dist', () => {
|
||||||
|
const output = runCLI(`build ${childLib2}`);
|
||||||
|
expect(output).toContain(`Bundle complete`);
|
||||||
|
checkFilesExist(`dist/libs/${childLib2}/README.md`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should properly add references to any dependency into the parent package.json', () => {
|
||||||
|
const childLibOutput = runCLI(`build ${childLib}`);
|
||||||
|
const childLib2Output = runCLI(`build ${childLib2}`);
|
||||||
|
const parentLibOutput = runCLI(`build ${parentLib}`);
|
||||||
|
|
||||||
|
expect(childLibOutput).toContain(`${childLib}.esm.js`);
|
||||||
|
expect(childLibOutput).toContain(`${childLib}.umd.js`);
|
||||||
|
expect(childLibOutput).toContain(`Bundle complete`);
|
||||||
|
|
||||||
|
expect(childLib2Output).toContain(`${childLib2}.esm.js`);
|
||||||
|
expect(childLib2Output).toContain(`${childLib2}.umd.js`);
|
||||||
|
expect(childLib2Output).toContain(`Bundle complete`);
|
||||||
|
|
||||||
|
expect(parentLibOutput).toContain(`${parentLib}.esm.js`);
|
||||||
|
expect(parentLibOutput).toContain(`${parentLib}.umd.js`);
|
||||||
|
expect(parentLibOutput).toContain(`Bundle complete`);
|
||||||
|
|
||||||
|
const jsonFile = readJson(`dist/libs/${parentLib}/package.json`);
|
||||||
|
expect(jsonFile.peerDependencies).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
[`@proj/${childLib}`]: '0.0.1',
|
||||||
|
[`@proj/${childLib2}`]: '0.0.1',
|
||||||
|
react: expect.anything(),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should build an app composed out of buildable libs', () => {
|
||||||
|
const buildWithDeps = runCLI(`build ${app} --with-deps`);
|
||||||
|
expect(buildWithDeps).toContain(`Running target "build" succeeded`);
|
||||||
|
checkFilesDoNotExist(`apps/${app}/tsconfig/tsconfig.nx-tmp`);
|
||||||
|
|
||||||
|
// we remove all path mappings from the root tsconfig, so when trying to build
|
||||||
|
// libs from source, the builder will throw
|
||||||
|
const failedBuild = runCLI(
|
||||||
|
`build ${app} --with-deps --buildLibsFromSource`,
|
||||||
|
{ silenceError: true }
|
||||||
|
);
|
||||||
|
expect(failedBuild).toContain(`Can't resolve`);
|
||||||
|
}, 1000000);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,8 +2,7 @@ import { serializeJson } from '@nrwl/workspace';
|
|||||||
import {
|
import {
|
||||||
checkFilesDoNotExist,
|
checkFilesDoNotExist,
|
||||||
checkFilesExist,
|
checkFilesExist,
|
||||||
ensureProject,
|
newProject,
|
||||||
forEachCli,
|
|
||||||
readFile,
|
readFile,
|
||||||
readJson,
|
readJson,
|
||||||
renameFile,
|
renameFile,
|
||||||
@ -14,406 +13,392 @@ import {
|
|||||||
workspaceConfigName,
|
workspaceConfigName,
|
||||||
} from '@nrwl/e2e/utils';
|
} from '@nrwl/e2e/utils';
|
||||||
|
|
||||||
forEachCli('nx', () => {
|
describe('React Applications', () => {
|
||||||
describe('React Applications', () => {
|
it('should be able to generate a react app + lib', async () => {
|
||||||
it('should be able to generate a react app + lib', async () => {
|
newProject();
|
||||||
ensureProject();
|
const appName = uniq('app');
|
||||||
const appName = uniq('app');
|
const libName = uniq('lib');
|
||||||
const libName = uniq('lib');
|
|
||||||
|
|
||||||
runCLI(
|
runCLI(`generate @nrwl/react:app ${appName} --style=css --no-interactive`);
|
||||||
`generate @nrwl/react:app ${appName} --style=css --no-interactive`
|
runCLI(`generate @nrwl/react:lib ${libName} --style=css --no-interactive`);
|
||||||
);
|
|
||||||
runCLI(
|
|
||||||
`generate @nrwl/react:lib ${libName} --style=css --no-interactive`
|
|
||||||
);
|
|
||||||
|
|
||||||
// Libs should not include package.json by default
|
// Libs should not include package.json by default
|
||||||
checkFilesDoNotExist(`libs/${libName}/package.json`);
|
checkFilesDoNotExist(`libs/${libName}/package.json`);
|
||||||
|
|
||||||
const mainPath = `apps/${appName}/src/main.tsx`;
|
const mainPath = `apps/${appName}/src/main.tsx`;
|
||||||
updateFile(mainPath, `import '@proj/${libName}';\n` + readFile(mainPath));
|
updateFile(mainPath, `import '@proj/${libName}';\n` + readFile(mainPath));
|
||||||
|
|
||||||
const libTestResults = await runCLIAsync(`test ${libName}`);
|
const libTestResults = await runCLIAsync(`test ${libName}`);
|
||||||
expect(libTestResults.combinedOutput).toContain(
|
expect(libTestResults.combinedOutput).toContain(
|
||||||
'Test Suites: 1 passed, 1 total'
|
'Test Suites: 1 passed, 1 total'
|
||||||
);
|
);
|
||||||
|
|
||||||
await testGeneratedApp(appName, {
|
await testGeneratedApp(appName, {
|
||||||
checkStyles: true,
|
checkStyles: true,
|
||||||
checkProdBuild: true,
|
checkProdBuild: true,
|
||||||
checkLinter: true,
|
checkLinter: true,
|
||||||
checkE2E: true,
|
checkE2E: true,
|
||||||
});
|
});
|
||||||
}, 120000);
|
}, 120000);
|
||||||
|
|
||||||
it('should support vendor sourcemaps', () => {
|
it('should support vendor sourcemaps', () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const appName = uniq('app');
|
const appName = uniq('app');
|
||||||
|
|
||||||
runCLI(`generate @nrwl/react:app ${appName} --no-interactive`);
|
runCLI(`generate @nrwl/react:app ${appName} --no-interactive`);
|
||||||
|
|
||||||
// By default, vendor sourcemaps are off
|
// By default, vendor sourcemaps are off
|
||||||
runCLI(`build ${appName}`);
|
runCLI(`build ${appName}`);
|
||||||
|
|
||||||
let vendorContent = readFile(`dist/apps/${appName}/vendor.js`);
|
let vendorContent = readFile(`dist/apps/${appName}/vendor.js`);
|
||||||
|
|
||||||
expect(vendorContent).not.toMatch(/sourceMappingURL/);
|
expect(vendorContent).not.toMatch(/sourceMappingURL/);
|
||||||
|
|
||||||
// Turn vendor sourcemaps on
|
// Turn vendor sourcemaps on
|
||||||
updateFile(`workspace.json`, (content) => {
|
updateFile(`workspace.json`, (content) => {
|
||||||
const json = JSON.parse(content);
|
const json = JSON.parse(content);
|
||||||
json.projects[appName].architect.build.options.sourceMap = {
|
json.projects[appName].architect.build.options.sourceMap = {
|
||||||
scripts: true,
|
scripts: true,
|
||||||
vendor: true,
|
vendor: true,
|
||||||
};
|
};
|
||||||
return JSON.stringify(json, null, 2);
|
return JSON.stringify(json, null, 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
runCLI(`build ${appName}`);
|
runCLI(`build ${appName}`);
|
||||||
vendorContent = readFile(`dist/apps/${appName}/vendor.js`);
|
vendorContent = readFile(`dist/apps/${appName}/vendor.js`);
|
||||||
|
|
||||||
expect(vendorContent).toMatch(/sourceMappingURL/);
|
expect(vendorContent).toMatch(/sourceMappingURL/);
|
||||||
}, 120000);
|
}, 120000);
|
||||||
|
|
||||||
it('should be able to generate a publishable react lib', async () => {
|
it('should be able to generate a publishable react lib', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const libName = uniq('lib');
|
const libName = uniq('lib');
|
||||||
|
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/react:lib ${libName} --publishable --importPath=@proj/${libName} --no-interactive`
|
`generate @nrwl/react:lib ${libName} --publishable --importPath=@proj/${libName} --no-interactive`
|
||||||
);
|
);
|
||||||
|
|
||||||
const libTestResults = await runCLIAsync(
|
const libTestResults = await runCLIAsync(
|
||||||
`build ${libName} --no-extract-css`
|
`build ${libName} --no-extract-css`
|
||||||
);
|
);
|
||||||
expect(libTestResults.stdout).toContain('Bundle complete.');
|
expect(libTestResults.stdout).toContain('Bundle complete.');
|
||||||
|
|
||||||
checkFilesExist(
|
checkFilesExist(
|
||||||
`dist/libs/${libName}/package.json`,
|
`dist/libs/${libName}/package.json`,
|
||||||
`dist/libs/${libName}/index.d.ts`,
|
`dist/libs/${libName}/index.d.ts`,
|
||||||
`dist/libs/${libName}/${libName}.esm.js`,
|
`dist/libs/${libName}/${libName}.esm.js`,
|
||||||
`dist/libs/${libName}/${libName}.umd.js`
|
`dist/libs/${libName}/${libName}.umd.js`
|
||||||
);
|
);
|
||||||
|
|
||||||
checkFilesDoNotExist(
|
checkFilesDoNotExist(
|
||||||
`dist/libs/${libName}/${libName}.esm.css`,
|
`dist/libs/${libName}/${libName}.esm.css`,
|
||||||
`dist/libs/${libName}/${libName}.umd.css`
|
`dist/libs/${libName}/${libName}.umd.css`
|
||||||
);
|
);
|
||||||
|
|
||||||
await runCLIAsync(`build ${libName} --extract-css`);
|
await runCLIAsync(`build ${libName} --extract-css`);
|
||||||
|
|
||||||
checkFilesExist(
|
checkFilesExist(
|
||||||
`dist/libs/${libName}/package.json`,
|
`dist/libs/${libName}/package.json`,
|
||||||
`dist/libs/${libName}/index.d.ts`,
|
`dist/libs/${libName}/index.d.ts`,
|
||||||
`dist/libs/${libName}/${libName}.esm.css`,
|
`dist/libs/${libName}/${libName}.esm.css`,
|
||||||
`dist/libs/${libName}/${libName}.esm.js`,
|
`dist/libs/${libName}/${libName}.esm.js`,
|
||||||
`dist/libs/${libName}/${libName}.umd.css`,
|
`dist/libs/${libName}/${libName}.umd.css`,
|
||||||
`dist/libs/${libName}/${libName}.umd.js`
|
`dist/libs/${libName}/${libName}.umd.js`
|
||||||
);
|
);
|
||||||
}, 120000);
|
}, 120000);
|
||||||
|
|
||||||
it('should be able to generate a react lib with no components', async () => {
|
it('should be able to generate a react lib with no components', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const appName = uniq('app');
|
const appName = uniq('app');
|
||||||
const libName = uniq('lib');
|
const libName = uniq('lib');
|
||||||
|
|
||||||
runCLI(`generate @nrwl/react:app ${appName} --no-interactive`);
|
runCLI(`generate @nrwl/react:app ${appName} --no-interactive`);
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/react:lib ${libName} --no-interactive --no-component`
|
`generate @nrwl/react:lib ${libName} --no-interactive --no-component`
|
||||||
);
|
);
|
||||||
|
|
||||||
const mainPath = `apps/${appName}/src/main.tsx`;
|
const mainPath = `apps/${appName}/src/main.tsx`;
|
||||||
updateFile(mainPath, `import '@proj/${libName}';\n` + readFile(mainPath));
|
updateFile(mainPath, `import '@proj/${libName}';\n` + readFile(mainPath));
|
||||||
|
|
||||||
const libTestResults = await runCLIAsync(`test ${libName}`);
|
const libTestResults = await runCLIAsync(`test ${libName}`);
|
||||||
expect(libTestResults.stderr).toBe('');
|
expect(libTestResults.stderr).toBe('');
|
||||||
|
|
||||||
await testGeneratedApp(appName, {
|
await testGeneratedApp(appName, {
|
||||||
checkStyles: true,
|
checkStyles: true,
|
||||||
checkProdBuild: false,
|
checkProdBuild: false,
|
||||||
checkLinter: false,
|
checkLinter: false,
|
||||||
checkE2E: false,
|
checkE2E: false,
|
||||||
});
|
});
|
||||||
}, 120000);
|
}, 120000);
|
||||||
|
|
||||||
it('should not create a dist folder if there is an error', async () => {
|
it('should not create a dist folder if there is an error', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const libName = uniq('lib');
|
const libName = uniq('lib');
|
||||||
|
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/react:lib ${libName} --publishable --importPath=@proj/${libName} --no-interactive`
|
`generate @nrwl/react:lib ${libName} --publishable --importPath=@proj/${libName} --no-interactive`
|
||||||
);
|
);
|
||||||
|
|
||||||
const mainPath = `libs/${libName}/src/lib/${libName}.tsx`;
|
const mainPath = `libs/${libName}/src/lib/${libName}.tsx`;
|
||||||
updateFile(mainPath, readFile(mainPath) + `\n console.log(a);`); // should error - "a" will be undefined
|
updateFile(mainPath, readFile(mainPath) + `\n console.log(a);`); // should error - "a" will be undefined
|
||||||
|
|
||||||
await expect(runCLIAsync(`build ${libName}`)).rejects.toThrow(
|
await expect(runCLIAsync(`build ${libName}`)).rejects.toThrow(
|
||||||
/Bundle failed/
|
/Bundle failed/
|
||||||
);
|
);
|
||||||
expect(() => {
|
expect(() => {
|
||||||
checkFilesExist(`dist/libs/${libName}/package.json`);
|
checkFilesExist(`dist/libs/${libName}/package.json`);
|
||||||
}).toThrow();
|
}).toThrow();
|
||||||
}, 120000);
|
}, 120000);
|
||||||
|
|
||||||
it('should generate app with routing', async () => {
|
it('should generate app with routing', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const appName = uniq('app');
|
const appName = uniq('app');
|
||||||
|
|
||||||
runCLI(`generate @nrwl/react:app ${appName} --routing --no-interactive`);
|
runCLI(`generate @nrwl/react:app ${appName} --routing --no-interactive`);
|
||||||
|
|
||||||
await testGeneratedApp(appName, {
|
await testGeneratedApp(appName, {
|
||||||
checkStyles: true,
|
checkStyles: true,
|
||||||
checkProdBuild: false,
|
checkProdBuild: false,
|
||||||
checkLinter: false,
|
checkLinter: false,
|
||||||
checkE2E: false,
|
checkE2E: false,
|
||||||
});
|
});
|
||||||
}, 120000);
|
}, 120000);
|
||||||
|
|
||||||
it('should generate app with different style options', async () => {
|
it('should generate app with different style options', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
|
|
||||||
const styledComponentsApp = uniq('app');
|
const styledComponentsApp = uniq('app');
|
||||||
|
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/react:app ${styledComponentsApp} --style styled-components --no-interactive`
|
`generate @nrwl/react:app ${styledComponentsApp} --style styled-components --no-interactive`
|
||||||
);
|
);
|
||||||
|
|
||||||
// Checking that we can enable displayName just for development.
|
// Checking that we can enable displayName just for development.
|
||||||
updateFile(
|
updateFile(
|
||||||
`apps/${styledComponentsApp}/.babelrc`,
|
`apps/${styledComponentsApp}/.babelrc`,
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
{
|
{
|
||||||
presets: ['@nrwl/react/babel'],
|
presets: ['@nrwl/react/babel'],
|
||||||
plugins: [
|
plugins: [
|
||||||
[
|
['styled-components', { pure: true, ssr: true, displayName: true }],
|
||||||
'styled-components',
|
],
|
||||||
{ pure: true, ssr: true, displayName: true },
|
env: {
|
||||||
],
|
production: {
|
||||||
],
|
plugins: [
|
||||||
env: {
|
[
|
||||||
production: {
|
'styled-components',
|
||||||
plugins: [
|
{ pure: true, ssr: true, displayName: false },
|
||||||
[
|
|
||||||
'styled-components',
|
|
||||||
{ pure: true, ssr: true, displayName: false },
|
|
||||||
],
|
|
||||||
],
|
],
|
||||||
},
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
null,
|
},
|
||||||
2
|
null,
|
||||||
)
|
2
|
||||||
);
|
)
|
||||||
|
);
|
||||||
|
|
||||||
await testGeneratedApp(styledComponentsApp, {
|
await testGeneratedApp(styledComponentsApp, {
|
||||||
checkStyles: false,
|
checkStyles: false,
|
||||||
checkProdBuild: true,
|
checkProdBuild: true,
|
||||||
checkLinter: false,
|
checkLinter: false,
|
||||||
checkE2E: false,
|
checkE2E: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(readFile(`dist/apps/${styledComponentsApp}/main.js`)).toContain(
|
expect(readFile(`dist/apps/${styledComponentsApp}/main.js`)).toContain(
|
||||||
'app__StyledApp'
|
'app__StyledApp'
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
readFile(`dist/apps/${styledComponentsApp}/prod/main.esm.js`)
|
readFile(`dist/apps/${styledComponentsApp}/prod/main.esm.js`)
|
||||||
).not.toContain('app__StyledApp');
|
).not.toContain('app__StyledApp');
|
||||||
|
|
||||||
const styledJsxApp = uniq('app');
|
const styledJsxApp = uniq('app');
|
||||||
|
|
||||||
|
runCLI(
|
||||||
|
`generate @nrwl/react:app ${styledJsxApp} --style styled-jsx --no-interactive`
|
||||||
|
);
|
||||||
|
|
||||||
|
await testGeneratedApp(styledJsxApp, {
|
||||||
|
checkStyles: false,
|
||||||
|
checkProdBuild: false,
|
||||||
|
checkLinter: false,
|
||||||
|
checkE2E: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const noStylesApp = uniq('app');
|
||||||
|
|
||||||
|
runCLI(
|
||||||
|
`generate @nrwl/react:app ${noStylesApp} --style none --no-interactive`
|
||||||
|
);
|
||||||
|
|
||||||
|
await testGeneratedApp(noStylesApp, {
|
||||||
|
checkStyles: false,
|
||||||
|
checkProdBuild: false,
|
||||||
|
checkLinter: false,
|
||||||
|
checkE2E: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(() =>
|
||||||
|
checkFilesExist(`dist/apps/${noStylesApp}/styles.css`)
|
||||||
|
).toThrow(/does not exist/);
|
||||||
|
expect(readFile(`dist/apps/${noStylesApp}/index.html`)).not.toContain(
|
||||||
|
`<link rel="stylesheet" href="styles.css">`
|
||||||
|
);
|
||||||
|
}, 120000);
|
||||||
|
|
||||||
|
it('should generate app with legacy-ie support', async () => {
|
||||||
|
newProject();
|
||||||
|
const appName = uniq('app');
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/react:app ${appName} --style=css --no-interactive`);
|
||||||
|
|
||||||
|
// changing browser suporrt of this application
|
||||||
|
updateFile(`apps/${appName}/.browserslistrc`, `IE 11`);
|
||||||
|
|
||||||
|
await testGeneratedApp(appName, {
|
||||||
|
checkStyles: false,
|
||||||
|
checkProdBuild: true,
|
||||||
|
checkLinter: false,
|
||||||
|
checkE2E: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const filesToCheck = [
|
||||||
|
`dist/apps/${appName}/prod/polyfills.es5.js`,
|
||||||
|
`dist/apps/${appName}/prod/main.es5.js`,
|
||||||
|
];
|
||||||
|
|
||||||
|
checkFilesExist(...filesToCheck);
|
||||||
|
|
||||||
|
expect(readFile(`dist/apps/${appName}/prod/index.html`)).toContain(
|
||||||
|
`<script src="main.esm.js" type="module"></script><script src="main.es5.js" nomodule defer></script>`
|
||||||
|
);
|
||||||
|
}, 120000);
|
||||||
|
|
||||||
|
it('should be able to add a redux slice', async () => {
|
||||||
|
newProject();
|
||||||
|
const appName = uniq('app');
|
||||||
|
const libName = uniq('lib');
|
||||||
|
|
||||||
|
runCLI(`g @nrwl/react:app ${appName} --no-interactive`);
|
||||||
|
runCLI(`g @nrwl/react:redux lemon --project=${appName}`);
|
||||||
|
runCLI(`g @nrwl/react:lib ${libName} --no-interactive`);
|
||||||
|
runCLI(`g @nrwl/react:redux orange --project=${libName}`);
|
||||||
|
|
||||||
|
const appTestResults = await runCLIAsync(`test ${appName}`);
|
||||||
|
expect(appTestResults.combinedOutput).toContain(
|
||||||
|
'Test Suites: 2 passed, 2 total'
|
||||||
|
);
|
||||||
|
|
||||||
|
const libTestResults = await runCLIAsync(`test ${libName}`);
|
||||||
|
expect(libTestResults.combinedOutput).toContain(
|
||||||
|
'Test Suites: 2 passed, 2 total'
|
||||||
|
);
|
||||||
|
}, 120000);
|
||||||
|
|
||||||
|
it('should be able to use JSX', async () => {
|
||||||
|
newProject();
|
||||||
|
const appName = uniq('app');
|
||||||
|
const libName = uniq('lib');
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/react:app ${appName} --no-interactive`);
|
||||||
|
runCLI(`generate @nrwl/react:lib ${libName} --no-interactive`);
|
||||||
|
|
||||||
|
renameFile(`apps/${appName}/src/main.tsx`, `apps/${appName}/src/main.jsx`);
|
||||||
|
renameFile(
|
||||||
|
`apps/${appName}/src/app/app.tsx`,
|
||||||
|
`apps/${appName}/src/app/app.jsx`
|
||||||
|
);
|
||||||
|
renameFile(
|
||||||
|
`apps/${appName}/src/app/app.spec.tsx`,
|
||||||
|
`apps/${appName}/src/app/app.spec.jsx`
|
||||||
|
);
|
||||||
|
renameFile(
|
||||||
|
`apps/${appName}/src/polyfills.ts`,
|
||||||
|
`apps/${appName}/src/polyfills.js`
|
||||||
|
);
|
||||||
|
const angularJson = readJson(workspaceConfigName());
|
||||||
|
|
||||||
|
angularJson.projects[
|
||||||
|
appName
|
||||||
|
].architect.build.options.main = `apps/${appName}/src/main.jsx`;
|
||||||
|
angularJson.projects[
|
||||||
|
appName
|
||||||
|
].architect.build.options.polyfills = `apps/${appName}/src/polyfills.js`;
|
||||||
|
updateFile(workspaceConfigName(), serializeJson(angularJson));
|
||||||
|
|
||||||
|
const mainPath = `apps/${appName}/src/main.jsx`;
|
||||||
|
updateFile(mainPath, `import '@proj/${libName}';\n` + readFile(mainPath));
|
||||||
|
|
||||||
|
await testGeneratedApp(appName, {
|
||||||
|
checkStyles: true,
|
||||||
|
checkProdBuild: false,
|
||||||
|
checkLinter: false,
|
||||||
|
checkE2E: false,
|
||||||
|
});
|
||||||
|
}, 30000);
|
||||||
|
|
||||||
|
async function testGeneratedApp(
|
||||||
|
appName,
|
||||||
|
opts: {
|
||||||
|
checkProdBuild: boolean;
|
||||||
|
checkStyles: boolean;
|
||||||
|
checkLinter: boolean;
|
||||||
|
checkE2E: boolean;
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
if (opts.checkLinter) {
|
||||||
|
const lintResults = runCLI(`lint ${appName}`);
|
||||||
|
expect(lintResults).toContain('All files pass linting.');
|
||||||
|
}
|
||||||
|
|
||||||
|
runCLI(`build ${appName}`);
|
||||||
|
let filesToCheck = [
|
||||||
|
`dist/apps/${appName}/index.html`,
|
||||||
|
`dist/apps/${appName}/polyfills.js`,
|
||||||
|
`dist/apps/${appName}/runtime.js`,
|
||||||
|
`dist/apps/${appName}/vendor.js`,
|
||||||
|
`dist/apps/${appName}/main.js`,
|
||||||
|
];
|
||||||
|
if (opts.checkStyles) {
|
||||||
|
filesToCheck.push(`dist/apps/${appName}/styles.js`);
|
||||||
|
}
|
||||||
|
checkFilesExist(...filesToCheck);
|
||||||
|
|
||||||
|
expect(readFile(`dist/apps/${appName}/main.js`)).toContain(
|
||||||
|
'function App() {'
|
||||||
|
);
|
||||||
|
|
||||||
|
if (opts.checkProdBuild) {
|
||||||
|
const prodOutputPath = `dist/apps/${appName}/prod`;
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/react:app ${styledJsxApp} --style styled-jsx --no-interactive`
|
`build ${appName} --prod --output-hashing none --outputPath ${prodOutputPath}`
|
||||||
);
|
);
|
||||||
|
filesToCheck = [
|
||||||
await testGeneratedApp(styledJsxApp, {
|
`${prodOutputPath}/index.html`,
|
||||||
checkStyles: false,
|
`${prodOutputPath}/runtime.js`,
|
||||||
checkProdBuild: false,
|
`${prodOutputPath}/polyfills.esm.js`,
|
||||||
checkLinter: false,
|
`${prodOutputPath}/main.esm.js`,
|
||||||
checkE2E: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const noStylesApp = uniq('app');
|
|
||||||
|
|
||||||
runCLI(
|
|
||||||
`generate @nrwl/react:app ${noStylesApp} --style none --no-interactive`
|
|
||||||
);
|
|
||||||
|
|
||||||
await testGeneratedApp(noStylesApp, {
|
|
||||||
checkStyles: false,
|
|
||||||
checkProdBuild: false,
|
|
||||||
checkLinter: false,
|
|
||||||
checkE2E: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(() =>
|
|
||||||
checkFilesExist(`dist/apps/${noStylesApp}/styles.css`)
|
|
||||||
).toThrow(/does not exist/);
|
|
||||||
expect(readFile(`dist/apps/${noStylesApp}/index.html`)).not.toContain(
|
|
||||||
`<link rel="stylesheet" href="styles.css">`
|
|
||||||
);
|
|
||||||
}, 120000);
|
|
||||||
|
|
||||||
it('should generate app with legacy-ie support', async () => {
|
|
||||||
ensureProject();
|
|
||||||
const appName = uniq('app');
|
|
||||||
|
|
||||||
runCLI(
|
|
||||||
`generate @nrwl/react:app ${appName} --style=css --no-interactive`
|
|
||||||
);
|
|
||||||
|
|
||||||
// changing browser suporrt of this application
|
|
||||||
updateFile(`apps/${appName}/.browserslistrc`, `IE 11`);
|
|
||||||
|
|
||||||
await testGeneratedApp(appName, {
|
|
||||||
checkStyles: false,
|
|
||||||
checkProdBuild: true,
|
|
||||||
checkLinter: false,
|
|
||||||
checkE2E: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const filesToCheck = [
|
|
||||||
`dist/apps/${appName}/prod/polyfills.es5.js`,
|
|
||||||
`dist/apps/${appName}/prod/main.es5.js`,
|
|
||||||
];
|
|
||||||
|
|
||||||
checkFilesExist(...filesToCheck);
|
|
||||||
|
|
||||||
expect(readFile(`dist/apps/${appName}/prod/index.html`)).toContain(
|
|
||||||
`<script src="main.esm.js" type="module"></script><script src="main.es5.js" nomodule defer></script>`
|
|
||||||
);
|
|
||||||
}, 120000);
|
|
||||||
|
|
||||||
it('should be able to add a redux slice', async () => {
|
|
||||||
ensureProject();
|
|
||||||
const appName = uniq('app');
|
|
||||||
const libName = uniq('lib');
|
|
||||||
|
|
||||||
runCLI(`g @nrwl/react:app ${appName} --no-interactive`);
|
|
||||||
runCLI(`g @nrwl/react:redux lemon --project=${appName}`);
|
|
||||||
runCLI(`g @nrwl/react:lib ${libName} --no-interactive`);
|
|
||||||
runCLI(`g @nrwl/react:redux orange --project=${libName}`);
|
|
||||||
|
|
||||||
const appTestResults = await runCLIAsync(`test ${appName}`);
|
|
||||||
expect(appTestResults.combinedOutput).toContain(
|
|
||||||
'Test Suites: 2 passed, 2 total'
|
|
||||||
);
|
|
||||||
|
|
||||||
const libTestResults = await runCLIAsync(`test ${libName}`);
|
|
||||||
expect(libTestResults.combinedOutput).toContain(
|
|
||||||
'Test Suites: 2 passed, 2 total'
|
|
||||||
);
|
|
||||||
}, 120000);
|
|
||||||
|
|
||||||
it('should be able to use JSX', async () => {
|
|
||||||
ensureProject();
|
|
||||||
const appName = uniq('app');
|
|
||||||
const libName = uniq('lib');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/react:app ${appName} --no-interactive`);
|
|
||||||
runCLI(`generate @nrwl/react:lib ${libName} --no-interactive`);
|
|
||||||
|
|
||||||
renameFile(
|
|
||||||
`apps/${appName}/src/main.tsx`,
|
|
||||||
`apps/${appName}/src/main.jsx`
|
|
||||||
);
|
|
||||||
renameFile(
|
|
||||||
`apps/${appName}/src/app/app.tsx`,
|
|
||||||
`apps/${appName}/src/app/app.jsx`
|
|
||||||
);
|
|
||||||
renameFile(
|
|
||||||
`apps/${appName}/src/app/app.spec.tsx`,
|
|
||||||
`apps/${appName}/src/app/app.spec.jsx`
|
|
||||||
);
|
|
||||||
renameFile(
|
|
||||||
`apps/${appName}/src/polyfills.ts`,
|
|
||||||
`apps/${appName}/src/polyfills.js`
|
|
||||||
);
|
|
||||||
const angularJson = readJson(workspaceConfigName());
|
|
||||||
|
|
||||||
angularJson.projects[
|
|
||||||
appName
|
|
||||||
].architect.build.options.main = `apps/${appName}/src/main.jsx`;
|
|
||||||
angularJson.projects[
|
|
||||||
appName
|
|
||||||
].architect.build.options.polyfills = `apps/${appName}/src/polyfills.js`;
|
|
||||||
updateFile(workspaceConfigName(), serializeJson(angularJson));
|
|
||||||
|
|
||||||
const mainPath = `apps/${appName}/src/main.jsx`;
|
|
||||||
updateFile(mainPath, `import '@proj/${libName}';\n` + readFile(mainPath));
|
|
||||||
|
|
||||||
await testGeneratedApp(appName, {
|
|
||||||
checkStyles: true,
|
|
||||||
checkProdBuild: false,
|
|
||||||
checkLinter: false,
|
|
||||||
checkE2E: false,
|
|
||||||
});
|
|
||||||
}, 30000);
|
|
||||||
|
|
||||||
async function testGeneratedApp(
|
|
||||||
appName,
|
|
||||||
opts: {
|
|
||||||
checkProdBuild: boolean;
|
|
||||||
checkStyles: boolean;
|
|
||||||
checkLinter: boolean;
|
|
||||||
checkE2E: boolean;
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
if (opts.checkLinter) {
|
|
||||||
const lintResults = runCLI(`lint ${appName}`);
|
|
||||||
expect(lintResults).toContain('All files pass linting.');
|
|
||||||
}
|
|
||||||
|
|
||||||
runCLI(`build ${appName}`);
|
|
||||||
let filesToCheck = [
|
|
||||||
`dist/apps/${appName}/index.html`,
|
|
||||||
`dist/apps/${appName}/polyfills.js`,
|
|
||||||
`dist/apps/${appName}/runtime.js`,
|
|
||||||
`dist/apps/${appName}/vendor.js`,
|
|
||||||
`dist/apps/${appName}/main.js`,
|
|
||||||
];
|
];
|
||||||
if (opts.checkStyles) {
|
if (opts.checkStyles) {
|
||||||
filesToCheck.push(`dist/apps/${appName}/styles.js`);
|
filesToCheck.push(`${prodOutputPath}/styles.css`);
|
||||||
}
|
}
|
||||||
checkFilesExist(...filesToCheck);
|
checkFilesExist(...filesToCheck);
|
||||||
|
|
||||||
expect(readFile(`dist/apps/${appName}/main.js`)).toContain(
|
if (opts.checkStyles) {
|
||||||
'function App() {'
|
expect(readFile(`${prodOutputPath}/index.html`)).toContain(
|
||||||
);
|
`<link rel="stylesheet" href="styles.css">`
|
||||||
|
|
||||||
if (opts.checkProdBuild) {
|
|
||||||
const prodOutputPath = `dist/apps/${appName}/prod`;
|
|
||||||
runCLI(
|
|
||||||
`build ${appName} --prod --output-hashing none --outputPath ${prodOutputPath}`
|
|
||||||
);
|
);
|
||||||
filesToCheck = [
|
|
||||||
`${prodOutputPath}/index.html`,
|
|
||||||
`${prodOutputPath}/runtime.js`,
|
|
||||||
`${prodOutputPath}/polyfills.esm.js`,
|
|
||||||
`${prodOutputPath}/main.esm.js`,
|
|
||||||
];
|
|
||||||
if (opts.checkStyles) {
|
|
||||||
filesToCheck.push(`${prodOutputPath}/styles.css`);
|
|
||||||
}
|
|
||||||
checkFilesExist(...filesToCheck);
|
|
||||||
|
|
||||||
if (opts.checkStyles) {
|
|
||||||
expect(readFile(`${prodOutputPath}/index.html`)).toContain(
|
|
||||||
`<link rel="stylesheet" href="styles.css">`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const testResults = await runCLIAsync(`test ${appName}`);
|
|
||||||
expect(testResults.combinedOutput).toContain(
|
|
||||||
'Test Suites: 1 passed, 1 total'
|
|
||||||
);
|
|
||||||
|
|
||||||
if (opts.checkE2E) {
|
|
||||||
const e2eResults = runCLI(`e2e ${appName}-e2e`);
|
|
||||||
expect(e2eResults).toContain('All specs passed!');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
const testResults = await runCLIAsync(`test ${appName}`);
|
||||||
|
expect(testResults.combinedOutput).toContain(
|
||||||
|
'Test Suites: 1 passed, 1 total'
|
||||||
|
);
|
||||||
|
|
||||||
|
if (opts.checkE2E) {
|
||||||
|
const e2eResults = runCLI(`e2e ${appName}-e2e`);
|
||||||
|
expect(e2eResults).toContain('All specs passed!');
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,34 +1,32 @@
|
|||||||
import {
|
import {
|
||||||
forEachCli,
|
checkFilesExist,
|
||||||
|
newProject,
|
||||||
|
readFile,
|
||||||
runCLI,
|
runCLI,
|
||||||
supportUi,
|
supportUi,
|
||||||
uniq,
|
|
||||||
ensureProject,
|
|
||||||
tmpProjPath,
|
tmpProjPath,
|
||||||
checkFilesExist,
|
uniq,
|
||||||
readFile,
|
|
||||||
} from '@nrwl/e2e/utils';
|
} from '@nrwl/e2e/utils';
|
||||||
import { writeFileSync, mkdirSync } from 'fs';
|
import { mkdirSync, writeFileSync } from 'fs';
|
||||||
|
|
||||||
forEachCli(() => {
|
describe('Storybook schematics', () => {
|
||||||
describe('Storybook schematics', () => {
|
describe('running Storybook and Cypress', () => {
|
||||||
describe('running Storybook and Cypress', () => {
|
it('should execute e2e tests using Cypress running against Storybook', () => {
|
||||||
it('should execute e2e tests using Cypress running against Storybook', () => {
|
newProject();
|
||||||
ensureProject();
|
|
||||||
|
|
||||||
const myapp = uniq('myapp');
|
const myapp = uniq('myapp');
|
||||||
runCLI(`generate @nrwl/angular:app ${myapp} --no-interactive`);
|
runCLI(`generate @nrwl/angular:app ${myapp} --no-interactive`);
|
||||||
|
|
||||||
const mylib = uniq('test-ui-lib');
|
const mylib = uniq('test-ui-lib');
|
||||||
createTestUILib(mylib);
|
createTestUILib(mylib);
|
||||||
const mylib2 = uniq('test-ui-lib-react');
|
const mylib2 = uniq('test-ui-lib-react');
|
||||||
runCLI(`generate @nrwl/react:lib ${mylib2} --no-interactive`);
|
runCLI(`generate @nrwl/react:lib ${mylib2} --no-interactive`);
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/react:component Button --project=${mylib2} --no-interactive`
|
`generate @nrwl/react:component Button --project=${mylib2} --no-interactive`
|
||||||
);
|
);
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
tmpProjPath(`libs/${mylib2}/src/lib/button.tsx`),
|
tmpProjPath(`libs/${mylib2}/src/lib/button.tsx`),
|
||||||
`
|
`
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import './button.css';
|
import './button.css';
|
||||||
@ -52,10 +50,10 @@ forEachCli(() => {
|
|||||||
|
|
||||||
export default Button;
|
export default Button;
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
tmpProjPath(`libs/${mylib2}/src/lib/button.stories.tsx`),
|
tmpProjPath(`libs/${mylib2}/src/lib/button.stories.tsx`),
|
||||||
`
|
`
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Button, ButtonStyle } from './button';
|
import { Button, ButtonStyle } from './button';
|
||||||
import { text, number } from '@storybook/addon-knobs';
|
import { text, number } from '@storybook/addon-knobs';
|
||||||
@ -73,20 +71,20 @@ forEachCli(() => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/angular:storybook-configuration ${mylib} --configureCypress --generateStories --generateCypressSpecs --no-interactive`
|
`generate @nrwl/angular:storybook-configuration ${mylib} --configureCypress --generateStories --generateCypressSpecs --no-interactive`
|
||||||
);
|
);
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/angular:stories ${mylib} --generateCypressSpecs --no-interactive`
|
`generate @nrwl/angular:stories ${mylib} --generateCypressSpecs --no-interactive`
|
||||||
);
|
);
|
||||||
|
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
tmpProjPath(
|
tmpProjPath(
|
||||||
`apps/${mylib}-e2e/src/integration/test-button/test-button.component.spec.ts`
|
`apps/${mylib}-e2e/src/integration/test-button/test-button.component.spec.ts`
|
||||||
),
|
),
|
||||||
`
|
`
|
||||||
describe('test-ui-lib3726865', () => {
|
describe('test-ui-lib3726865', () => {
|
||||||
|
|
||||||
it('should render the component', () => {
|
it('should render the component', () => {
|
||||||
@ -104,16 +102,16 @@ forEachCli(() => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/react:storybook-configuration ${mylib2} --configureCypress --no-interactive`
|
`generate @nrwl/react:storybook-configuration ${mylib2} --configureCypress --no-interactive`
|
||||||
);
|
);
|
||||||
|
|
||||||
mkdirSync(tmpProjPath(`apps/${mylib2}-e2e/src/integration`));
|
mkdirSync(tmpProjPath(`apps/${mylib2}-e2e/src/integration`));
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
tmpProjPath(`apps/${mylib2}-e2e/src/integration/button.spec.ts`),
|
tmpProjPath(`apps/${mylib2}-e2e/src/integration/button.spec.ts`),
|
||||||
`
|
`
|
||||||
describe('react-ui', () => {
|
describe('react-ui', () => {
|
||||||
it('should render the component', () => {
|
it('should render the component', () => {
|
||||||
cy.visit(
|
cy.visit(
|
||||||
@ -130,77 +128,73 @@ forEachCli(() => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (supportUi()) {
|
||||||
|
expect(runCLI(`run ${mylib}-e2e:e2e --no-watch`)).toContain(
|
||||||
|
'All specs passed!'
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (supportUi()) {
|
runCLI(`run ${mylib}:build-storybook`);
|
||||||
expect(runCLI(`run ${mylib}-e2e:e2e --no-watch`)).toContain(
|
|
||||||
'All specs passed!'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
runCLI(`run ${mylib}:build-storybook`);
|
checkFilesExist(`dist/storybook/${mylib}/index.html`);
|
||||||
|
expect(readFile(`dist/storybook/${mylib}/index.html`)).toContain(
|
||||||
|
`<title>Storybook</title>`
|
||||||
|
);
|
||||||
|
}, 1000000);
|
||||||
|
});
|
||||||
|
|
||||||
checkFilesExist(`dist/storybook/${mylib}/index.html`);
|
describe('build storybook', () => {
|
||||||
expect(readFile(`dist/storybook/${mylib}/index.html`)).toContain(
|
it('should build an Angular based storybook', () => {
|
||||||
`<title>Storybook</title>`
|
newProject();
|
||||||
);
|
|
||||||
}, 1000000);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('build storybook', () => {
|
const angularStorybookLib = uniq('test-ui-lib');
|
||||||
it('should build an Angular based storybook', () => {
|
createTestUILib(angularStorybookLib);
|
||||||
ensureProject();
|
runCLI(
|
||||||
|
`generate @nrwl/angular:storybook-configuration ${angularStorybookLib} --generateStories --no-interactive`
|
||||||
|
);
|
||||||
|
|
||||||
const angularStorybookLib = uniq('test-ui-lib');
|
// build Angular lib
|
||||||
createTestUILib(angularStorybookLib);
|
runCLI(`run ${angularStorybookLib}:build-storybook`);
|
||||||
runCLI(
|
checkFilesExist(`dist/storybook/${angularStorybookLib}/index.html`);
|
||||||
`generate @nrwl/angular:storybook-configuration ${angularStorybookLib} --generateStories --no-interactive`
|
expect(
|
||||||
);
|
readFile(`dist/storybook/${angularStorybookLib}/index.html`)
|
||||||
|
).toContain(`<title>Storybook</title>`);
|
||||||
|
}, 1000000);
|
||||||
|
|
||||||
// build Angular lib
|
it('should build a React based storybook', () => {
|
||||||
runCLI(`run ${angularStorybookLib}:build-storybook`);
|
newProject();
|
||||||
checkFilesExist(`dist/storybook/${angularStorybookLib}/index.html`);
|
|
||||||
expect(
|
|
||||||
readFile(`dist/storybook/${angularStorybookLib}/index.html`)
|
|
||||||
).toContain(`<title>Storybook</title>`);
|
|
||||||
}, 1000000);
|
|
||||||
|
|
||||||
it('should build a React based storybook', () => {
|
const reactStorybookLib = uniq('test-ui-lib-react');
|
||||||
ensureProject();
|
runCLI(`generate @nrwl/react:lib ${reactStorybookLib} --no-interactive`);
|
||||||
|
runCLI(
|
||||||
|
`generate @nrwl/react:storybook-configuration ${reactStorybookLib} --generateStories --no-interactive`
|
||||||
|
);
|
||||||
|
|
||||||
const reactStorybookLib = uniq('test-ui-lib-react');
|
// build React lib
|
||||||
runCLI(
|
runCLI(`run ${reactStorybookLib}:build-storybook`);
|
||||||
`generate @nrwl/react:lib ${reactStorybookLib} --no-interactive`
|
checkFilesExist(`dist/storybook/${reactStorybookLib}/index.html`);
|
||||||
);
|
expect(
|
||||||
runCLI(
|
readFile(`dist/storybook/${reactStorybookLib}/index.html`)
|
||||||
`generate @nrwl/react:storybook-configuration ${reactStorybookLib} --generateStories --no-interactive`
|
).toContain(`<title>Storybook</title>`);
|
||||||
);
|
}, 1000000);
|
||||||
|
|
||||||
// build React lib
|
it('should build a React based storybook that references another lib', () => {
|
||||||
runCLI(`run ${reactStorybookLib}:build-storybook`);
|
newProject();
|
||||||
checkFilesExist(`dist/storybook/${reactStorybookLib}/index.html`);
|
|
||||||
expect(
|
|
||||||
readFile(`dist/storybook/${reactStorybookLib}/index.html`)
|
|
||||||
).toContain(`<title>Storybook</title>`);
|
|
||||||
}, 1000000);
|
|
||||||
|
|
||||||
it('should build a React based storybook that references another lib', () => {
|
const reactStorybookLib = uniq('test-ui-lib-react');
|
||||||
ensureProject();
|
runCLI(`generate @nrwl/react:lib ${reactStorybookLib} --no-interactive`);
|
||||||
|
runCLI(
|
||||||
|
`generate @nrwl/react:storybook-configuration ${reactStorybookLib} --generateStories --no-interactive`
|
||||||
|
);
|
||||||
|
|
||||||
const reactStorybookLib = uniq('test-ui-lib-react');
|
const anotherReactLib = uniq('test-another-lib-react');
|
||||||
runCLI(
|
runCLI(`generate @nrwl/react:lib ${anotherReactLib} --no-interactive`);
|
||||||
`generate @nrwl/react:lib ${reactStorybookLib} --no-interactive`
|
// create a React component we can reference
|
||||||
);
|
writeFileSync(
|
||||||
runCLI(
|
tmpProjPath(`libs/${anotherReactLib}/src/lib/mytestcmp.tsx`),
|
||||||
`generate @nrwl/react:storybook-configuration ${reactStorybookLib} --generateStories --no-interactive`
|
`
|
||||||
);
|
|
||||||
|
|
||||||
const anotherReactLib = uniq('test-another-lib-react');
|
|
||||||
runCLI(`generate @nrwl/react:lib ${anotherReactLib} --no-interactive`);
|
|
||||||
// create a React component we can reference
|
|
||||||
writeFileSync(
|
|
||||||
tmpProjPath(`libs/${anotherReactLib}/src/lib/mytestcmp.tsx`),
|
|
||||||
`
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
/* eslint-disable-next-line */
|
/* eslint-disable-next-line */
|
||||||
@ -216,21 +210,21 @@ forEachCli(() => {
|
|||||||
|
|
||||||
export default MyTestCmp;
|
export default MyTestCmp;
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
// update index.ts and export it
|
// update index.ts and export it
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
tmpProjPath(`libs/${anotherReactLib}/src/index.ts`),
|
tmpProjPath(`libs/${anotherReactLib}/src/index.ts`),
|
||||||
`
|
`
|
||||||
export * from './lib/mytestcmp';
|
export * from './lib/mytestcmp';
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
// create a story in the first lib to reference the cmp from the 2nd lib
|
// create a story in the first lib to reference the cmp from the 2nd lib
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
tmpProjPath(
|
tmpProjPath(
|
||||||
`libs/${reactStorybookLib}/src/lib/myteststory.stories.tsx`
|
`libs/${reactStorybookLib}/src/lib/myteststory.stories.tsx`
|
||||||
),
|
),
|
||||||
`
|
`
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { MyTestCmp, MyTestCmpProps } from '@proj/${anotherReactLib}';
|
import { MyTestCmp, MyTestCmpProps } from '@proj/${anotherReactLib}';
|
||||||
@ -247,46 +241,46 @@ forEachCli(() => {
|
|||||||
return <MyTestCmp />;
|
return <MyTestCmp />;
|
||||||
};
|
};
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
// build React lib
|
// build React lib
|
||||||
runCLI(`run ${reactStorybookLib}:build-storybook`);
|
runCLI(`run ${reactStorybookLib}:build-storybook`);
|
||||||
checkFilesExist(`dist/storybook/${reactStorybookLib}/index.html`);
|
checkFilesExist(`dist/storybook/${reactStorybookLib}/index.html`);
|
||||||
expect(
|
expect(
|
||||||
readFile(`dist/storybook/${reactStorybookLib}/index.html`)
|
readFile(`dist/storybook/${reactStorybookLib}/index.html`)
|
||||||
).toContain(`<title>Storybook</title>`);
|
).toContain(`<title>Storybook</title>`);
|
||||||
}, 1000000);
|
}, 1000000);
|
||||||
|
|
||||||
it('should build an Angular based storybook that references another lib', () => {
|
it('should build an Angular based storybook that references another lib', () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
|
|
||||||
const angularStorybookLib = uniq('test-ui-lib');
|
const angularStorybookLib = uniq('test-ui-lib');
|
||||||
createTestUILib(angularStorybookLib);
|
createTestUILib(angularStorybookLib);
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nrwl/angular:storybook-configuration ${angularStorybookLib} --generateStories --no-interactive`
|
`generate @nrwl/angular:storybook-configuration ${angularStorybookLib} --generateStories --no-interactive`
|
||||||
);
|
);
|
||||||
|
|
||||||
// create another lib with a component
|
// create another lib with a component
|
||||||
const anotherTestLib = uniq('test-another-lib');
|
const anotherTestLib = uniq('test-another-lib');
|
||||||
runCLI(`g @nrwl/angular:library ${anotherTestLib} --no-interactive`);
|
runCLI(`g @nrwl/angular:library ${anotherTestLib} --no-interactive`);
|
||||||
runCLI(
|
runCLI(
|
||||||
`g @nrwl/angular:component my-test-cmp --project=${anotherTestLib} --no-interactive`
|
`g @nrwl/angular:component my-test-cmp --project=${anotherTestLib} --no-interactive`
|
||||||
);
|
);
|
||||||
|
|
||||||
// update index.ts and export it
|
// update index.ts and export it
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
tmpProjPath(`libs/${anotherTestLib}/src/index.ts`),
|
tmpProjPath(`libs/${anotherTestLib}/src/index.ts`),
|
||||||
`
|
`
|
||||||
export * from './lib/my-test-cmp/my-test-cmp.component';
|
export * from './lib/my-test-cmp/my-test-cmp.component';
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
// create a story in the first lib to reference the cmp from the 2nd lib
|
// create a story in the first lib to reference the cmp from the 2nd lib
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
tmpProjPath(
|
tmpProjPath(
|
||||||
`libs/${angularStorybookLib}/src/lib/myteststory.stories.ts`
|
`libs/${angularStorybookLib}/src/lib/myteststory.stories.ts`
|
||||||
),
|
),
|
||||||
`
|
`
|
||||||
import { MyTestCmpComponent } from '@proj/${anotherTestLib}';
|
import { MyTestCmpComponent } from '@proj/${anotherTestLib}';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -303,16 +297,15 @@ forEachCli(() => {
|
|||||||
props: {},
|
props: {},
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
// build Angular lib
|
// build Angular lib
|
||||||
runCLI(`run ${angularStorybookLib}:build-storybook`);
|
runCLI(`run ${angularStorybookLib}:build-storybook`);
|
||||||
checkFilesExist(`dist/storybook/${angularStorybookLib}/index.html`);
|
checkFilesExist(`dist/storybook/${angularStorybookLib}/index.html`);
|
||||||
expect(
|
expect(
|
||||||
readFile(`dist/storybook/${angularStorybookLib}/index.html`)
|
readFile(`dist/storybook/${angularStorybookLib}/index.html`)
|
||||||
).toContain(`<title>Storybook</title>`);
|
).toContain(`<title>Storybook</title>`);
|
||||||
}, 1000000);
|
}, 1000000);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,12 @@ interface RunCmdOpts {
|
|||||||
cwd?: string;
|
cwd?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export let cli;
|
let cli;
|
||||||
|
|
||||||
|
export function currentCli() {
|
||||||
|
return cli ? cli : 'nx';
|
||||||
|
}
|
||||||
|
|
||||||
let projName: string;
|
let projName: string;
|
||||||
|
|
||||||
export function setCurrentProjName(name: string) {
|
export function setCurrentProjName(name: string) {
|
||||||
@ -74,7 +79,7 @@ export function patchKarmaToWorkOnWSL(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function workspaceConfigName() {
|
export function workspaceConfigName() {
|
||||||
return cli === 'angular' ? 'angular.json' : 'workspace.json';
|
return currentCli() === 'angular' ? 'angular.json' : 'workspace.json';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function runCreateWorkspace(
|
export function runCreateWorkspace(
|
||||||
@ -95,7 +100,9 @@ export function runCreateWorkspace(
|
|||||||
) {
|
) {
|
||||||
const linterArg =
|
const linterArg =
|
||||||
preset === 'angular' || preset === 'angular-nest' ? ' --linter=tslint' : '';
|
preset === 'angular' || preset === 'angular-nest' ? ' --linter=tslint' : '';
|
||||||
let command = `npx create-nx-workspace@${process.env.PUBLISHED_VERSION} ${name} --cli=${cli} --preset=${preset} ${linterArg} --no-nxCloud --no-interactive`;
|
let command = `npx create-nx-workspace@${
|
||||||
|
process.env.PUBLISHED_VERSION
|
||||||
|
} ${name} --cli=${currentCli()} --preset=${preset} ${linterArg} --no-nxCloud --no-interactive`;
|
||||||
if (appName) {
|
if (appName) {
|
||||||
command += ` --appName=${appName}`;
|
command += ` --appName=${appName}`;
|
||||||
}
|
}
|
||||||
@ -112,7 +119,7 @@ export function runCreateWorkspace(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const create = execSync(command, {
|
const create = execSync(command, {
|
||||||
cwd: `./tmp/${cli}`,
|
cwd: `./tmp/${currentCli()}`,
|
||||||
stdio: [0, 1, 2],
|
stdio: [0, 1, 2],
|
||||||
env: process.env,
|
env: process.env,
|
||||||
});
|
});
|
||||||
@ -120,7 +127,7 @@ export function runCreateWorkspace(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function yarnAdd(pkg: string, projName?: string) {
|
export function yarnAdd(pkg: string, projName?: string) {
|
||||||
const cwd = projName ? `./tmp/${cli}/${projName}` : tmpProjPath();
|
const cwd = projName ? `./tmp/${currentCli()}/${projName}` : tmpProjPath();
|
||||||
const install = execSync(`yarn add ${pkg}`, {
|
const install = execSync(`yarn add ${pkg}`, {
|
||||||
cwd,
|
cwd,
|
||||||
// ...{ stdio: ['pipe', 'pipe', 'pipe'] },
|
// ...{ stdio: ['pipe', 'pipe', 'pipe'] },
|
||||||
@ -132,7 +139,7 @@ export function yarnAdd(pkg: string, projName?: string) {
|
|||||||
|
|
||||||
export function runNgNew(): string {
|
export function runNgNew(): string {
|
||||||
return execSync(`../../node_modules/.bin/ng new proj --no-interactive`, {
|
return execSync(`../../node_modules/.bin/ng new proj --no-interactive`, {
|
||||||
cwd: `./tmp/${cli}`,
|
cwd: `./tmp/${currentCli()}`,
|
||||||
env: process.env,
|
env: process.env,
|
||||||
}).toString();
|
}).toString();
|
||||||
}
|
}
|
||||||
@ -162,9 +169,9 @@ export function newProject(): void {
|
|||||||
(f) => f !== '@nrwl/nx-plugin' && f !== `@nrwl/eslint-plugin-nx`
|
(f) => f !== '@nrwl/nx-plugin' && f !== `@nrwl/eslint-plugin-nx`
|
||||||
)
|
)
|
||||||
.forEach((p) => {
|
.forEach((p) => {
|
||||||
runCLI(`g ${p}:init`, { cwd: `./tmp/${cli}/proj` });
|
runCLI(`g ${p}:init`, { cwd: `./tmp/${currentCli()}/proj` });
|
||||||
});
|
});
|
||||||
execSync(`mv ./tmp/${cli}/proj ${tmpBackupProjPath()}`);
|
execSync(`mv ./tmp/${currentCli()}/proj ${tmpBackupProjPath()}`);
|
||||||
}
|
}
|
||||||
execSync(`cp -a ${tmpBackupProjPath()} ${tmpProjPath()}`);
|
execSync(`cp -a ${tmpBackupProjPath()} ${tmpProjPath()}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -174,19 +181,6 @@ export function newProject(): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures that a project has been setup
|
|
||||||
* in the temporary project path for the
|
|
||||||
* currently selected CLI.
|
|
||||||
*
|
|
||||||
* If one is not found, it creates a new project.
|
|
||||||
*/
|
|
||||||
export function ensureProject(): void {
|
|
||||||
// if (!directoryExists(tmpProjPath())) {
|
|
||||||
newProject();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
export function supportUi() {
|
export function supportUi() {
|
||||||
return false;
|
return false;
|
||||||
// return !process.env.NO_CHROME;
|
// return !process.env.NO_CHROME;
|
||||||
@ -203,7 +197,7 @@ export function runCommandAsync(
|
|||||||
exec(
|
exec(
|
||||||
command,
|
command,
|
||||||
{
|
{
|
||||||
cwd: opts.cwd || tmpProjPath(),
|
cwd: tmpProjPath(),
|
||||||
env: { ...process.env, FORCE_COLOR: 'false' },
|
env: { ...process.env, FORCE_COLOR: 'false' },
|
||||||
},
|
},
|
||||||
(err, stdout, stderr) => {
|
(err, stdout, stderr) => {
|
||||||
@ -216,6 +210,43 @@ export function runCommandAsync(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function runCommandUntil(
|
||||||
|
command: string,
|
||||||
|
criteria: (output: string) => boolean
|
||||||
|
) {
|
||||||
|
const p = exec(`./node_modules/.bin/nx ${command}`, {
|
||||||
|
cwd: tmpProjPath(),
|
||||||
|
env: { ...process.env, FORCE_COLOR: 'false' },
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Promise((res, rej) => {
|
||||||
|
let output = '';
|
||||||
|
let complete = false;
|
||||||
|
p.stdout.on('data', (c) => {
|
||||||
|
output += c.toString();
|
||||||
|
if (criteria(output)) {
|
||||||
|
complete = true;
|
||||||
|
res(true);
|
||||||
|
p.kill();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
p.stderr.on('data', (c) => {
|
||||||
|
output += c.toString();
|
||||||
|
if (criteria(output)) {
|
||||||
|
complete = true;
|
||||||
|
res(true);
|
||||||
|
p.kill();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
p.on('exit', (code) => {
|
||||||
|
if (code !== 0 && !complete) {
|
||||||
|
console.log(output);
|
||||||
|
}
|
||||||
|
rej(`Exited with ${code}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function runCLIAsync(
|
export function runCLIAsync(
|
||||||
command: string,
|
command: string,
|
||||||
opts: RunCmdOpts = {
|
opts: RunCmdOpts = {
|
||||||
@ -436,9 +467,13 @@ export function getSize(filePath: string): number {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function tmpProjPath(path?: string) {
|
export function tmpProjPath(path?: string) {
|
||||||
return path ? `./tmp/${cli}/${projName}/${path}` : `./tmp/${cli}/${projName}`;
|
return path
|
||||||
|
? `./tmp/${currentCli()}/${projName}/${path}`
|
||||||
|
: `./tmp/${currentCli()}/${projName}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function tmpBackupProjPath(path?: string) {
|
function tmpBackupProjPath(path?: string) {
|
||||||
return path ? `./tmp/${cli}/proj-backup/${path}` : `./tmp/${cli}/proj-backup`;
|
return path
|
||||||
|
? `./tmp/${currentCli()}/proj-backup/${path}`
|
||||||
|
: `./tmp/${currentCli()}/proj-backup`;
|
||||||
}
|
}
|
||||||
|
|||||||
32
e2e/web/src/file-server.test.ts
Normal file
32
e2e/web/src/file-server.test.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import {
|
||||||
|
newProject,
|
||||||
|
readJson,
|
||||||
|
runCLI,
|
||||||
|
runCommandUntil,
|
||||||
|
uniq,
|
||||||
|
updateFile,
|
||||||
|
workspaceConfigName,
|
||||||
|
} from '@nrwl/e2e/utils';
|
||||||
|
import { serializeJson } from '@nrwl/workspace';
|
||||||
|
|
||||||
|
describe('file-server', () => {
|
||||||
|
it('should serve folder of files', async (done) => {
|
||||||
|
newProject();
|
||||||
|
const appName = uniq('app');
|
||||||
|
|
||||||
|
runCLI(`generate @nrwl/web:app ${appName} --no-interactive`);
|
||||||
|
const workspaceJson = readJson(workspaceConfigName());
|
||||||
|
workspaceJson.projects[appName].architect['serve'].builder =
|
||||||
|
'@nrwl/web:file-server';
|
||||||
|
updateFile(workspaceConfigName(), serializeJson(workspaceJson));
|
||||||
|
|
||||||
|
await runCommandUntil(`serve ${appName}`, (output) => {
|
||||||
|
return (
|
||||||
|
output.indexOf('Built at') > -1 && output.indexOf('Available on') > -1
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// success, nothing to do
|
||||||
|
done();
|
||||||
|
}, 30000);
|
||||||
|
});
|
||||||
@ -1,174 +1,165 @@
|
|||||||
import {
|
import {
|
||||||
checkFilesExist,
|
|
||||||
checkFilesDoNotExist,
|
checkFilesDoNotExist,
|
||||||
ensureProject,
|
checkFilesExist,
|
||||||
forEachCli,
|
createFile,
|
||||||
|
newProject,
|
||||||
readFile,
|
readFile,
|
||||||
runCLI,
|
runCLI,
|
||||||
runCLIAsync,
|
runCLIAsync,
|
||||||
uniq,
|
uniq,
|
||||||
updateFile,
|
updateFile,
|
||||||
createFile,
|
|
||||||
} from '@nrwl/e2e/utils';
|
} from '@nrwl/e2e/utils';
|
||||||
|
|
||||||
forEachCli((currentCLIName) => {
|
describe('Web Components Applications', () => {
|
||||||
describe('Web Components Applications', () => {
|
it('should be able to generate a web app', async () => {
|
||||||
it('should be able to generate a web app', async () => {
|
newProject();
|
||||||
ensureProject();
|
const appName = uniq('app');
|
||||||
const appName = uniq('app');
|
runCLI(`generate @nrwl/web:app ${appName} --no-interactive`);
|
||||||
|
|
||||||
const linter = currentCLIName === 'angular' ? 'tslint' : 'eslint';
|
const lintResults = runCLI(`lint ${appName}`);
|
||||||
runCLI(
|
expect(lintResults).toContain('All files pass linting.');
|
||||||
`generate @nrwl/web:app ${appName} --no-interactive --linter=${linter}`
|
|
||||||
);
|
|
||||||
|
|
||||||
const lintResults = runCLI(`lint ${appName}`);
|
runCLI(`build ${appName}`);
|
||||||
expect(lintResults).toContain('All files pass linting.');
|
checkFilesExist(
|
||||||
|
`dist/apps/${appName}/index.html`,
|
||||||
|
`dist/apps/${appName}/runtime.js`,
|
||||||
|
`dist/apps/${appName}/polyfills.js`,
|
||||||
|
`dist/apps/${appName}/main.js`,
|
||||||
|
`dist/apps/${appName}/styles.js`
|
||||||
|
);
|
||||||
|
expect(readFile(`dist/apps/${appName}/main.js`)).toContain(
|
||||||
|
'class AppElement'
|
||||||
|
);
|
||||||
|
runCLI(`build ${appName} --prod --output-hashing none`);
|
||||||
|
checkFilesExist(
|
||||||
|
`dist/apps/${appName}/index.html`,
|
||||||
|
`dist/apps/${appName}/runtime.js`,
|
||||||
|
`dist/apps/${appName}/polyfills.esm.js`,
|
||||||
|
`dist/apps/${appName}/main.esm.js`,
|
||||||
|
`dist/apps/${appName}/styles.css`
|
||||||
|
);
|
||||||
|
expect(readFile(`dist/apps/${appName}/index.html`)).toContain(
|
||||||
|
`<link rel="stylesheet" href="styles.css">`
|
||||||
|
);
|
||||||
|
const testResults = await runCLIAsync(`test ${appName}`);
|
||||||
|
expect(testResults.combinedOutput).toContain(
|
||||||
|
'Test Suites: 1 passed, 1 total'
|
||||||
|
);
|
||||||
|
const lintE2eResults = runCLI(`lint ${appName}-e2e`);
|
||||||
|
expect(lintE2eResults).toContain('All files pass linting.');
|
||||||
|
|
||||||
runCLI(`build ${appName}`);
|
const e2eResults = runCLI(`e2e ${appName}-e2e`);
|
||||||
checkFilesExist(
|
expect(e2eResults).toContain('All specs passed!');
|
||||||
`dist/apps/${appName}/index.html`,
|
}, 120000);
|
||||||
`dist/apps/${appName}/runtime.js`,
|
|
||||||
`dist/apps/${appName}/polyfills.js`,
|
|
||||||
`dist/apps/${appName}/main.js`,
|
|
||||||
`dist/apps/${appName}/styles.js`
|
|
||||||
);
|
|
||||||
expect(readFile(`dist/apps/${appName}/main.js`)).toContain(
|
|
||||||
'class AppElement'
|
|
||||||
);
|
|
||||||
runCLI(`build ${appName} --prod --output-hashing none`);
|
|
||||||
checkFilesExist(
|
|
||||||
`dist/apps/${appName}/index.html`,
|
|
||||||
`dist/apps/${appName}/runtime.js`,
|
|
||||||
`dist/apps/${appName}/polyfills.esm.js`,
|
|
||||||
`dist/apps/${appName}/main.esm.js`,
|
|
||||||
`dist/apps/${appName}/styles.css`
|
|
||||||
);
|
|
||||||
expect(readFile(`dist/apps/${appName}/index.html`)).toContain(
|
|
||||||
`<link rel="stylesheet" href="styles.css">`
|
|
||||||
);
|
|
||||||
const testResults = await runCLIAsync(`test ${appName}`);
|
|
||||||
expect(testResults.combinedOutput).toContain(
|
|
||||||
'Test Suites: 1 passed, 1 total'
|
|
||||||
);
|
|
||||||
const lintE2eResults = runCLI(`lint ${appName}-e2e`);
|
|
||||||
expect(lintE2eResults).toContain('All files pass linting.');
|
|
||||||
|
|
||||||
const e2eResults = runCLI(`e2e ${appName}-e2e`);
|
it('should remove previous output before building', async () => {
|
||||||
expect(e2eResults).toContain('All specs passed!');
|
newProject();
|
||||||
}, 120000);
|
const appName = uniq('app');
|
||||||
|
const libName = uniq('lib');
|
||||||
|
|
||||||
it('should remove previous output before building', async () => {
|
runCLI(`generate @nrwl/web:app ${appName} --no-interactive`);
|
||||||
ensureProject();
|
runCLI(`generate @nrwl/react:lib ${libName} --buildable --no-interactive`);
|
||||||
const appName = uniq('app');
|
|
||||||
const libName = uniq('lib');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/web:app ${appName} --no-interactive`);
|
createFile(`dist/apps/${appName}/_should_remove.txt`);
|
||||||
runCLI(
|
createFile(`dist/libs/${libName}/_should_remove.txt`);
|
||||||
`generate @nrwl/react:lib ${libName} --buildable --no-interactive`
|
createFile(`dist/apps/_should_not_remove.txt`);
|
||||||
);
|
checkFilesExist(
|
||||||
|
`dist/apps/${appName}/_should_remove.txt`,
|
||||||
|
`dist/apps/_should_not_remove.txt`
|
||||||
|
);
|
||||||
|
runCLI(`build ${appName}`);
|
||||||
|
runCLI(`build ${libName}`);
|
||||||
|
checkFilesDoNotExist(
|
||||||
|
`dist/apps/${appName}/_should_remove.txt`,
|
||||||
|
`dist/libs/${libName}/_should_remove.txt`
|
||||||
|
);
|
||||||
|
checkFilesExist(`dist/apps/_should_not_remove.txt`);
|
||||||
|
}, 120000);
|
||||||
|
|
||||||
createFile(`dist/apps/${appName}/_should_remove.txt`);
|
it('should do another build if differential loading is needed', async () => {
|
||||||
createFile(`dist/libs/${libName}/_should_remove.txt`);
|
newProject();
|
||||||
createFile(`dist/apps/_should_not_remove.txt`);
|
const appName = uniq('app');
|
||||||
checkFilesExist(
|
|
||||||
`dist/apps/${appName}/_should_remove.txt`,
|
|
||||||
`dist/apps/_should_not_remove.txt`
|
|
||||||
);
|
|
||||||
runCLI(`build ${appName}`);
|
|
||||||
runCLI(`build ${libName}`);
|
|
||||||
checkFilesDoNotExist(
|
|
||||||
`dist/apps/${appName}/_should_remove.txt`,
|
|
||||||
`dist/libs/${libName}/_should_remove.txt`
|
|
||||||
);
|
|
||||||
checkFilesExist(`dist/apps/_should_not_remove.txt`);
|
|
||||||
}, 120000);
|
|
||||||
|
|
||||||
it('should do another build if differential loading is needed', async () => {
|
runCLI(`generate @nrwl/web:app ${appName} --no-interactive`);
|
||||||
ensureProject();
|
|
||||||
const appName = uniq('app');
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/web:app ${appName} --no-interactive`);
|
updateFile(`apps/${appName}/browserslist`, `IE 9-11`);
|
||||||
|
|
||||||
updateFile(`apps/${appName}/browserslist`, `IE 9-11`);
|
const output = runCLI(`build ${appName} --prod --outputHashing=none`);
|
||||||
|
checkFilesExist(
|
||||||
|
`dist/apps/${appName}/main.esm.js`,
|
||||||
|
`dist/apps/${appName}/main.es5.js`
|
||||||
|
);
|
||||||
|
|
||||||
const output = runCLI(`build ${appName} --prod --outputHashing=none`);
|
// Do not run type checking for legacy build
|
||||||
checkFilesExist(
|
expect(
|
||||||
`dist/apps/${appName}/main.esm.js`,
|
output.match(/Starting type checking service.../g) || []
|
||||||
`dist/apps/${appName}/main.es5.js`
|
).toHaveLength(1);
|
||||||
);
|
}, 120000);
|
||||||
|
});
|
||||||
|
|
||||||
// Do not run type checking for legacy build
|
describe('CLI - Environment Variables', () => {
|
||||||
expect(
|
it('should automatically load workspace and per-project environment variables', () => {
|
||||||
output.match(/Starting type checking service.../g) || []
|
newProject();
|
||||||
).toHaveLength(1);
|
|
||||||
}, 120000);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('CLI - Environment Variables', () => {
|
const appName = uniq('app');
|
||||||
it('should automatically load workspace and per-project environment variables', () => {
|
//test if the Nx CLI loads root .env vars
|
||||||
ensureProject();
|
updateFile(
|
||||||
|
`.env`,
|
||||||
|
'NX_WS_BASE=ws-base\nNX_SHARED_ENV=shared-in-workspace-base'
|
||||||
|
);
|
||||||
|
updateFile(
|
||||||
|
`.local.env`,
|
||||||
|
'NX_WS_LOCAL=ws-local\nNX_SHARED_ENV=shared-in-workspace-local'
|
||||||
|
);
|
||||||
|
updateFile(
|
||||||
|
`apps/${appName}/.env`,
|
||||||
|
'NX_APP_BASE=app-base\nNX_SHARED_ENV=shared-in-app-base'
|
||||||
|
);
|
||||||
|
updateFile(
|
||||||
|
`apps/${appName}/.local.env`,
|
||||||
|
'NX_APP_LOCAL=app-local\nNX_SHARED_ENV=shared-in-app-local'
|
||||||
|
);
|
||||||
|
const main = `apps/${appName}/src/main.ts`;
|
||||||
|
const newCode = `const envVars = [process.env.NODE_ENV, process.env.NX_BUILD, process.env.NX_API, process.env.NX_WS_BASE, process.env.NX_WS_LOCAL, process.env.NX_APP_BASE, process.env.NX_APP_LOCAL, process.env.NX_SHARED_ENV];`;
|
||||||
|
|
||||||
const appName = uniq('app');
|
runCLI(`generate @nrwl/web:app ${appName} --no-interactive`);
|
||||||
//test if the Nx CLI loads root .env vars
|
|
||||||
updateFile(
|
|
||||||
`.env`,
|
|
||||||
'NX_WS_BASE=ws-base\nNX_SHARED_ENV=shared-in-workspace-base'
|
|
||||||
);
|
|
||||||
updateFile(
|
|
||||||
`.local.env`,
|
|
||||||
'NX_WS_LOCAL=ws-local\nNX_SHARED_ENV=shared-in-workspace-local'
|
|
||||||
);
|
|
||||||
updateFile(
|
|
||||||
`apps/${appName}/.env`,
|
|
||||||
'NX_APP_BASE=app-base\nNX_SHARED_ENV=shared-in-app-base'
|
|
||||||
);
|
|
||||||
updateFile(
|
|
||||||
`apps/${appName}/.local.env`,
|
|
||||||
'NX_APP_LOCAL=app-local\nNX_SHARED_ENV=shared-in-app-local'
|
|
||||||
);
|
|
||||||
const main = `apps/${appName}/src/main.ts`;
|
|
||||||
const newCode = `const envVars = [process.env.NODE_ENV, process.env.NX_BUILD, process.env.NX_API, process.env.NX_WS_BASE, process.env.NX_WS_LOCAL, process.env.NX_APP_BASE, process.env.NX_APP_LOCAL, process.env.NX_SHARED_ENV];`;
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/web:app ${appName} --no-interactive`);
|
const content = readFile(main);
|
||||||
|
|
||||||
const content = readFile(main);
|
updateFile(main, `${newCode}\n${content}`);
|
||||||
|
|
||||||
updateFile(main, `${newCode}\n${content}`);
|
const appName2 = uniq('app');
|
||||||
|
|
||||||
const appName2 = uniq('app');
|
updateFile(
|
||||||
|
`apps/${appName2}/.env`,
|
||||||
|
'NX_APP_BASE=app2-base\nNX_SHARED_ENV=shared2-in-app-base'
|
||||||
|
);
|
||||||
|
updateFile(
|
||||||
|
`apps/${appName2}/.local.env`,
|
||||||
|
'NX_APP_LOCAL=app2-local\nNX_SHARED_ENV=shared2-in-app-local'
|
||||||
|
);
|
||||||
|
const main2 = `apps/${appName2}/src/main.ts`;
|
||||||
|
const newCode2 = `const envVars = [process.env.NODE_ENV, process.env.NX_BUILD, process.env.NX_API, process.env.NX_WS_BASE, process.env.NX_WS_LOCAL, process.env.NX_APP_BASE, process.env.NX_APP_LOCAL, process.env.NX_SHARED_ENV];`;
|
||||||
|
|
||||||
updateFile(
|
runCLI(`generate @nrwl/web:app ${appName2} --no-interactive`);
|
||||||
`apps/${appName2}/.env`,
|
|
||||||
'NX_APP_BASE=app2-base\nNX_SHARED_ENV=shared2-in-app-base'
|
|
||||||
);
|
|
||||||
updateFile(
|
|
||||||
`apps/${appName2}/.local.env`,
|
|
||||||
'NX_APP_LOCAL=app2-local\nNX_SHARED_ENV=shared2-in-app-local'
|
|
||||||
);
|
|
||||||
const main2 = `apps/${appName2}/src/main.ts`;
|
|
||||||
const newCode2 = `const envVars = [process.env.NODE_ENV, process.env.NX_BUILD, process.env.NX_API, process.env.NX_WS_BASE, process.env.NX_WS_LOCAL, process.env.NX_APP_BASE, process.env.NX_APP_LOCAL, process.env.NX_SHARED_ENV];`;
|
|
||||||
|
|
||||||
runCLI(`generate @nrwl/web:app ${appName2} --no-interactive`);
|
const content2 = readFile(main2);
|
||||||
|
|
||||||
const content2 = readFile(main2);
|
updateFile(main2, `${newCode2}\n${content2}`);
|
||||||
|
|
||||||
updateFile(main2, `${newCode2}\n${content2}`);
|
runCLI(`run-many --target=build --all`, {
|
||||||
|
env: {
|
||||||
runCLI(`run-many --target=build --all`, {
|
...process.env,
|
||||||
env: {
|
NODE_ENV: 'test',
|
||||||
...process.env,
|
NX_BUILD: '52',
|
||||||
NODE_ENV: 'test',
|
NX_API: 'QA',
|
||||||
NX_BUILD: '52',
|
},
|
||||||
NX_API: 'QA',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(readFile(`dist/apps/${appName}/main.js`)).toContain(
|
|
||||||
'const envVars = ["test", "52", "QA", "ws-base", "ws-local", "app-base", "app-local", "shared-in-app-local"];'
|
|
||||||
);
|
|
||||||
expect(readFile(`dist/apps/${appName2}/main.js`)).toContain(
|
|
||||||
'const envVars = ["test", "52", "QA", "ws-base", "ws-local", "app2-base", "app2-local", "shared2-in-app-local"];'
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
expect(readFile(`dist/apps/${appName}/main.js`)).toContain(
|
||||||
|
'const envVars = ["test", "52", "QA", "ws-base", "ws-local", "app-base", "app-local", "shared-in-app-local"];'
|
||||||
|
);
|
||||||
|
expect(readFile(`dist/apps/${appName2}/main.js`)).toContain(
|
||||||
|
'const envVars = ["test", "52", "QA", "ws-base", "ws-local", "app2-base", "app2-local", "shared2-in-app-local"];'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,4 +1,9 @@
|
|||||||
import { cli, forEachCli, runCreateWorkspace, uniq } from '@nrwl/e2e/utils';
|
import {
|
||||||
|
currentCli,
|
||||||
|
forEachCli,
|
||||||
|
runCreateWorkspace,
|
||||||
|
uniq,
|
||||||
|
} from '@nrwl/e2e/utils';
|
||||||
import { existsSync, mkdirSync } from 'fs-extra';
|
import { existsSync, mkdirSync } from 'fs-extra';
|
||||||
import { execSync } from 'child_process';
|
import { execSync } from 'child_process';
|
||||||
|
|
||||||
@ -98,11 +103,13 @@ forEachCli(() => {
|
|||||||
it('should handle spaces in workspace path', () => {
|
it('should handle spaces in workspace path', () => {
|
||||||
const wsName = uniq('empty');
|
const wsName = uniq('empty');
|
||||||
|
|
||||||
const tmpDir = `./tmp/${cli}/with space`;
|
const tmpDir = `./tmp/${currentCli()}/with space`;
|
||||||
|
|
||||||
mkdirSync(tmpDir);
|
mkdirSync(tmpDir);
|
||||||
|
|
||||||
const command = `npx create-nx-workspace@${process.env.PUBLISHED_VERSION} ${wsName} --cli=${cli} --preset=empty --no-nxCloud --no-interactive`;
|
const command = `npx create-nx-workspace@${
|
||||||
|
process.env.PUBLISHED_VERSION
|
||||||
|
} ${wsName} --cli=${currentCli()} --preset=empty --no-nxCloud --no-interactive`;
|
||||||
execSync(command, {
|
execSync(command, {
|
||||||
cwd: tmpDir,
|
cwd: tmpDir,
|
||||||
stdio: [0, 1, 2],
|
stdio: [0, 1, 2],
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
ensureProject,
|
|
||||||
forEachCli,
|
forEachCli,
|
||||||
|
newProject,
|
||||||
readJson,
|
readJson,
|
||||||
runCLI,
|
runCLI,
|
||||||
uniq,
|
uniq,
|
||||||
@ -11,7 +11,7 @@ import {
|
|||||||
forEachCli(() => {
|
forEachCli(() => {
|
||||||
describe('Run Commands', () => {
|
describe('Run Commands', () => {
|
||||||
it('should not override environment variables already set when setting a custom env file path', async (done) => {
|
it('should not override environment variables already set when setting a custom env file path', async (done) => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const nodeapp = uniq('nodeapp');
|
const nodeapp = uniq('nodeapp');
|
||||||
updateFile(
|
updateFile(
|
||||||
`.env`,
|
`.env`,
|
||||||
@ -38,7 +38,7 @@ forEachCli(() => {
|
|||||||
}, 120000);
|
}, 120000);
|
||||||
|
|
||||||
it('should interpolate provided arguments', async (done) => {
|
it('should interpolate provided arguments', async (done) => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const myapp = uniq('myapp1');
|
const myapp = uniq('myapp1');
|
||||||
|
|
||||||
runCLI(`generate @nrwl/web:app ${myapp}`);
|
runCLI(`generate @nrwl/web:app ${myapp}`);
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
checkFilesExist,
|
checkFilesExist,
|
||||||
ensureProject,
|
|
||||||
exists,
|
exists,
|
||||||
forEachCli,
|
forEachCli,
|
||||||
|
newProject,
|
||||||
readFile,
|
readFile,
|
||||||
readJson,
|
readJson,
|
||||||
runCLI,
|
runCLI,
|
||||||
@ -18,7 +18,7 @@ import { classify } from '@nrwl/workspace/src/utils/strings';
|
|||||||
|
|
||||||
forEachCli((cli) => {
|
forEachCli((cli) => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
ensureProject();
|
newProject();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('lint', () => {
|
describe('lint', () => {
|
||||||
@ -263,8 +263,8 @@ forEachCli((cli) => {
|
|||||||
`;
|
`;
|
||||||
});
|
});
|
||||||
|
|
||||||
const dryRunOutput = runCommand(
|
runCommand(
|
||||||
`npm run workspace-schematic ${custom} ${workspace} -- --no-interactive -d`
|
`nx workspace-schematic ${custom} ${workspace} --no-interactive -d`
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(() =>
|
expect(() =>
|
||||||
@ -279,7 +279,7 @@ forEachCli((cli) => {
|
|||||||
).toThrow();
|
).toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('vvvshould support workspace-specific schematics', async () => {
|
it('should support workspace-specific schematics', async () => {
|
||||||
const json = readJson(`tools/schematics/${custom}/schema.json`);
|
const json = readJson(`tools/schematics/${custom}/schema.json`);
|
||||||
json.properties['directory'] = {
|
json.properties['directory'] = {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@ -304,24 +304,20 @@ forEachCli((cli) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const workspace = uniq('workspace');
|
const workspace = uniq('workspace');
|
||||||
const dryRunOutput = runCommand(
|
const dryRunOutput = runCLI(
|
||||||
`npm run workspace-schematic ${custom} ${workspace} -- --no-interactive --directory=dir --skipTsConfig=true -d`
|
`workspace-schematic ${custom} ${workspace} --no-interactive --directory=dir --skipTsConfig=true -d`
|
||||||
);
|
);
|
||||||
expect(exists(`libs/dir/${workspace}/src/index.ts`)).toEqual(false);
|
expect(exists(`libs/dir/${workspace}/src/index.ts`)).toEqual(false);
|
||||||
expect(dryRunOutput).toContain(`UPDATE ${workspaceConfigName()}`);
|
expect(dryRunOutput).toContain(`UPDATE ${workspaceConfigName()}`);
|
||||||
expect(dryRunOutput).toContain('UPDATE nx.json');
|
expect(dryRunOutput).toContain('UPDATE nx.json');
|
||||||
expect(dryRunOutput).not.toContain('UPDATE tsconfig.base.json');
|
|
||||||
|
|
||||||
const output = runCommand(
|
const output = runCLI(
|
||||||
`npm run workspace-schematic ${custom} ${workspace} -- --no-interactive --directory=dir`
|
`workspace-schematic ${custom} ${workspace} --no-interactive --directory=dir`
|
||||||
);
|
);
|
||||||
checkFilesExist(`libs/dir/${workspace}/src/index.ts`);
|
checkFilesExist(`libs/dir/${workspace}/src/index.ts`);
|
||||||
expect(output).toContain(`UPDATE ${workspaceConfigName()}`);
|
expect(output).toContain(`UPDATE ${workspaceConfigName()}`);
|
||||||
expect(output).toContain('UPDATE nx.json');
|
expect(output).toContain('UPDATE nx.json');
|
||||||
|
|
||||||
const another = uniq('another');
|
|
||||||
runCLI(`g workspace-schematic ${another} --no-interactive`);
|
|
||||||
|
|
||||||
const jsonFailing = readJson(`tools/schematics/${failing}/schema.json`);
|
const jsonFailing = readJson(`tools/schematics/${failing}/schema.json`);
|
||||||
jsonFailing.properties = {};
|
jsonFailing.properties = {};
|
||||||
jsonFailing.required = [];
|
jsonFailing.required = [];
|
||||||
@ -340,26 +336,15 @@ forEachCli((cli) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await runCommandAsync(
|
await runCLI(`workspace-schematic ${failing} --no-interactive`);
|
||||||
`npm run workspace-schematic -- ${failing} --no-interactive`
|
|
||||||
);
|
|
||||||
fail(`Should exit 1 for a workspace-schematic that throws an error`);
|
fail(`Should exit 1 for a workspace-schematic that throws an error`);
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
const listSchematicsOutput = runCommand(
|
const listSchematicsOutput = runCLI(
|
||||||
'npm run workspace-schematic -- --list-schematics'
|
'workspace-schematic --list-schematics'
|
||||||
);
|
|
||||||
expect(listSchematicsOutput).toContain(
|
|
||||||
'nx workspace-schematic "--list-schematics"'
|
|
||||||
);
|
);
|
||||||
expect(listSchematicsOutput).toContain(custom);
|
expect(listSchematicsOutput).toContain(custom);
|
||||||
expect(listSchematicsOutput).toContain(failing);
|
expect(listSchematicsOutput).toContain(failing);
|
||||||
expect(listSchematicsOutput).toContain(another);
|
|
||||||
|
|
||||||
const promptOutput = runCommand(
|
|
||||||
`npm run workspace-schematic ${custom} mylib2 --dry-run`
|
|
||||||
);
|
|
||||||
expect(promptOutput).toContain('UPDATE nx.json');
|
|
||||||
}, 1000000);
|
}, 1000000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { NxJson } from '@nrwl/workspace';
|
import { NxJson } from '@nrwl/workspace';
|
||||||
import {
|
import {
|
||||||
ensureProject,
|
|
||||||
forEachCli,
|
forEachCli,
|
||||||
listFiles,
|
listFiles,
|
||||||
newProject,
|
newProject,
|
||||||
@ -33,7 +32,7 @@ forEachCli((cliName) => {
|
|||||||
|
|
||||||
describe('run-one', () => {
|
describe('run-one', () => {
|
||||||
it('should build specific project', () => {
|
it('should build specific project', () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const myapp = uniq('myapp');
|
const myapp = uniq('myapp');
|
||||||
const mylib1 = uniq('mylib1');
|
const mylib1 = uniq('mylib1');
|
||||||
const mylib2 = uniq('mylib1');
|
const mylib2 = uniq('mylib1');
|
||||||
@ -140,7 +139,7 @@ forEachCli((cliName) => {
|
|||||||
}, 1000000);
|
}, 1000000);
|
||||||
|
|
||||||
it('should run only failed projects', () => {
|
it('should run only failed projects', () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const myapp = uniq('myapp');
|
const myapp = uniq('myapp');
|
||||||
const myapp2 = uniq('myapp2');
|
const myapp2 = uniq('myapp2');
|
||||||
runCLI(`generate @nrwl/angular:app ${myapp}`);
|
runCLI(`generate @nrwl/angular:app ${myapp}`);
|
||||||
@ -196,7 +195,7 @@ forEachCli((cliName) => {
|
|||||||
|
|
||||||
describe('affected:*', () => {
|
describe('affected:*', () => {
|
||||||
it('should print, build, and test affected apps', () => {
|
it('should print, build, and test affected apps', () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const myapp = uniq('myapp');
|
const myapp = uniq('myapp');
|
||||||
const myapp2 = uniq('myapp2');
|
const myapp2 = uniq('myapp2');
|
||||||
const mylib = uniq('mylib');
|
const mylib = uniq('mylib');
|
||||||
@ -356,7 +355,7 @@ forEachCli((cliName) => {
|
|||||||
let myapp2 = uniq('myapp');
|
let myapp2 = uniq('myapp');
|
||||||
let mylib = uniq('mylib');
|
let mylib = uniq('mylib');
|
||||||
it('should not affect other projects by generating a new project', () => {
|
it('should not affect other projects by generating a new project', () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
|
|
||||||
const nxJson: NxJson = readJson('nx.json');
|
const nxJson: NxJson = readJson('nx.json');
|
||||||
|
|
||||||
@ -557,7 +556,7 @@ forEachCli((cliName) => {
|
|||||||
|
|
||||||
describe('cache', () => {
|
describe('cache', () => {
|
||||||
it('should cache command execution', async () => {
|
it('should cache command execution', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
|
|
||||||
const myapp1 = uniq('myapp1');
|
const myapp1 = uniq('myapp1');
|
||||||
const myapp2 = uniq('myapp2');
|
const myapp2 = uniq('myapp2');
|
||||||
@ -690,7 +689,7 @@ forEachCli((cliName) => {
|
|||||||
}, 120000);
|
}, 120000);
|
||||||
|
|
||||||
it('should only cache specific files if build outputs is configured with specific files', async () => {
|
it('should only cache specific files if build outputs is configured with specific files', async () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
|
|
||||||
const mylib1 = uniq('mylib1');
|
const mylib1 = uniq('mylib1');
|
||||||
runCLI(`generate @nrwl/react:lib ${mylib1} --buildable`);
|
runCLI(`generate @nrwl/react:lib ${mylib1} --buildable`);
|
||||||
@ -759,7 +758,7 @@ forEachCli((cliName) => {
|
|||||||
|
|
||||||
describe('workspace structure', () => {
|
describe('workspace structure', () => {
|
||||||
it('should have a vscode/extensions.json file created', () => {
|
it('should have a vscode/extensions.json file created', () => {
|
||||||
ensureProject();
|
newProject();
|
||||||
const extensions = readJson('.vscode/extensions.json');
|
const extensions = readJson('.vscode/extensions.json');
|
||||||
if (cliName === 'angular') {
|
if (cliName === 'angular') {
|
||||||
expect(extensions).toEqual({
|
expect(extensions).toEqual({
|
||||||
|
|||||||
8
nx.json
8
nx.json
@ -35,11 +35,12 @@
|
|||||||
"tags": []
|
"tags": []
|
||||||
},
|
},
|
||||||
"devkit": {
|
"devkit": {
|
||||||
"tags": []
|
"tags": ["tao"],
|
||||||
|
"implicitDependencies": ["tao"]
|
||||||
},
|
},
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"tags": [],
|
"tags": [],
|
||||||
"implicitDependencies": ["tao", "cli"]
|
"implicitDependencies": ["tao", "cli", "devkit"]
|
||||||
},
|
},
|
||||||
"web": {
|
"web": {
|
||||||
"tags": [],
|
"tags": [],
|
||||||
@ -98,7 +99,8 @@
|
|||||||
"implicitDependencies": ["nx-plugin"]
|
"implicitDependencies": ["nx-plugin"]
|
||||||
},
|
},
|
||||||
"cli": {
|
"cli": {
|
||||||
"tags": []
|
"tags": [],
|
||||||
|
"implicitDependencies": ["tao"]
|
||||||
},
|
},
|
||||||
"angular": {
|
"angular": {
|
||||||
"tags": [],
|
"tags": [],
|
||||||
|
|||||||
19
package.json
19
package.json
@ -63,14 +63,15 @@
|
|||||||
"@ngrx/store": "9.1.0",
|
"@ngrx/store": "9.1.0",
|
||||||
"@ngrx/store-devtools": "9.1.0",
|
"@ngrx/store-devtools": "9.1.0",
|
||||||
"@ngtools/webpack": "~10.1.3",
|
"@ngtools/webpack": "~10.1.3",
|
||||||
"@nrwl/cli": "10.3.1-beta.1",
|
"@nrwl/cli": "10.4.1",
|
||||||
"@nrwl/cypress": "10.4.0-beta.2",
|
"@nrwl/tao": "10.4.1",
|
||||||
"@nrwl/eslint-plugin-nx": "10.4.0-beta.2",
|
"@nrwl/cypress": "10.4.1",
|
||||||
"@nrwl/jest": "10.4.0-beta.2",
|
"@nrwl/eslint-plugin-nx": "10.4.1",
|
||||||
"@nrwl/node": "10.4.0-beta.2",
|
"@nrwl/jest": "10.4.1",
|
||||||
|
"@nrwl/node": "10.4.1",
|
||||||
"@nrwl/nx-cloud": "10.1.9",
|
"@nrwl/nx-cloud": "10.1.9",
|
||||||
"@nrwl/web": "10.4.0-beta.2",
|
"@nrwl/web": "10.4.1",
|
||||||
"@nrwl/workspace": "10.4.0-beta.2",
|
"@nrwl/workspace": "10.4.1",
|
||||||
"@reduxjs/toolkit": "1.3.2",
|
"@reduxjs/toolkit": "1.3.2",
|
||||||
"@rollup/plugin-babel": "5.0.2",
|
"@rollup/plugin-babel": "5.0.2",
|
||||||
"@rollup/plugin-commonjs": "11.0.2",
|
"@rollup/plugin-commonjs": "11.0.2",
|
||||||
@ -252,7 +253,9 @@
|
|||||||
"yargs-parser": "20.0.0",
|
"yargs-parser": "20.0.0",
|
||||||
"zone.js": "^0.10.0",
|
"zone.js": "^0.10.0",
|
||||||
"ejs": "^3.1.5",
|
"ejs": "^3.1.5",
|
||||||
"tsconfig-paths":"^3.9.0"
|
"tsconfig-paths": "^3.9.0",
|
||||||
|
"node-watch": "0.7.0",
|
||||||
|
"http-server": "0.12.3"
|
||||||
},
|
},
|
||||||
"author": "Victor Savkin",
|
"author": "Victor Savkin",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@ -1,4 +1,10 @@
|
|||||||
export { Tree, FileChange } from '@nrwl/tao/src/shared/tree';
|
export { Tree, FileChange } from '@nrwl/tao/src/shared/tree';
|
||||||
|
export {
|
||||||
|
WorkspaceDefinition,
|
||||||
|
TargetDefinition,
|
||||||
|
ProjectDefinition,
|
||||||
|
} from '@nrwl/tao/src/shared/workspace';
|
||||||
|
export { TargetContext } from '@nrwl/tao/src/commands/run';
|
||||||
export { formatFiles } from './src/schematics/format-files';
|
export { formatFiles } from './src/schematics/format-files';
|
||||||
export { generateFiles } from './src/schematics/generate-files';
|
export { generateFiles } from './src/schematics/generate-files';
|
||||||
export { installPackagesTask } from './src/tasks/install-packages-task';
|
export { installPackagesTask } from './src/tasks/install-packages-task';
|
||||||
|
|||||||
@ -1,62 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/schema",
|
|
||||||
"id": "BuildersSchema",
|
|
||||||
"title": "Builders schema for validating a list of builders.",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"$schema": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Link to schema."
|
|
||||||
},
|
|
||||||
"builders": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": {
|
|
||||||
"$ref": "#/definitions/builder"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["builders"],
|
|
||||||
"definitions": {
|
|
||||||
"builder": {
|
|
||||||
"type": "object",
|
|
||||||
"description": "Target options for Builders.",
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"properties": {
|
|
||||||
"schema": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Schema for builder option validation."
|
|
||||||
},
|
|
||||||
"description": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Builder description."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["schema", "description"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"properties": {
|
|
||||||
"implementation": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The next generation builder module."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["implementation"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"properties": {
|
|
||||||
"class": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The builder class module."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["class"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -8,7 +8,12 @@ import {
|
|||||||
Schema,
|
Schema,
|
||||||
} from '../shared/params';
|
} from '../shared/params';
|
||||||
import { commandName, printHelp } from '../shared/print-help';
|
import { commandName, printHelp } from '../shared/print-help';
|
||||||
import { WorkspaceDefinition, Workspaces } from '../shared/workspace';
|
import {
|
||||||
|
TargetDefinition,
|
||||||
|
WorkspaceDefinition,
|
||||||
|
Workspaces,
|
||||||
|
} from '../shared/workspace';
|
||||||
|
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
|
||||||
export interface RunOptions {
|
export interface RunOptions {
|
||||||
@ -130,17 +135,22 @@ export function validateTargetAndConfiguration(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TargetContext {
|
||||||
|
root: string;
|
||||||
|
target: TargetDefinition;
|
||||||
|
workspace: WorkspaceDefinition;
|
||||||
|
}
|
||||||
|
|
||||||
export async function run(root: string, args: string[], isVerbose: boolean) {
|
export async function run(root: string, args: string[], isVerbose: boolean) {
|
||||||
const logger = getLogger(isVerbose) as any;
|
const logger = getLogger(isVerbose) as any;
|
||||||
const ws = new Workspaces();
|
const ws = new Workspaces();
|
||||||
|
|
||||||
return handleErrors(logger, isVerbose, async () => {
|
return handleErrors(logger, isVerbose, async () => {
|
||||||
const workspaceDefinition = ws.readWorkspaceConfiguration(root);
|
const workspace = ws.readWorkspaceConfiguration(root);
|
||||||
const opts = parseRunOpts(args, workspaceDefinition.defaultProject, logger);
|
const opts = parseRunOpts(args, workspace.defaultProject, logger);
|
||||||
validateTargetAndConfiguration(workspaceDefinition, opts);
|
validateTargetAndConfiguration(workspace, opts);
|
||||||
|
|
||||||
const target =
|
const target = workspace.projects[opts.project].architect[opts.target];
|
||||||
workspaceDefinition.projects[opts.project].architect[opts.target];
|
|
||||||
if (ws.isNxBuilder(target)) {
|
if (ws.isNxBuilder(target)) {
|
||||||
const { schema, implementation } = ws.readBuilder(target);
|
const { schema, implementation } = ws.readBuilder(target);
|
||||||
const combinedOptions = combineOptionsForBuilder(
|
const combinedOptions = combineOptionsForBuilder(
|
||||||
@ -153,7 +163,7 @@ export async function run(root: string, args: string[], isVerbose: boolean) {
|
|||||||
printRunHelp(opts, schema, logger);
|
printRunHelp(opts, schema, logger);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return await implementation(combinedOptions);
|
return await implementation(combinedOptions, { root, target, workspace });
|
||||||
} else {
|
} else {
|
||||||
return (await import('./ngcli-adapter')).run(logger, root, opts);
|
return (await import('./ngcli-adapter')).run(logger, root, opts);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,13 +39,13 @@ export class Workspaces {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isNxBuilder(target: TargetDefinition) {
|
isNxBuilder(target: TargetDefinition) {
|
||||||
const { buildersJson } = this.readBuildersJson(target);
|
const schema = this.readBuilder(target).schema;
|
||||||
return buildersJson['$schema'] === '@nrwl/tao/src/builders-schema.json';
|
return schema['cli'] === 'nx';
|
||||||
}
|
}
|
||||||
|
|
||||||
isNxSchematic(collectionName: string, schematicName: string) {
|
isNxSchematic(collectionName: string, schematicName: string) {
|
||||||
const schema = this.readSchematic(collectionName, schematicName).schema;
|
const schema = this.readSchematic(collectionName, schematicName).schema;
|
||||||
return schema['$schema'] === '@nrwl/tao/src/schematic-schema.json';
|
return schema['cli'] === 'nx';
|
||||||
}
|
}
|
||||||
|
|
||||||
readBuilder(target: TargetDefinition) {
|
readBuilder(target: TargetDefinition) {
|
||||||
|
|||||||
@ -15,6 +15,11 @@
|
|||||||
"implementation": "./src/builders/dev-server/dev-server.impl",
|
"implementation": "./src/builders/dev-server/dev-server.impl",
|
||||||
"schema": "./src/builders/dev-server/schema.json",
|
"schema": "./src/builders/dev-server/schema.json",
|
||||||
"description": "Serve a web application"
|
"description": "Serve a web application"
|
||||||
|
},
|
||||||
|
"file-server": {
|
||||||
|
"implementation": "./src/builders/file-server/file-server.impl",
|
||||||
|
"schema": "./src/builders/file-server/schema.json",
|
||||||
|
"description": "Serve a web application from a folder"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -117,6 +117,9 @@
|
|||||||
"webpack-subresource-integrity": "^1.5.1",
|
"webpack-subresource-integrity": "^1.5.1",
|
||||||
"worker-plugin": "3.2.0",
|
"worker-plugin": "3.2.0",
|
||||||
"webpack-dev-server": "3.11.0",
|
"webpack-dev-server": "3.11.0",
|
||||||
"webpack-node-externals": "1.7.2"
|
"webpack-node-externals": "1.7.2",
|
||||||
|
"node-watch": "0.7.0",
|
||||||
|
"http-server": "0.12.3",
|
||||||
|
"ignore": "^5.0.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
136
packages/web/src/builders/file-server/file-server.impl.ts
Normal file
136
packages/web/src/builders/file-server/file-server.impl.ts
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
import { JsonObject } from '@angular-devkit/core';
|
||||||
|
import watch from 'node-watch';
|
||||||
|
import { exec, execSync } from 'child_process';
|
||||||
|
import { TargetContext } from '@nrwl/devkit';
|
||||||
|
import ignore from 'ignore';
|
||||||
|
import { readFileSync } from 'fs-extra';
|
||||||
|
|
||||||
|
export interface FileServerOptions extends JsonObject {
|
||||||
|
host: string;
|
||||||
|
port: number;
|
||||||
|
ssl: boolean;
|
||||||
|
sslKey?: string;
|
||||||
|
sslCert?: string;
|
||||||
|
proxyUrl?: string;
|
||||||
|
buildTarget: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getHttpServerArgs(opts: FileServerOptions) {
|
||||||
|
const args = [] as any[];
|
||||||
|
if (opts.port) {
|
||||||
|
args.push(`-p=${opts.port}`);
|
||||||
|
}
|
||||||
|
if (opts.host) {
|
||||||
|
args.push(`-a=${opts.host}`);
|
||||||
|
}
|
||||||
|
if (opts.ssl) {
|
||||||
|
args.push(`-S`);
|
||||||
|
}
|
||||||
|
if (opts.sslCert) {
|
||||||
|
args.push(`-C=${opts.sslCert}`);
|
||||||
|
}
|
||||||
|
if (opts.sslKey) {
|
||||||
|
args.push(`-K=${opts.sslCert}`);
|
||||||
|
}
|
||||||
|
if (opts.proxyUrl) {
|
||||||
|
args.push(`-P=${opts.proxyUrl}`);
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBuildTargetOutputPath(
|
||||||
|
opts: FileServerOptions,
|
||||||
|
context: TargetContext
|
||||||
|
) {
|
||||||
|
let buildOpts;
|
||||||
|
try {
|
||||||
|
const [project, target, config] = opts.buildTarget.split(':');
|
||||||
|
|
||||||
|
const buildTarget = context.workspace.projects[project].architect[target];
|
||||||
|
buildOpts = config
|
||||||
|
? { ...buildTarget.options, ...buildTarget.configurations[config] }
|
||||||
|
: buildTarget.options;
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Invalid buildTarget: ${opts.buildTarget}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: vsavkin we should also check outputs
|
||||||
|
const outputPath = buildOpts.outputPath;
|
||||||
|
if (!outputPath) {
|
||||||
|
throw new Error(
|
||||||
|
`Invalid buildTarget: ${opts.buildTarget}. The target must contain outputPath property.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return outputPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getIgnoredGlobs(root: string) {
|
||||||
|
const ig = ignore();
|
||||||
|
try {
|
||||||
|
ig.add(readFileSync(`${root}/.gitignore`).toString());
|
||||||
|
} catch (e) {}
|
||||||
|
try {
|
||||||
|
ig.add(readFileSync(`${root}/.nxignore`).toString());
|
||||||
|
} catch (e) {}
|
||||||
|
return ig;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function (
|
||||||
|
opts: FileServerOptions,
|
||||||
|
context: TargetContext
|
||||||
|
) {
|
||||||
|
let changed = true;
|
||||||
|
let running = false;
|
||||||
|
|
||||||
|
const fileFilter = getIgnoredGlobs(context.root).createFilter();
|
||||||
|
// TODO: vsavkin create a transitive closure of all deps and watch src of all the packages in the closure
|
||||||
|
watch('libs', { recursive: true, filter: fileFilter }, () => {
|
||||||
|
changed = true;
|
||||||
|
run();
|
||||||
|
});
|
||||||
|
watch('apps', { recursive: true, filter: fileFilter }, () => {
|
||||||
|
changed = true;
|
||||||
|
run();
|
||||||
|
});
|
||||||
|
|
||||||
|
function run() {
|
||||||
|
if (changed && !running) {
|
||||||
|
changed = false;
|
||||||
|
running = true;
|
||||||
|
try {
|
||||||
|
execSync(`npx nx run ${opts.buildTarget} --with-deps`, {
|
||||||
|
stdio: [0, 1, 2],
|
||||||
|
});
|
||||||
|
} catch (e) {}
|
||||||
|
running = false;
|
||||||
|
setTimeout(() => run(), 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const outputPath = getBuildTargetOutputPath(opts, context);
|
||||||
|
const args = getHttpServerArgs(opts);
|
||||||
|
run();
|
||||||
|
|
||||||
|
const serve = exec(`npx http-server ${outputPath} ${args.join(' ')}`, {
|
||||||
|
cwd: context.root,
|
||||||
|
});
|
||||||
|
serve.stdout.on('data', (chunk) => {
|
||||||
|
if (chunk.toString().indexOf('GET') === -1) {
|
||||||
|
process.stdout.write(chunk);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
serve.stderr.on('data', (chunk) => {
|
||||||
|
process.stderr.write(chunk);
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Promise((res) => {
|
||||||
|
serve.on('exit', (code) => {
|
||||||
|
if (code == 0) {
|
||||||
|
res({ success: true });
|
||||||
|
} else {
|
||||||
|
res({ success: false });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
39
packages/web/src/builders/file-server/schema.json
Normal file
39
packages/web/src/builders/file-server/schema.json
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"title": "File Server",
|
||||||
|
"description": "File Server",
|
||||||
|
"type": "object",
|
||||||
|
"cli": "nx",
|
||||||
|
"properties": {
|
||||||
|
"buildTarget": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Target which builds the application"
|
||||||
|
},
|
||||||
|
"port": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "Port to listen on.",
|
||||||
|
"default": 4200
|
||||||
|
},
|
||||||
|
"host": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Host to listen on.",
|
||||||
|
"default": "localhost"
|
||||||
|
},
|
||||||
|
"ssl": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Serve using HTTPS.",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"sslKey": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "SSL key to use for serving HTTPS."
|
||||||
|
},
|
||||||
|
"sslCert": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "SSL certificate to use for serving HTTPS."
|
||||||
|
},
|
||||||
|
"proxyUrl": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "URL to proxy unhandled requests to."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
"$schema": "@nrwl/tao/src/builders-schema.json",
|
|
||||||
"builders": {
|
"builders": {
|
||||||
"run-commands": {
|
"run-commands": {
|
||||||
"implementation": "./src/builders/run-commands/run-commands.impl",
|
"implementation": "./src/builders/run-commands/run-commands.impl",
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
"title": "Run Commands",
|
"title": "Run Commands",
|
||||||
"description": "Run any custom commands with Nx",
|
"description": "Run any custom commands with Nx",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"cli": "nx",
|
||||||
"properties": {
|
"properties": {
|
||||||
"commands": {
|
"commands": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
"id": "SchematicsRunCommands",
|
"id": "SchematicsRunCommands",
|
||||||
"title": "Create a custom target to run any command",
|
"title": "Create a custom target to run any command",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"cli": "nx",
|
||||||
"examples": [
|
"examples": [
|
||||||
{
|
{
|
||||||
"command": "g @nrwl/workspace:run-commands printhello --project my-feature-lib --command 'echo hello'",
|
"command": "g @nrwl/workspace:run-commands printhello --project my-feature-lib --command 'echo hello'",
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"$schema": "@nrwl/tao/src/schematic-schema.json",
|
"cli": "nx",
|
||||||
"id": "<%= name %>",
|
"id": "<%= name %>",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"$schema": "@nrwl/tao/src/schematic-schema.json",
|
"cli": "nx",
|
||||||
"id": "SchematicsNxWorkspaceSchematic",
|
"id": "SchematicsNxWorkspaceSchematic",
|
||||||
"title": "Create a custom schematic",
|
"title": "Create a custom schematic",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|||||||
204
yarn.lock
204
yarn.lock
@ -2594,32 +2594,21 @@
|
|||||||
node-gyp "^6.1.0"
|
node-gyp "^6.1.0"
|
||||||
read-package-json-fast "^1.1.3"
|
read-package-json-fast "^1.1.3"
|
||||||
|
|
||||||
"@nrwl/cli@10.3.1-beta.1":
|
"@nrwl/cli@10.4.1":
|
||||||
version "10.3.1-beta.1"
|
version "10.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-10.3.1-beta.1.tgz#a67326315884c986a0f366dcc82b8c3cdf24e25f"
|
resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-10.4.1.tgz#e3b662ae2e43264bcf9be7b9551448b52e6ddf1d"
|
||||||
integrity sha512-Wv19Unn6aWQ29Nx6rpWhzMh+bzTexyVm6Iol7f4mFDD5ZTqsxNFEuLCY69fwCE2tEN/6dHEV4IwWF9VdToZMLg==
|
integrity sha512-91AbEIbNC145KdaLCWCOVYktJ6GML25M5pN0ehSPmeIzOePpbF2zyGwUnSrmpdnjm63E0qkeDIspmt3527HGhA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@nrwl/tao" "10.3.1-beta.1"
|
"@nrwl/tao" "10.4.1"
|
||||||
chalk "2.4.2"
|
chalk "2.4.2"
|
||||||
tmp "0.0.33"
|
tmp "0.0.33"
|
||||||
yargs "15.4.1"
|
yargs "15.4.1"
|
||||||
yargs-parser "20.0.0"
|
yargs-parser "20.0.0"
|
||||||
|
|
||||||
"@nrwl/cli@10.4.0-beta.2":
|
"@nrwl/cypress@10.4.1":
|
||||||
version "10.4.0-beta.2"
|
version "10.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-10.4.0-beta.2.tgz#d94d1a23e3664f8b1b288e376121e8424fc3e41c"
|
resolved "https://registry.yarnpkg.com/@nrwl/cypress/-/cypress-10.4.1.tgz#9765f01edb2c2130bd2ce51ba8be55437e0060e8"
|
||||||
integrity sha512-nlQJX3KlXSrVwibMYW/YmWq0lnvn36Q77rjqHjU2yZZz8/jFMBOp9skiWpe3L5B1x3Bd2vHIf4zxCP3CvLFriA==
|
integrity sha512-b4SaOt/wGalw2MCCwLAQs5JxkfAEMfKXy3lV9AYN46fbjSPJGkvKt59lqEqVWAvKaArFooijTXPQhz5HrBp6qA==
|
||||||
dependencies:
|
|
||||||
"@nrwl/tao" "10.4.0-beta.2"
|
|
||||||
chalk "2.4.2"
|
|
||||||
tmp "0.0.33"
|
|
||||||
yargs "15.4.1"
|
|
||||||
yargs-parser "20.0.0"
|
|
||||||
|
|
||||||
"@nrwl/cypress@10.4.0-beta.2":
|
|
||||||
version "10.4.0-beta.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@nrwl/cypress/-/cypress-10.4.0-beta.2.tgz#305659dcb6e0b330114e8bb1dae387499f7b4c47"
|
|
||||||
integrity sha512-rXrX4O3vQmN3p5icLWGTp9H/kNeFZ2VmnWfqsBSz2LIOB/RalX/9TUPIiWzZxCv8fxA9Dib0o/yJLPgHGu9soQ==
|
|
||||||
dependencies:
|
dependencies:
|
||||||
"@angular-devkit/architect" "~0.1001.3"
|
"@angular-devkit/architect" "~0.1001.3"
|
||||||
"@angular-devkit/core" "~10.1.3"
|
"@angular-devkit/core" "~10.1.3"
|
||||||
@ -2635,46 +2624,46 @@
|
|||||||
webpack-node-externals "1.7.2"
|
webpack-node-externals "1.7.2"
|
||||||
yargs-parser "20.0.0"
|
yargs-parser "20.0.0"
|
||||||
|
|
||||||
"@nrwl/eslint-plugin-nx@10.4.0-beta.2":
|
"@nrwl/eslint-plugin-nx@10.4.1":
|
||||||
version "10.4.0-beta.2"
|
version "10.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-10.4.0-beta.2.tgz#262225d7bb370d8423579136c0c58acbd2074f98"
|
resolved "https://registry.yarnpkg.com/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-10.4.1.tgz#2063cdbe53a2f24904cdaada0ee6ee582be1582e"
|
||||||
integrity sha512-iX0SdrjtdqkjxhMS51SOne9JPD3s8BiYoLKHj0MdKBs8oowgJOHrr2RPHUT3EiWanuP9FUuN3rXqHaHQ9vuIHg==
|
integrity sha512-EWBuWD6kbc7yTc4rvZzT8DZyMFlMVBdOn7A3GIvVnkFJiXzvQ/ERg5Mv8dNmiEpU8f0MKZn3ILb4q28rOR5t/A==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@angular-devkit/core" "~10.1.3"
|
"@angular-devkit/core" "~10.1.3"
|
||||||
"@typescript-eslint/experimental-utils" "^4.3.0"
|
"@typescript-eslint/experimental-utils" "^4.3.0"
|
||||||
confusing-browser-globals "^1.0.9"
|
confusing-browser-globals "^1.0.9"
|
||||||
|
|
||||||
"@nrwl/jest@10.4.0-beta.2":
|
"@nrwl/jest@10.4.1":
|
||||||
version "10.4.0-beta.2"
|
version "10.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/@nrwl/jest/-/jest-10.4.0-beta.2.tgz#020493bd4a341bf35287fa9a32f438f7ee366ac2"
|
resolved "https://registry.yarnpkg.com/@nrwl/jest/-/jest-10.4.1.tgz#eb9e587db0fe5a599fd761829620a71ebd5c90cd"
|
||||||
integrity sha512-v2ZTVkTwc5RfdBaBF2OeY2lhZf46LYI2yXGBVOACBlsqKao/GypWrmw5BYCQiFt/MLqTIzMMKscbYxNSknELyg==
|
integrity sha512-5UaA5hc05YxfvDTopJQa/uelqb+HnBfgb4OkwixMPF/fISio2fwHMsrG+DSc0PAI3DH/qwy2AjZCPAbAlgU3Gw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@angular-devkit/architect" "~0.1001.3"
|
"@angular-devkit/architect" "~0.1001.3"
|
||||||
"@angular-devkit/core" "~10.1.3"
|
"@angular-devkit/core" "~10.1.3"
|
||||||
"@angular-devkit/schematics" "~10.1.3"
|
"@angular-devkit/schematics" "~10.1.3"
|
||||||
rxjs "^6.5.4"
|
rxjs "^6.5.4"
|
||||||
|
|
||||||
"@nrwl/linter@10.4.0-beta.2":
|
"@nrwl/linter@10.4.1":
|
||||||
version "10.4.0-beta.2"
|
version "10.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/@nrwl/linter/-/linter-10.4.0-beta.2.tgz#0e6a0c9ac8deb9e72d3d4d654811a44a0a46f0e3"
|
resolved "https://registry.yarnpkg.com/@nrwl/linter/-/linter-10.4.1.tgz#66f6df5ba8bdc081d0459ed5ab67f949e16ce80e"
|
||||||
integrity sha512-fqRwvuwCfMMByKWHWGMoAtbZa1dlm17iuq5WIMRADLi5L5/9wc9wtvZyP+rCnYXLcQ4w/WFCKae+/juJhZ20aA==
|
integrity sha512-CNb9yDeF1ABOuniLFN4k5H+UGQPk4rdY6i56LND/RwEgsLzvi65J7FyD8N1EF7M0HoEoDRykyZiDwU9WlG0NIQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@angular-devkit/architect" "~0.1001.3"
|
"@angular-devkit/architect" "~0.1001.3"
|
||||||
glob "7.1.4"
|
glob "7.1.4"
|
||||||
minimatch "3.0.4"
|
minimatch "3.0.4"
|
||||||
tslib "^2.0.0"
|
tslib "^2.0.0"
|
||||||
|
|
||||||
"@nrwl/node@10.4.0-beta.2":
|
"@nrwl/node@10.4.1":
|
||||||
version "10.4.0-beta.2"
|
version "10.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/@nrwl/node/-/node-10.4.0-beta.2.tgz#dbabe864bec378a3cd5f508d1e93e49d6594a4ef"
|
resolved "https://registry.yarnpkg.com/@nrwl/node/-/node-10.4.1.tgz#872ede5c4cb222f63e9bda1eaaee5bfec001ccfd"
|
||||||
integrity sha512-JeXSqBulbcXY1FB0KI5SKSkQdG8c/qQ01tGJ+C95vzuTMpWLj0rYxsxSVuVxDnVPtxrnBNOqA7WQKkwLDC5uYQ==
|
integrity sha512-B7BSx9jTEAd+GbHEBiEi49RgPGXRtQk1ozPTA7CFfGSM3v0hfLDqi1NTXFjfapR1kh5CFhP7n0UwlN9ggBUiIA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@angular-devkit/architect" "~0.1001.3"
|
"@angular-devkit/architect" "~0.1001.3"
|
||||||
"@angular-devkit/build-webpack" "~0.1001.3"
|
"@angular-devkit/build-webpack" "~0.1001.3"
|
||||||
"@angular-devkit/core" "~10.1.3"
|
"@angular-devkit/core" "~10.1.3"
|
||||||
"@angular-devkit/schematics" "~10.1.3"
|
"@angular-devkit/schematics" "~10.1.3"
|
||||||
"@nrwl/jest" "10.4.0-beta.2"
|
"@nrwl/jest" "10.4.1"
|
||||||
"@nrwl/linter" "10.4.0-beta.2"
|
"@nrwl/linter" "10.4.1"
|
||||||
circular-dependency-plugin "5.2.0"
|
circular-dependency-plugin "5.2.0"
|
||||||
copy-webpack-plugin "6.0.3"
|
copy-webpack-plugin "6.0.3"
|
||||||
fork-ts-checker-webpack-plugin "^3.1.1"
|
fork-ts-checker-webpack-plugin "^3.1.1"
|
||||||
@ -2700,26 +2689,10 @@
|
|||||||
tar "5.0.5"
|
tar "5.0.5"
|
||||||
uuid "^3.3.3"
|
uuid "^3.3.3"
|
||||||
|
|
||||||
"@nrwl/tao@10.3.1-beta.1":
|
"@nrwl/tao@10.4.1":
|
||||||
version "10.3.1-beta.1"
|
version "10.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-10.3.1-beta.1.tgz#a51b48b5c0f077136a5a7e715c6436d683fab4db"
|
resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-10.4.1.tgz#5343078fd431b548df91d18f6170790602386b09"
|
||||||
integrity sha512-WDSgxXz0VB1zK2t6ErbX8I9uh8rjIVpBVajNbMVhwy+CzrsK4FMwRhhk3sbA5gCKv5yQ0xFygodHYeca8VpnCg==
|
integrity sha512-wlaC9f3pfX0JhSMhPmQCjr3BKEPhxMzmVQ6+cXbTLH8wIUqrYKs1I6FRu+gPI4zWuDQrX5S8sQk4wVUiraiJIA==
|
||||||
dependencies:
|
|
||||||
"@angular-devkit/architect" "~0.1001.3"
|
|
||||||
"@angular-devkit/core" "~10.1.3"
|
|
||||||
"@angular-devkit/schematics" "~10.1.3"
|
|
||||||
inquirer "^6.3.1"
|
|
||||||
minimist "^1.2.0"
|
|
||||||
semver "6.3.0"
|
|
||||||
strip-json-comments "2.0.1"
|
|
||||||
tmp "0.0.33"
|
|
||||||
tslib "^1.9.3"
|
|
||||||
yargs-parser "20.0.0"
|
|
||||||
|
|
||||||
"@nrwl/tao@10.4.0-beta.2":
|
|
||||||
version "10.4.0-beta.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-10.4.0-beta.2.tgz#2b94cc4eb121dee9e94dae4a7fbf873399b9f942"
|
|
||||||
integrity sha512-XBdaM3/TA96yj5aiftcQJZFfmOa1KEvJ1wZ/QMIjK+AWOHjl0XynwXnolh3mormrznaLY4Z819CNC68mgfhVqg==
|
|
||||||
dependencies:
|
dependencies:
|
||||||
"@angular-devkit/architect" "~0.1001.3"
|
"@angular-devkit/architect" "~0.1001.3"
|
||||||
"@angular-devkit/core" "~10.1.3"
|
"@angular-devkit/core" "~10.1.3"
|
||||||
@ -2732,10 +2705,10 @@
|
|||||||
tslib "^2.0.0"
|
tslib "^2.0.0"
|
||||||
yargs-parser "20.0.0"
|
yargs-parser "20.0.0"
|
||||||
|
|
||||||
"@nrwl/web@10.4.0-beta.2":
|
"@nrwl/web@10.4.1":
|
||||||
version "10.4.0-beta.2"
|
version "10.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/@nrwl/web/-/web-10.4.0-beta.2.tgz#15e5cc85558dfc9f8b4903fc32a84e045c8c8de4"
|
resolved "https://registry.yarnpkg.com/@nrwl/web/-/web-10.4.1.tgz#a22540bfdc25f887f760cb285b7a2490c22af34a"
|
||||||
integrity sha512-n6WS+9Tdfx4BSnaIT6n6vXkbskUnPtMeuXyxZzK0FcXuNU7MzIw1MNXVXYMeSsnjsUzqrErRWvBQ4nnvWjZ1tA==
|
integrity sha512-qXqjKna8fSWyD4Vgn/KfX+p7iU2C35PEsjlaHkvr34Z2zbLcKcZ1C4rSpjUWCLKzJOQ2D5kijNOBpswvrp08+g==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@angular-devkit/architect" "~0.1001.3"
|
"@angular-devkit/architect" "~0.1001.3"
|
||||||
"@angular-devkit/build-optimizer" "~0.1001.3"
|
"@angular-devkit/build-optimizer" "~0.1001.3"
|
||||||
@ -2748,9 +2721,9 @@
|
|||||||
"@babel/plugin-transform-regenerator" "7.8.7"
|
"@babel/plugin-transform-regenerator" "7.8.7"
|
||||||
"@babel/preset-env" "7.9.6"
|
"@babel/preset-env" "7.9.6"
|
||||||
"@babel/preset-typescript" "7.10.4"
|
"@babel/preset-typescript" "7.10.4"
|
||||||
"@nrwl/cypress" "10.4.0-beta.2"
|
"@nrwl/cypress" "10.4.1"
|
||||||
"@nrwl/jest" "10.4.0-beta.2"
|
"@nrwl/jest" "10.4.1"
|
||||||
"@nrwl/linter" "10.4.0-beta.2"
|
"@nrwl/linter" "10.4.1"
|
||||||
"@rollup/plugin-babel" "5.0.2"
|
"@rollup/plugin-babel" "5.0.2"
|
||||||
"@rollup/plugin-commonjs" "11.0.2"
|
"@rollup/plugin-commonjs" "11.0.2"
|
||||||
"@rollup/plugin-image" "2.0.4"
|
"@rollup/plugin-image" "2.0.4"
|
||||||
@ -2825,15 +2798,15 @@
|
|||||||
webpack-subresource-integrity "^1.5.1"
|
webpack-subresource-integrity "^1.5.1"
|
||||||
worker-plugin "3.2.0"
|
worker-plugin "3.2.0"
|
||||||
|
|
||||||
"@nrwl/workspace@10.4.0-beta.2":
|
"@nrwl/workspace@10.4.1":
|
||||||
version "10.4.0-beta.2"
|
version "10.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-10.4.0-beta.2.tgz#f5fde6d70198b00213105c51eb3693925b3dddda"
|
resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-10.4.1.tgz#1839c31c91c260d927403fde34fc693015fb4777"
|
||||||
integrity sha512-2TUIdPQ6Hq8mmDCYaVoXfTGrfMoM4L45fLRrpyJWhJ3zgYJFSiS/Aiu7z1OaPrDkc3K9d+jdqmyaW7Smc7c+4Q==
|
integrity sha512-77JdHbnwpxwlVxXjzTKeP/KDsxZEck3aGvH7ZAnNo3RT6fdcdKHHAi1VK4jdSl36UlXYC3UOTZWJRU2jzj4sGw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@angular-devkit/architect" "~0.1001.3"
|
"@angular-devkit/architect" "~0.1001.3"
|
||||||
"@angular-devkit/core" "~10.1.3"
|
"@angular-devkit/core" "~10.1.3"
|
||||||
"@angular-devkit/schematics" "~10.1.3"
|
"@angular-devkit/schematics" "~10.1.3"
|
||||||
"@nrwl/cli" "10.4.0-beta.2"
|
"@nrwl/cli" "10.4.1"
|
||||||
axios "0.19.2"
|
axios "0.19.2"
|
||||||
chalk "2.4.2"
|
chalk "2.4.2"
|
||||||
cosmiconfig "^4.0.0"
|
cosmiconfig "^4.0.0"
|
||||||
@ -6608,6 +6581,11 @@ base@^0.11.1:
|
|||||||
mixin-deep "^1.2.0"
|
mixin-deep "^1.2.0"
|
||||||
pascalcase "^0.1.1"
|
pascalcase "^0.1.1"
|
||||||
|
|
||||||
|
basic-auth@^1.0.3:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-1.1.0.tgz#45221ee429f7ee1e5035be3f51533f1cdfd29884"
|
||||||
|
integrity sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ=
|
||||||
|
|
||||||
batch-processor@1.0.0:
|
batch-processor@1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/batch-processor/-/batch-processor-1.0.0.tgz#75c95c32b748e0850d10c2b168f6bdbe9891ace8"
|
resolved "https://registry.yarnpkg.com/batch-processor/-/batch-processor-1.0.0.tgz#75c95c32b748e0850d10c2b168f6bdbe9891ace8"
|
||||||
@ -8423,6 +8401,11 @@ cors@2.8.5:
|
|||||||
object-assign "^4"
|
object-assign "^4"
|
||||||
vary "^1"
|
vary "^1"
|
||||||
|
|
||||||
|
corser@^2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/corser/-/corser-2.0.1.tgz#8eda252ecaab5840dcd975ceb90d9370c819ff87"
|
||||||
|
integrity sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=
|
||||||
|
|
||||||
cosmiconfig@^4.0.0:
|
cosmiconfig@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc"
|
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc"
|
||||||
@ -10313,6 +10296,16 @@ ecdsa-sig-formatter@1.0.11:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "^5.0.1"
|
safe-buffer "^5.0.1"
|
||||||
|
|
||||||
|
ecstatic@^3.3.2:
|
||||||
|
version "3.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/ecstatic/-/ecstatic-3.3.2.tgz#6d1dd49814d00594682c652adb66076a69d46c48"
|
||||||
|
integrity sha512-fLf9l1hnwrHI2xn9mEDT7KIi22UDqA2jaCwyCbSUJh9a1V+LEUSL/JO/6TIz/QyuBURWUHrFL5Kg2TtO1bkkog==
|
||||||
|
dependencies:
|
||||||
|
he "^1.1.1"
|
||||||
|
mime "^1.6.0"
|
||||||
|
minimist "^1.1.0"
|
||||||
|
url-join "^2.0.5"
|
||||||
|
|
||||||
editor@1.0.0:
|
editor@1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742"
|
resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742"
|
||||||
@ -10330,6 +10323,13 @@ ejs@^3.1.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
jake "^10.6.1"
|
jake "^10.6.1"
|
||||||
|
|
||||||
|
ejs@^3.1.5:
|
||||||
|
version "3.1.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.5.tgz#aed723844dc20acb4b170cd9ab1017e476a0d93b"
|
||||||
|
integrity sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w==
|
||||||
|
dependencies:
|
||||||
|
jake "^10.6.1"
|
||||||
|
|
||||||
electron-to-chromium@^1.3.378:
|
electron-to-chromium@^1.3.378:
|
||||||
version "1.3.514"
|
version "1.3.514"
|
||||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.514.tgz#107499c28cb3c09fe6a863c19fc2202d5d9e8e41"
|
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.514.tgz#107499c28cb3c09fe6a863c19fc2202d5d9e8e41"
|
||||||
@ -12512,7 +12512,7 @@ he@1.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
|
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
|
||||||
integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0=
|
integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0=
|
||||||
|
|
||||||
he@1.2.x, he@^1.1.0, he@^1.2.0:
|
he@1.2.x, he@^1.1.0, he@^1.1.1, he@^1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||||
@ -12786,7 +12786,7 @@ http-proxy-middleware@0.19.1:
|
|||||||
lodash "^4.17.11"
|
lodash "^4.17.11"
|
||||||
micromatch "^3.1.10"
|
micromatch "^3.1.10"
|
||||||
|
|
||||||
http-proxy@^1.13.0, http-proxy@^1.17.0:
|
http-proxy@^1.13.0, http-proxy@^1.17.0, http-proxy@^1.18.0:
|
||||||
version "1.18.1"
|
version "1.18.1"
|
||||||
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
|
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
|
||||||
integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==
|
integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==
|
||||||
@ -12795,6 +12795,22 @@ http-proxy@^1.13.0, http-proxy@^1.17.0:
|
|||||||
follow-redirects "^1.0.0"
|
follow-redirects "^1.0.0"
|
||||||
requires-port "^1.0.0"
|
requires-port "^1.0.0"
|
||||||
|
|
||||||
|
http-server@0.12.3:
|
||||||
|
version "0.12.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/http-server/-/http-server-0.12.3.tgz#ba0471d0ecc425886616cb35c4faf279140a0d37"
|
||||||
|
integrity sha512-be0dKG6pni92bRjq0kvExtj/NrrAd28/8fCXkaI/4piTwQMSDSLMhWyW0NI1V+DBI3aa1HMlQu46/HjVLfmugA==
|
||||||
|
dependencies:
|
||||||
|
basic-auth "^1.0.3"
|
||||||
|
colors "^1.4.0"
|
||||||
|
corser "^2.0.1"
|
||||||
|
ecstatic "^3.3.2"
|
||||||
|
http-proxy "^1.18.0"
|
||||||
|
minimist "^1.2.5"
|
||||||
|
opener "^1.5.1"
|
||||||
|
portfinder "^1.0.25"
|
||||||
|
secure-compare "3.0.1"
|
||||||
|
union "~0.5.0"
|
||||||
|
|
||||||
http-signature@~1.2.0:
|
http-signature@~1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
|
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
|
||||||
@ -15906,7 +15922,7 @@ mime-types@^2.1.12, mime-types@^2.1.26, mime-types@~2.1.17, mime-types@~2.1.19,
|
|||||||
dependencies:
|
dependencies:
|
||||||
mime-db "1.44.0"
|
mime-db "1.44.0"
|
||||||
|
|
||||||
mime@1.6.0, mime@^1.4.1:
|
mime@1.6.0, mime@^1.4.1, mime@^1.6.0:
|
||||||
version "1.6.0"
|
version "1.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||||
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
||||||
@ -16025,7 +16041,7 @@ minimist-options@^4.0.2:
|
|||||||
is-plain-obj "^1.1.0"
|
is-plain-obj "^1.1.0"
|
||||||
kind-of "^6.0.3"
|
kind-of "^6.0.3"
|
||||||
|
|
||||||
minimist@1.2.5, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5:
|
minimist@1.2.5, minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5:
|
||||||
version "1.2.5"
|
version "1.2.5"
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||||
@ -16159,7 +16175,7 @@ mkdirp@0.5.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
minimist "^1.2.5"
|
minimist "^1.2.5"
|
||||||
|
|
||||||
mkdirp@0.5.5, mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@~0.5.1, mkdirp@~0.5.x:
|
mkdirp@0.5.5, mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.1, mkdirp@~0.5.x:
|
||||||
version "0.5.5"
|
version "0.5.5"
|
||||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
||||||
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
|
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
|
||||||
@ -16611,6 +16627,11 @@ node-sass-tilde-importer@^1.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
find-parent-dir "^0.3.0"
|
find-parent-dir "^0.3.0"
|
||||||
|
|
||||||
|
node-watch@0.7.0:
|
||||||
|
version "0.7.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-watch/-/node-watch-0.7.0.tgz#033c0c04239d9348f3402b6b6f9c1e689a7edbe1"
|
||||||
|
integrity sha512-OOBiglke5SlRQT5WYfwXTmYqTfXjcTNBHpalyHLtLxDpQYVpVRkJqabcch1kmwJsjV/J4OZuzEafeb4soqtFZA==
|
||||||
|
|
||||||
nopt@^4.0.1:
|
nopt@^4.0.1:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48"
|
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48"
|
||||||
@ -17044,6 +17065,11 @@ opencollective-postinstall@^2.0.0, opencollective-postinstall@^2.0.2:
|
|||||||
resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259"
|
resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259"
|
||||||
integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==
|
integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==
|
||||||
|
|
||||||
|
opener@^1.5.1:
|
||||||
|
version "1.5.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598"
|
||||||
|
integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==
|
||||||
|
|
||||||
opn@^5.3.0, opn@^5.5.0:
|
opn@^5.3.0, opn@^5.5.0:
|
||||||
version "5.5.0"
|
version "5.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc"
|
resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc"
|
||||||
@ -17797,6 +17823,15 @@ popper.js@^1.14.4, popper.js@^1.14.7:
|
|||||||
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
|
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
|
||||||
integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==
|
integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==
|
||||||
|
|
||||||
|
portfinder@^1.0.25:
|
||||||
|
version "1.0.28"
|
||||||
|
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778"
|
||||||
|
integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==
|
||||||
|
dependencies:
|
||||||
|
async "^2.6.2"
|
||||||
|
debug "^3.1.1"
|
||||||
|
mkdirp "^0.5.5"
|
||||||
|
|
||||||
portfinder@^1.0.26:
|
portfinder@^1.0.26:
|
||||||
version "1.0.26"
|
version "1.0.26"
|
||||||
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70"
|
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70"
|
||||||
@ -18618,7 +18653,7 @@ qs@6.7.0:
|
|||||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
|
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
|
||||||
integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
|
integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
|
||||||
|
|
||||||
qs@^6.6.0:
|
qs@^6.4.0, qs@^6.6.0:
|
||||||
version "6.9.4"
|
version "6.9.4"
|
||||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687"
|
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687"
|
||||||
integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==
|
integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==
|
||||||
@ -20188,6 +20223,11 @@ schema-utils@^2.0.0, schema-utils@^2.0.1, schema-utils@^2.5.0, schema-utils@^2.6
|
|||||||
ajv "^6.12.2"
|
ajv "^6.12.2"
|
||||||
ajv-keywords "^3.4.1"
|
ajv-keywords "^3.4.1"
|
||||||
|
|
||||||
|
secure-compare@3.0.1:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/secure-compare/-/secure-compare-3.0.1.tgz#f1a0329b308b221fae37b9974f3d578d0ca999e3"
|
||||||
|
integrity sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=
|
||||||
|
|
||||||
select-hose@^2.0.0:
|
select-hose@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
||||||
@ -22239,6 +22279,13 @@ union-value@^1.0.0:
|
|||||||
is-extendable "^0.1.1"
|
is-extendable "^0.1.1"
|
||||||
set-value "^2.0.1"
|
set-value "^2.0.1"
|
||||||
|
|
||||||
|
union@~0.5.0:
|
||||||
|
version "0.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/union/-/union-0.5.0.tgz#b2c11be84f60538537b846edb9ba266ba0090075"
|
||||||
|
integrity sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==
|
||||||
|
dependencies:
|
||||||
|
qs "^6.4.0"
|
||||||
|
|
||||||
uniq@^1.0.1:
|
uniq@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
|
resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
|
||||||
@ -22367,6 +22414,11 @@ urix@^0.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
|
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
|
||||||
integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
|
integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
|
||||||
|
|
||||||
|
url-join@^2.0.5:
|
||||||
|
version "2.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/url-join/-/url-join-2.0.5.tgz#5af22f18c052a000a48d7b82c5e9c2e2feeda728"
|
||||||
|
integrity sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=
|
||||||
|
|
||||||
url-loader@^3.0.0:
|
url-loader@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-3.0.0.tgz#9f1f11b371acf6e51ed15a50db635e02eec18368"
|
resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-3.0.0.tgz#9f1f11b371acf6e51ed15a50db635e02eec18368"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user