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