chore(gatsby): move gatsby plugin to main repo

This commit is contained in:
Jack Hsu 2021-01-18 13:22:58 -05:00 committed by Victor Savkin
parent ffe769f102
commit 51973b88e2
98 changed files with 4361 additions and 24 deletions

View File

@ -8,7 +8,7 @@ var_2:
'e2e-cli,e2e-nx-plugin,dep-graph-client-e2e', 'e2e-cli,e2e-nx-plugin,dep-graph-client-e2e',
'e2e-cypress,e2e-jest', 'e2e-cypress,e2e-jest',
'e2e-react', 'e2e-react',
'e2e-next', 'e2e-next,e2e-gatsby',
'e2e-node', 'e2e-node',
'e2e-web,e2e-linter,e2e-storybook', 'e2e-web,e2e-linter,e2e-storybook',
] ]

View File

@ -19,6 +19,7 @@ module.exports = {
{ name: 'core', description: 'anything Nx core specific' }, { name: 'core', description: 'anything Nx core specific' },
{ name: 'nxdev', description: 'anything related to docs infrastructure' }, { name: 'nxdev', description: 'anything related to docs infrastructure' },
{ name: 'nextjs', description: 'anything Next specific' }, { name: 'nextjs', description: 'anything Next specific' },
{ name: 'gatsby', description: 'anything Gatsby specific' },
{ name: 'nest', description: 'anything Nest specific' }, { name: 'nest', description: 'anything Nest specific' },
{ name: 'node', description: 'anything Node specific' }, { name: 'node', description: 'anything Node specific' },
{ name: 'express', description: 'anything Express specific' }, { name: 'express', description: 'anything Express specific' },

View File

@ -0,0 +1,47 @@
# build
Build a Gatsby app
Properties can be configured in angular.json when defining the executor, or when invoking it.
## Properties
### color
Default: `true`
Type: `boolean`
Enable colored terminal output.
### graphqlTracing
Type: `boolean`
Trace every graphql resolver, may have performance implications.
### openTracingConfigFile
Type: `string`
Tracer configuration file (OpenTracing compatible).
### prefixPaths
Type: `boolean`
Build site with link paths prefixed (set pathPrefix in your config).
### profile
Type: `boolean`
Build site with react profiling.
### uglify
Default: `true`
Type: `boolean`
Build site without uglifying JS bundles (true by default).

View File

@ -0,0 +1,43 @@
# server
Starts server for app
Properties can be configured in angular.json when defining the executor, or when invoking it.
## Properties
### buildTarget
Type: `string`
Target which builds the application
### host
Default: `localhost`
Type: `string`
Host to listen on.
### https
Default: `false`
Type: `boolean`
Serve using HTTPS.
### open
Type: `boolean`
Open the site in your (default) browser for you.
### port
Default: `4200`
Type: `number`
Port to listen on.

View File

@ -0,0 +1,89 @@
# application
Create an application
## Usage
```bash
nx generate application ...
```
```bash
nx 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
nx g @nrwl/gatsby:application ...
```
Show what will be generated without writing to disk:
```bash
nx g application ... --dry-run
```
## Options
### directory
Alias(es): d
Type: `string`
A directory where the project is placed
### e2eTestRunner
Default: `cypress`
Type: `string`
Possible values: `cypress`, `none`
Adds the specified e2e test runner
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files
### name
Type: `string`
### style
Alias(es): s
Default: `css`
Type: `string`
Possible values: `css`, `scss`, `styl`, `less`, `styled-components`, `@emotion/styled`, `none`
The file extension to be used for style files.
### tags
Alias(es): t
Type: `string`
Add tags to the project (used for linting)
### unitTestRunner
Default: `jest`
Type: `string`
Possible values: `jest`, `none`
Adds the specified unit test runner

View File

@ -0,0 +1,107 @@
# component
Create a component
## Usage
```bash
nx generate component ...
```
By default, Nx will search for `component` in the default collection provisioned in `angular.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/gatsby:component ...
```
Show what will be generated without writing to disk:
```bash
nx g component ... --dry-run
```
### Examples
Generate a component in the mylib library:
```bash
nx g component my-component --project=mylib
```
Generate a class component in the mylib library:
```bash
nx g component my-component --project=mylib --classComponent
```
## Options
### directory
Alias(es): d
Type: `string`
Create the component under this directory (can be nested).
### export
Alias(es): e
Default: `false`
Type: `boolean`
When true, the component is exported from the project index.ts (if it exists).
### flat
Default: `false`
Type: `boolean`
Create component at the source root rather than its own directory.
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files.
### name
Type: `string`
The name of the component.
### project
Alias(es): p
Type: `string`
The name of the project.
### skipTests
Default: `false`
Type: `boolean`
When true, does not create "spec.ts" test files for the new component.
### style
Alias(es): s
Default: `css`
Type: `string`
Possible values: `css`, `scss`, `styl`, `less`, `styled-components`, `@emotion/styled`, `none`
The file extension to be used for style files.

View File

@ -0,0 +1,107 @@
# page
Create a page
## Usage
```bash
nx generate page ...
```
By default, Nx will search for `page` in the default collection provisioned in `angular.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/gatsby:page ...
```
Show what will be generated without writing to disk:
```bash
nx g page ... --dry-run
```
### Examples
Generate a page in the mylib library:
```bash
nx g page my-page --project=mylib
```
Generate a class component in the mylib library:
```bash
nx g page my-page --project=mylib --classComponent
```
## Options
### directory
Alias(es): d
Type: `string`
Create the component under this directory (can be nested).
### export
Alias(es): e
Default: `false`
Type: `boolean`
When true, the component is exported from the project index.ts (if it exists).
### flat
Default: `false`
Type: `boolean`
Create component at the source root rather than its own directory.
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files.
### name
Type: `string`
The name of the component.
### project
Alias(es): p
Type: `string`
The name of the project.
### skipTests
Default: `false`
Type: `boolean`
When true, does not create "spec.ts" test files for the new component.
### style
Alias(es): s
Default: `css`
Type: `string`
Possible values: `css`, `scss`, `styl`, `less`, `styled-components`, `@emotion/styled`, `none`
The file extension to be used for style files.

View File

@ -2,6 +2,7 @@
"angular", "angular",
"cypress", "cypress",
"express", "express",
"gatsby",
"jest", "jest",
"linter", "linter",
"nest", "nest",

View File

@ -2,6 +2,7 @@
"angular", "angular",
"cypress", "cypress",
"express", "express",
"gatsby",
"jest", "jest",
"nest", "nest",
"next", "next",

View File

@ -1699,6 +1699,104 @@
"name": "service generator", "name": "service generator",
"id": "service", "id": "service",
"file": "react/api-nest/generators/service" "file": "react/api-nest/generators/service"
},
{
"name": "gatsby",
"id": "gatsby",
"itemList": [
{
"id": "overview",
"name": "Overview",
"searchResultsName": "@nrwl/gatsby Overview",
"file": "shared/gatsby-plugin"
},
{
"id": "generators",
"name": "Generators",
"itemList": [
{
"name": "application",
"id": "application",
"file": "angular/api-gatsby/generators/application"
},
{
"name": "component",
"id": "component",
"file": "angular/api-gatsby/generators/component"
},
{
"name": "page",
"id": "page",
"file": "angular/api-gatsby/generators/page"
}
]
},
{
"id": "executors",
"name": "Executors / Builders",
"itemList": [
{
"name": "build",
"id": "build",
"file": "angular/api-gatsby/executors/build"
},
{
"name": "server",
"id": "server",
"file": "angular/api-gatsby/executors/server"
}
]
}
]
},
{
"name": "Nx Plugin",
"id": "nx-plugin",
"itemList": [
{
"id": "overview",
"name": "Overview",
"searchResultsName": "@nrwl/nx-plugin Overview",
"file": "shared/nx-plugin"
},
{
"id": "generators",
"name": "Generators",
"itemList": [
{
"name": "executor",
"id": "executor",
"file": "angular/api-nx-plugin/generators/executor"
},
{
"name": "migration",
"id": "migration",
"file": "angular/api-nx-plugin/generators/migration"
},
{
"name": "plugin",
"id": "plugin",
"file": "angular/api-nx-plugin/generators/plugin"
},
{
"name": "generator",
"id": "schematic",
"file": "angular/api-nx-plugin/generators/generator"
}
]
},
{
"id": "executors",
"name": "Executors / Builders",
"itemList": [
{
"name": "e2e",
"id": "e2e",
"file": "angular/api-nx-plugin/executors/e2e"
}
]
}
]
} }
] ]
}, },
@ -2229,6 +2327,104 @@
"name": "run-commands executor", "name": "run-commands executor",
"id": "run-commands", "id": "run-commands",
"file": "node/api-workspace/executors/run-commands" "file": "node/api-workspace/executors/run-commands"
},
{
"name": "gatsby",
"id": "gatsby",
"itemList": [
{
"id": "overview",
"name": "Overview",
"searchResultsName": "@nrwl/gatsby Overview",
"file": "shared/gatsby-plugin"
},
{
"id": "generators",
"name": "Generators",
"itemList": [
{
"name": "application",
"id": "application",
"file": "react/api-gatsby/generators/application"
},
{
"name": "component",
"id": "component",
"file": "react/api-gatsby/generators/component"
},
{
"name": "page",
"id": "page",
"file": "react/api-gatsby/generators/page"
}
]
},
{
"id": "executors",
"name": "Executors / Builders",
"itemList": [
{
"name": "build",
"id": "build",
"file": "react/api-gatsby/executors/build"
},
{
"name": "server",
"id": "server",
"file": "react/api-gatsby/executors/server"
}
]
}
]
},
{
"name": "Nx Plugin",
"id": "nx-plugin",
"itemList": [
{
"id": "overview",
"name": "Overview",
"searchResultsName": "@nrwl/nx-plugin Overview",
"file": "shared/nx-plugin"
},
{
"id": "generators",
"name": "Generators",
"itemList": [
{
"name": "executor",
"id": "executor",
"file": "react/api-nx-plugin/generators/executor"
},
{
"name": "migration",
"id": "migration",
"file": "react/api-nx-plugin/generators/migration"
},
{
"name": "plugin",
"id": "plugin",
"file": "react/api-nx-plugin/generators/plugin"
},
{
"name": "generator",
"id": "schematic",
"file": "react/api-nx-plugin/generators/generator"
}
]
},
{
"id": "executors",
"name": "Executors / Builders",
"itemList": [
{
"name": "e2e",
"id": "e2e",
"file": "react/api-nx-plugin/executors/e2e"
}
]
}
]
} }
] ]
}, },
@ -2769,6 +2965,104 @@
"name": "Dependency Graph", "name": "Dependency Graph",
"id": "dependency-graph", "id": "dependency-graph",
"file": "shared/workspace/structure/dependency-graph" "file": "shared/workspace/structure/dependency-graph"
},
{
"name": "gatsby",
"id": "gatsby",
"itemList": [
{
"id": "overview",
"name": "Overview",
"searchResultsName": "@nrwl/gatsby Overview",
"file": "shared/gatsby-plugin"
},
{
"id": "generators",
"name": "Generators",
"itemList": [
{
"name": "application",
"id": "application",
"file": "node/api-gatsby/generators/application"
},
{
"name": "component",
"id": "component",
"file": "node/api-gatsby/generators/component"
},
{
"name": "page",
"id": "page",
"file": "node/api-gatsby/generators/page"
}
]
},
{
"id": "executors",
"name": "Executors / Builders",
"itemList": [
{
"name": "build",
"id": "build",
"file": "node/api-gatsby/executors/build"
},
{
"name": "server",
"id": "server",
"file": "node/api-gatsby/executors/server"
}
]
}
]
},
{
"name": "Nx Plugin",
"id": "nx-plugin",
"itemList": [
{
"id": "overview",
"name": "Overview",
"searchResultsName": "@nrwl/nx-plugin Overview",
"file": "shared/nx-plugin"
},
{
"id": "generators",
"name": "Generators",
"itemList": [
{
"name": "executor",
"id": "executor",
"file": "node/api-nx-plugin/generators/executor"
},
{
"name": "migration",
"id": "migration",
"file": "node/api-nx-plugin/generators/migration"
},
{
"name": "plugin",
"id": "plugin",
"file": "node/api-nx-plugin/generators/plugin"
},
{
"name": "generator",
"id": "schematic",
"file": "node/api-nx-plugin/generators/generator"
}
]
},
{
"id": "executors",
"name": "Executors / Builders",
"itemList": [
{
"name": "e2e",
"id": "e2e",
"file": "node/api-nx-plugin/executors/e2e"
}
]
}
]
} }
] ]
}, },

View File

@ -0,0 +1,48 @@
# build
Build a Gatsby app
Properties can be configured in workspace.json when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/node/guides/cli.
## Properties
### color
Default: `true`
Type: `boolean`
Enable colored terminal output.
### graphqlTracing
Type: `boolean`
Trace every graphql resolver, may have performance implications.
### openTracingConfigFile
Type: `string`
Tracer configuration file (OpenTracing compatible).
### prefixPaths
Type: `boolean`
Build site with link paths prefixed (set pathPrefix in your config).
### profile
Type: `boolean`
Build site with react profiling.
### uglify
Default: `true`
Type: `boolean`
Build site without uglifying JS bundles (true by default).

View File

@ -0,0 +1,44 @@
# server
Starts server for app
Properties can be configured in workspace.json when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/node/guides/cli.
## Properties
### buildTarget
Type: `string`
Target which builds the application
### host
Default: `localhost`
Type: `string`
Host to listen on.
### https
Default: `false`
Type: `boolean`
Serve using HTTPS.
### open
Type: `boolean`
Open the site in your (default) browser for you.
### port
Default: `4200`
Type: `number`
Port to listen on.

View File

@ -0,0 +1,89 @@
# application
Create an 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/gatsby:application ...
```
Show what will be generated without writing to disk:
```bash
nx g application ... --dry-run
```
## Options
### directory
Alias(es): d
Type: `string`
A directory where the project is placed
### e2eTestRunner
Default: `cypress`
Type: `string`
Possible values: `cypress`, `none`
Adds the specified e2e test runner
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files
### name
Type: `string`
### style
Alias(es): s
Default: `css`
Type: `string`
Possible values: `css`, `scss`, `styl`, `less`, `styled-components`, `@emotion/styled`, `none`
The file extension to be used for style files.
### tags
Alias(es): t
Type: `string`
Add tags to the project (used for linting)
### unitTestRunner
Default: `jest`
Type: `string`
Possible values: `jest`, `none`
Adds the specified unit test runner

View File

@ -0,0 +1,107 @@
# component
Create a component
## Usage
```bash
nx generate component ...
```
By default, Nx will search for `component` in the default collection provisioned in `workspace.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/gatsby:component ...
```
Show what will be generated without writing to disk:
```bash
nx g component ... --dry-run
```
### Examples
Generate a component in the mylib library:
```bash
nx g component my-component --project=mylib
```
Generate a class component in the mylib library:
```bash
nx g component my-component --project=mylib --classComponent
```
## Options
### directory
Alias(es): d
Type: `string`
Create the component under this directory (can be nested).
### export
Alias(es): e
Default: `false`
Type: `boolean`
When true, the component is exported from the project index.ts (if it exists).
### flat
Default: `false`
Type: `boolean`
Create component at the source root rather than its own directory.
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files.
### name
Type: `string`
The name of the component.
### project
Alias(es): p
Type: `string`
The name of the project.
### skipTests
Default: `false`
Type: `boolean`
When true, does not create "spec.ts" test files for the new component.
### style
Alias(es): s
Default: `css`
Type: `string`
Possible values: `css`, `scss`, `styl`, `less`, `styled-components`, `@emotion/styled`, `none`
The file extension to be used for style files.

View File

@ -0,0 +1,107 @@
# page
Create a page
## Usage
```bash
nx generate page ...
```
By default, Nx will search for `page` in the default collection provisioned in `workspace.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/gatsby:page ...
```
Show what will be generated without writing to disk:
```bash
nx g page ... --dry-run
```
### Examples
Generate a page in the mylib library:
```bash
nx g page my-page --project=mylib
```
Generate a class component in the mylib library:
```bash
nx g page my-page --project=mylib --classComponent
```
## Options
### directory
Alias(es): d
Type: `string`
Create the component under this directory (can be nested).
### export
Alias(es): e
Default: `false`
Type: `boolean`
When true, the component is exported from the project index.ts (if it exists).
### flat
Default: `false`
Type: `boolean`
Create component at the source root rather than its own directory.
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files.
### name
Type: `string`
The name of the component.
### project
Alias(es): p
Type: `string`
The name of the project.
### skipTests
Default: `false`
Type: `boolean`
When true, does not create "spec.ts" test files for the new component.
### style
Alias(es): s
Default: `css`
Type: `string`
Possible values: `css`, `scss`, `styl`, `less`, `styled-components`, `@emotion/styled`, `none`
The file extension to be used for style files.

View File

@ -2,6 +2,7 @@
"angular", "angular",
"cypress", "cypress",
"express", "express",
"gatsby",
"jest", "jest",
"linter", "linter",
"nest", "nest",

View File

@ -2,6 +2,7 @@
"angular", "angular",
"cypress", "cypress",
"express", "express",
"gatsby",
"jest", "jest",
"nest", "nest",
"next", "next",

View File

@ -0,0 +1,48 @@
# build
Build a Gatsby app
Properties can be configured in workspace.json when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/react/guides/cli.
## Properties
### color
Default: `true`
Type: `boolean`
Enable colored terminal output.
### graphqlTracing
Type: `boolean`
Trace every graphql resolver, may have performance implications.
### openTracingConfigFile
Type: `string`
Tracer configuration file (OpenTracing compatible).
### prefixPaths
Type: `boolean`
Build site with link paths prefixed (set pathPrefix in your config).
### profile
Type: `boolean`
Build site with react profiling.
### uglify
Default: `true`
Type: `boolean`
Build site without uglifying JS bundles (true by default).

View File

@ -0,0 +1,44 @@
# server
Starts server for app
Properties can be configured in workspace.json when defining the executor, or when invoking it.
Read more about how to use executors and the CLI here: https://nx.dev/react/guides/cli.
## Properties
### buildTarget
Type: `string`
Target which builds the application
### host
Default: `localhost`
Type: `string`
Host to listen on.
### https
Default: `false`
Type: `boolean`
Serve using HTTPS.
### open
Type: `boolean`
Open the site in your (default) browser for you.
### port
Default: `4200`
Type: `number`
Port to listen on.

View File

@ -0,0 +1,89 @@
# application
Create an 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/gatsby:application ...
```
Show what will be generated without writing to disk:
```bash
nx g application ... --dry-run
```
## Options
### directory
Alias(es): d
Type: `string`
A directory where the project is placed
### e2eTestRunner
Default: `cypress`
Type: `string`
Possible values: `cypress`, `none`
Adds the specified e2e test runner
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files
### name
Type: `string`
### style
Alias(es): s
Default: `css`
Type: `string`
Possible values: `css`, `scss`, `styl`, `less`, `styled-components`, `@emotion/styled`, `none`
The file extension to be used for style files.
### tags
Alias(es): t
Type: `string`
Add tags to the project (used for linting)
### unitTestRunner
Default: `jest`
Type: `string`
Possible values: `jest`, `none`
Adds the specified unit test runner

View File

@ -0,0 +1,107 @@
# component
Create a component
## Usage
```bash
nx generate component ...
```
By default, Nx will search for `component` in the default collection provisioned in `workspace.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/gatsby:component ...
```
Show what will be generated without writing to disk:
```bash
nx g component ... --dry-run
```
### Examples
Generate a component in the mylib library:
```bash
nx g component my-component --project=mylib
```
Generate a class component in the mylib library:
```bash
nx g component my-component --project=mylib --classComponent
```
## Options
### directory
Alias(es): d
Type: `string`
Create the component under this directory (can be nested).
### export
Alias(es): e
Default: `false`
Type: `boolean`
When true, the component is exported from the project index.ts (if it exists).
### flat
Default: `false`
Type: `boolean`
Create component at the source root rather than its own directory.
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files.
### name
Type: `string`
The name of the component.
### project
Alias(es): p
Type: `string`
The name of the project.
### skipTests
Default: `false`
Type: `boolean`
When true, does not create "spec.ts" test files for the new component.
### style
Alias(es): s
Default: `css`
Type: `string`
Possible values: `css`, `scss`, `styl`, `less`, `styled-components`, `@emotion/styled`, `none`
The file extension to be used for style files.

View File

@ -0,0 +1,107 @@
# page
Create a page
## Usage
```bash
nx generate page ...
```
By default, Nx will search for `page` in the default collection provisioned in `workspace.json`.
You can specify the collection explicitly as follows:
```bash
nx g @nrwl/gatsby:page ...
```
Show what will be generated without writing to disk:
```bash
nx g page ... --dry-run
```
### Examples
Generate a page in the mylib library:
```bash
nx g page my-page --project=mylib
```
Generate a class component in the mylib library:
```bash
nx g page my-page --project=mylib --classComponent
```
## Options
### directory
Alias(es): d
Type: `string`
Create the component under this directory (can be nested).
### export
Alias(es): e
Default: `false`
Type: `boolean`
When true, the component is exported from the project index.ts (if it exists).
### flat
Default: `false`
Type: `boolean`
Create component at the source root rather than its own directory.
### js
Default: `false`
Type: `boolean`
Generate JavaScript files rather than TypeScript files.
### name
Type: `string`
The name of the component.
### project
Alias(es): p
Type: `string`
The name of the project.
### skipTests
Default: `false`
Type: `boolean`
When true, does not create "spec.ts" test files for the new component.
### style
Alias(es): s
Default: `css`
Type: `string`
Possible values: `css`, `scss`, `styl`, `less`, `styled-components`, `@emotion/styled`, `none`
The file extension to be used for style files.

View File

@ -2,6 +2,7 @@
"angular", "angular",
"cypress", "cypress",
"express", "express",
"gatsby",
"jest", "jest",
"linter", "linter",
"nest", "nest",

View File

@ -2,6 +2,7 @@
"angular", "angular",
"cypress", "cypress",
"express", "express",
"gatsby",
"jest", "jest",
"nest", "nest",
"next", "next",

View File

@ -0,0 +1,73 @@
# Next.js Plugin
The Nx Plugin for Next.js contains executors and generators for managing Next.js applications and libraries within an Nx workspace. It provides:
- Scaffolding for creating, building, serving, linting, and testing Next.js applications.
- Integration with building, serving, and exporting a Next.js application.
- Integration with React libraries within the workspace.
## Installing the Next.js Plugin
Installing the Next plugin to a workspace can be done with the following:
```shell script
yarn add -D @nrwl/next
```
```shell script
npm install -D @nrwl/next
```
## Applications
Generating new applications can be done with the following:
```shell script
nx generate @nrwl/next:application <name>
```
This creates the following app structure:
```treeview
myorg/
├── apps/
│   ├── myapp/
│   │   ├── pages/
│   │   │   ├── index.css
│   │   │   └── index.tsx
│   │   ├── jest.conf.js
│   │   ├── tsconfig.json
│   │   ├── tsconfig.spec.json
│   │   └── .eslintrc.json
│   └── myapp-e2e/
│   │   ├── src/
│   │   │   ├── integrations/
│   │   │   │   └── app.spec.ts
│   │   │   ├── fixtures/
│   │   │   ├── plugins/
│   │   │   └── support/
│   │   ├── cypress.json
│   │   ├── tsconfig.e2e.json
│   │   └── .eslintrc.json
├── libs/
├── workspace.json
├── nx.json
├── package.json
├── tools/
├── tsconfig.json
└── .eslintrc.json
```
## See Also
- [Using Next.js](https://nextjs.org/docs/getting-started)
## Executors / Builders
- [build](/{{framework}}/plugins/next/executors/build) - Builds a Next.js application
- [dev-server](/{{framework}}/plugins/next/executors/dev-server) - Builds and serves a Next.js application
- [export](/{{framework}}/plugins/next/executors/package) - Export a Next.js app. The exported application is located at `dist/$outputPath/exported`
## Generators
- [application](/{{framework}}/plugins/next/generators/application) - Create an Next.js application

View File

@ -1,21 +1,21 @@
# Next.js Plugin # Gatsby Plugin
The Nx Plugin for Next.js contains executors and generators for managing Next.js applications and libraries within an Nx workspace. It provides: The Nx Plugin for Gatsby contains executors and generators for managing Gatsby applications and libraries within an Nx workspace. It provides:
- Scaffolding for creating, building, serving, linting, and testing Next.js applications. - Scaffolding for creating, building, serving, linting, and testing Gatsby applications.
- Integration with building, serving, and exporting a Next.js application. - Integration with building, serving, and exporting a Gatsby application.
- Integration with React libraries within the workspace. - Integration with React libraries within the workspace.
## Installing the Next.js Plugin ## Installing the Gatsby Plugin
Installing the Next plugin to a workspace can be done with the following: Installing the Gatsby plugin to a workspace can be done with the following:
```shell script ```shell script
yarn add -D @nrwl/next yarn add -D @nrwl/gatsby
``` ```
```shell script ```shell script
npm install -D @nrwl/next npm install -D @nrwl/gatsby
``` ```
## Applications ## Applications
@ -23,7 +23,7 @@ npm install -D @nrwl/next
Generating new applications can be done with the following: Generating new applications can be done with the following:
```shell script ```shell script
nx generate @nrwl/next:application <name> nx generate @nrwl/gatsby:application <name>
``` ```
This creates the following app structure: This creates the following app structure:
@ -32,11 +32,13 @@ This creates the following app structure:
myorg/ myorg/
├── apps/ ├── apps/
│   ├── myapp/ │   ├── myapp/
│   │   ├── pages/ │   │   ├── src/
│   │   │   ├── index.css │   │   │   ├── pages/
│   │   │   └── index.tsx │   │   │   │   ├── index.module.css
│   │   │   │   └── index.tsx
│   │   ├── jest.conf.js │   │   ├── jest.conf.js
│   │   ├── tsconfig.json │   │   ├── tsconfig.json
│   │   ├── tsconfig.app.json
│   │   ├── tsconfig.spec.json │   │   ├── tsconfig.spec.json
│   │   └── .eslintrc.json │   │   └── .eslintrc.json
│   └── myapp-e2e/ │   └── myapp-e2e/
@ -60,14 +62,15 @@ myorg/
## See Also ## See Also
- [Using Next.js](https://nextjs.org/docs/getting-started) - [Using Gatsby](https://www.gatsbyjs.com/docs/quick-start/)
## Executors / Builders ## Executors / Builders
- [build](/{{framework}}/plugins/next/executors/build) - Builds a Next.js application - [build](/{{framework}}/plugins/gatsby/executors/build) - Builds a Gatsby application
- [dev-server](/{{framework}}/plugins/next/executors/dev-server) - Builds and serves a Next.js application - [server](/{{framework}}/plugins/gatsby/executors/server) - Builds and serves a Gatsby application
- [export](/{{framework}}/plugins/next/executors/package) - Export a Next.js app. The exported application is located at `dist/$outputPath/exported`
## Generators ## Generators
- [application](/{{framework}}/plugins/next/generators/application) - Create an Next.js application - [application](/{{framework}}/plugins/gatsby/generators/application) - Create a Gatsby application
- [component](/{{framework}}/plugins/gatsby/generators/component) - Create a Gatsby component
- [page](/{{framework}}/plugins/gatsby/generators/page) - Create a Gatsby page

10
e2e/gatsby/jest.config.js Normal file
View File

@ -0,0 +1,10 @@
module.exports = {
preset: '../../jest.preset.js',
transform: {
'^.+\\.[tj]sx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: { 'ts-jest': { tsConfig: '<rootDir>/tsconfig.spec.json' } },
displayName: 'e2e-next',
};

View File

@ -0,0 +1,59 @@
import {
checkFilesExist,
newProject,
runCLI,
runCLIAsync,
uniq,
updateFile,
} from '@nrwl/e2e/utils';
describe('Gatsby Applications', () => {
let proj: string;
beforeEach(() => (proj = newProject()));
it('should generate a valid gatsby application', async () => {
const appName = uniq('app');
runCLI(`generate @nrwl/gatsby:app ${appName}`);
runCLI(`generate @nrwl/gatsby:component header --project ${appName}`);
checkFilesExist(
`apps/${appName}/package.json`,
`apps/${appName}/src/components/header.tsx`,
`apps/${appName}/src/components/header.spec.tsx`,
`apps/${appName}/src/pages/index.tsx`,
`apps/${appName}/src/pages/index.spec.tsx`
);
updateFile(`apps/${appName}/src/pages/index.tsx`, (content) => {
let updated = `import Header from '../components/header';\n${content}`;
updated = updated.replace('<main>', '<Header /><main>');
return updated;
});
let result = runCLI(`build ${appName}`);
expect(result).toContain('Done building in');
result = runCLI(`lint ${appName}`);
expect(result).not.toMatch('Lint errors found in the listed files');
const testResults = await runCLIAsync(`test ${appName}`);
expect(testResults.combinedOutput).toContain(
'Test Suites: 2 passed, 2 total'
);
}, 120000);
test('supports --js option', async () => {
const app = uniq('app');
runCLI(`generate @nrwl/gatsby:app ${app} --js`);
checkFilesExist(
`apps/${app}/package.json`,
`apps/${app}/src/pages/index.js`,
`apps/${app}/src/pages/index.spec.js`
);
const result = runCLI(`build ${app}`);
expect(result).toContain('Done building in');
}, 120000);
});

13
e2e/gatsby/tsconfig.json Normal file
View File

@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"types": ["node", "jest"]
},
"include": [],
"files": [],
"references": [
{
"path": "./tsconfig.spec.json"
}
]
}

View File

@ -0,0 +1,16 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"**/*.test.ts",
"**/*.spec.ts",
"**/*.spec.tsx",
"**/*.spec.js",
"**/*.spec.jsx",
"**/*.d.ts"
]
}

View File

@ -139,6 +139,7 @@ export function newProject({ name = uniq('proj') } = {}): string {
`@nrwl/express`, `@nrwl/express`,
`@nrwl/nest`, `@nrwl/nest`,
`@nrwl/next`, `@nrwl/next`,
`@nrwl/gatsby`,
`@nrwl/node`, `@nrwl/node`,
`@nrwl/react`, `@nrwl/react`,
`@nrwl/storybook`, `@nrwl/storybook`,

BIN
images/nx-gatsby.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -18,5 +18,6 @@ module.exports = {
'<rootDir>/packages/create-nx-plugin', '<rootDir>/packages/create-nx-plugin',
'<rootDir>/packages/cli', '<rootDir>/packages/cli',
'<rootDir>/packages/angular', '<rootDir>/packages/angular',
'<rootDir>/packages/gatsby',
], ],
}; };

View File

@ -124,6 +124,10 @@
"tags": [], "tags": [],
"implicitDependencies": ["cypress"] "implicitDependencies": ["cypress"]
}, },
"e2e-gatsby": {
"tags": [],
"implicitDependencies": ["gatsby"]
},
"e2e-jest": { "e2e-jest": {
"tags": [], "tags": [],
"implicitDependencies": ["jest"] "implicitDependencies": ["jest"]
@ -166,6 +170,9 @@
"dep-graph-client-e2e": { "dep-graph-client-e2e": {
"tags": [], "tags": [],
"implicitDependencies": ["dep-graph-client"] "implicitDependencies": ["dep-graph-client"]
},
"gatsby": {
"tags": []
} }
}, },
"affected": { "affected": {

View File

@ -30,6 +30,10 @@ const presetOptions: { value: Preset; name: string }[] = [
value: Preset.NextJs, value: Preset.NextJs,
name: 'next.js [a workspace with a single Next.js application]', name: 'next.js [a workspace with a single Next.js application]',
}, },
{
value: Preset.Gatsby,
name: 'gatsby [a workspace with a single Gatsby application]',
},
{ {
value: Preset.Nest, value: Preset.Nest,
name: 'nest [a workspace with a single Nest application]', name: 'nest [a workspace with a single Nest application]',
@ -480,6 +484,7 @@ function pointToTutorialAndCourse(preset: Preset) {
case Preset.React: case Preset.React:
case Preset.ReactWithExpress: case Preset.ReactWithExpress:
case Preset.NextJs: case Preset.NextJs:
case Preset.Gatsby:
output.addVerticalSeparator(); output.addVerticalSeparator();
output.note({ output.note({
title: title, title: title,

View File

@ -0,0 +1,5 @@
{
"extends": "../../.eslintrc",
"rules": {},
"ignorePatterns": ["!**/*"]
}

40
packages/gatsby/README.md Normal file
View File

@ -0,0 +1,40 @@
<p align="center"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-gatsby.png" width="600"></p>
{{links}}
<hr>
# Gatsby Plugin for Nx
{{what-is-nx}}
{{getting-started}}
```
? Workspace name (e.g., org name) happyorg
? What to create in the new workspace gatsby [a workspace with a single Gatsby application]
? Application name myapp
? Default stylesheet format CSS
```
You can also select `empty` and add `@nrwl/gatsby` plugin using yarn or npm, and then generate a new express app using `nx g @nrwl/gatsby:app myapp`.
If it's your first Nx project, the command will recommend you to install the `nx` package globally, so you can invoke `nx` directly without going through yarn or npm.
### Serving Application
- Run `nx serve myapp` to serve the newly generated application!
- Run `nx test myapp` to test it.
- Run `nx e2e myapp` to run e2e tests for your application.
You are good to go!
## Quick Start Videos
<a href="https://www.youtube.com/watch?v=E188J7E_MDU" target="_blank">
<p align="center"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-react-video.png" width="350"></p>
</a>
- [Nx Dev Tools for Monorepos, In-Depth Explainer (React)](https://www.youtube.com/watch?v=jCf92IyR-GE)
{{resources}}

9
packages/gatsby/babel.ts Normal file
View File

@ -0,0 +1,9 @@
/*
* Babel preset to provide Gatsby support for Nx.
*/
module.exports = function (api, options) {
api.assertVersion(7);
return {
presets: [[require.resolve('babel-preset-gatsby'), { useBuiltIns: true }]],
};
};

View File

@ -0,0 +1,15 @@
{
"$schema": "@angular-devkit/architect/src/builders-schema.json",
"builders": {
"build": {
"implementation": "./src/builders/build/builder",
"schema": "./src/builders/build/schema.json",
"description": "Build a Gatsby app"
},
"server": {
"implementation": "./src/builders/server/builder",
"schema": "./src/builders/server/schema.json",
"description": "Starts server for app"
}
}
}

View File

@ -0,0 +1,29 @@
{
"name": "nx/gatsby",
"version": "0.1",
"extends": ["@nrwl/react"],
"schematics": {
"init": {
"factory": "./src/schematics/init/init",
"schema": "./src/schematics/init/schema.json",
"description": "Initialize the @nrwl/gatsby plugin",
"hidden": true
},
"application": {
"factory": "./src/schematics/application/application",
"schema": "./src/schematics/application/schema.json",
"aliases": ["app"],
"description": "Create an application"
},
"component": {
"factory": "./src/schematics/component/component",
"schema": "./src/schematics/component/schema.json",
"description": "Create a component"
},
"page": {
"factory": "./src/schematics/page/page",
"schema": "./src/schematics/page/schema.json",
"description": "Create a page"
}
}
}

3
packages/gatsby/index.ts Normal file
View File

@ -0,0 +1,3 @@
export { applicationGenerator } from './src/schematics/application/application';
export { componentGenerator } from './src/schematics/component/component';
export { pageGenerator } from './src/schematics/page/page';

View File

@ -0,0 +1,9 @@
module.exports = {
preset: '../../jest.preset.js',
transform: {
'^.+\\.[tj]sx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
globals: { 'ts-jest': { tsConfig: '<rootDir>/tsconfig.spec.json' } },
displayName: 'gatsby',
};

View File

@ -0,0 +1,41 @@
{
"name": "@nrwl/gatsby",
"version": "0.0.1",
"description": "Gatsby Plugin for Nx",
"repository": {
"type": "git",
"url": "git+https://github.com/nrwl/nx.git"
},
"keywords": [
"Monorepo",
"Node",
"Express",
"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"
},
"dependencies": {
"@angular-devkit/core": "~11.0.1",
"@angular-devkit/schematics": "~11.0.1",
"@nrwl/cypress": "*",
"@nrwl/devkit": "*",
"@nrwl/jest": "*",
"@nrwl/node": "*",
"@nrwl/react": "*",
"gatsby-cli": "^2.17.1"
}
}

View File

@ -0,0 +1,3 @@
module.exports = {
plugins: [`gatsby-plugin-typescript`],
};

View File

@ -0,0 +1,26 @@
import * as path from 'path';
import { appRootPath as workspaceRoot } from '@nrwl/workspace/src/utils/app-root';
import { readJsonFile } from '@nrwl/workspace';
function onCreateBabelConfig({ actions }, options) {
const tsConfig = readJsonFile(path.join(workspaceRoot, 'tsconfig.base.json'));
const tsConfigPaths: { [key: string]: Array<string> } =
tsConfig.compilerOptions.paths;
const paths = Object.entries(tsConfigPaths).reduce((result, [key, paths]) => {
return {
...result,
[key]: paths.map((p) => path.join(workspaceRoot, p)),
};
}, {});
actions.setBabelPlugin({
name: require.resolve(`babel-plugin-module-resolver`),
options: {
root: ['./src'],
alias: paths,
},
});
}
export { onCreateBabelConfig };

View File

@ -0,0 +1,10 @@
{
"name": "nx-gatsby-ext-plugin",
"version": "1.0.0",
"main": "gatsby-config.js",
"author": "max koretskyi",
"license": "MIT",
"peerDependencies": {
"gatsby": "^2.6.0"
}
}

View File

@ -0,0 +1,93 @@
import {
BuilderContext,
BuilderOutput,
createBuilder,
} from '@angular-devkit/architect';
import { fork } from 'child_process';
import { join } from 'path';
import { from, Observable } from 'rxjs';
import { concatMap } from 'rxjs/operators';
import { GatsbyPluginBuilderSchema } from './schema';
import { getProjectRoot } from '../../utils/get-project-root';
export function runBuilder(
options: GatsbyPluginBuilderSchema,
context: BuilderContext
): Observable<BuilderOutput> {
return from(getProjectRoot(context)).pipe(
concatMap((projectRoot) => {
return new Observable<BuilderOutput>((subscriber) => {
runGatsbyBuild(context.workspaceRoot, projectRoot, options)
.then(() => {
subscriber.next({
success: true,
});
subscriber.complete();
})
.catch((err) => {
context.logger.error('Error during build', err);
subscriber.next({
success: false,
});
subscriber.complete();
});
});
})
);
}
export function runGatsbyBuild(
workspaceRoot: string,
projectRoot: string,
options: GatsbyPluginBuilderSchema
) {
return new Promise((resolve, reject) => {
const cp = fork(
require.resolve('gatsby-cli'),
['build', ...createGatsbyBuildOptions(options)],
{
cwd: join(workspaceRoot, projectRoot),
}
);
cp.on('error', (err) => {
reject(err);
});
cp.on('exit', (code) => {
if (code === 0) {
resolve();
} else {
reject(code);
}
});
});
}
function createGatsbyBuildOptions(options: GatsbyPluginBuilderSchema) {
return Object.keys(options).reduce((acc, k) => {
const val = options[k];
if (typeof val === 'undefined') return acc;
switch (k) {
case 'prefixPaths':
return val ? acc.concat(`--prefix-paths`) : acc;
case 'uglify':
return val ? acc : acc.concat('--no-uglify');
case 'color':
return val ? acc : acc.concat('--no-color');
case 'profile':
return val ? acc.concat('--profile') : acc;
case 'openTracingConfigFile':
return val ? acc.concat([`--open-tracing-config-file`, val]) : acc;
case 'graphqlTracing':
return val ? acc.concat('--graphql-tracing') : acc;
case 'serve':
case 'host':
case 'port':
default:
return acc;
}
}, []);
}
export default createBuilder(runBuilder);

View File

@ -0,0 +1,10 @@
import { JsonObject } from '@angular-devkit/core';
export interface GatsbyPluginBuilderSchema extends JsonObject {
prefixPaths?: boolean;
uglify: boolean;
profile?: boolean;
openTracingConfigFile?: string;
graphqlTracing?: boolean;
color: boolean;
}

View File

@ -0,0 +1,35 @@
{
"$schema": "http://json-schema.org/schema",
"title": "GatsbyPlugin builder",
"description": "",
"type": "object",
"properties": {
"prefixPaths": {
"type": "boolean",
"description": "Build site with link paths prefixed (set pathPrefix in your config)."
},
"uglify": {
"type": "boolean",
"description": "Build site without uglifying JS bundles (true by default).",
"default": true
},
"profile": {
"type": "boolean",
"description": "Build site with react profiling."
},
"openTracingConfigFile": {
"type": "string",
"description": "Tracer configuration file (OpenTracing compatible)."
},
"graphqlTracing": {
"type": "boolean",
"description": "Trace every graphql resolver, may have performance implications."
},
"color": {
"type": "boolean",
"description": "Enable colored terminal output.",
"default": true
}
},
"required": []
}

View File

@ -0,0 +1,161 @@
import {
BuilderContext,
BuilderOutput,
createBuilder,
targetFromTargetString,
} from '@angular-devkit/architect';
import { fork } from 'child_process';
import { join } from 'path';
import { from, Observable, of } from 'rxjs';
import { catchError, concatMap, withLatestFrom } from 'rxjs/operators';
import { GatsbyPluginBuilderSchema } from './schema';
import { runGatsbyBuild } from '../build/builder';
import { GatsbyPluginBuilderSchema as BuildBuilderSchema } from '../build/schema';
import { getProjectRoot } from '../../utils/get-project-root';
export function runBuilder(
options: GatsbyPluginBuilderSchema,
context: BuilderContext
): Observable<BuilderOutput> {
const buildTarget = targetFromTargetString(options.buildTarget);
const baseUrl = `${options.https ? 'https' : 'http'}://${options.host}:${
options.port
}`;
return from(getProjectRoot(context)).pipe(
concatMap((projectRoot) => {
return from(context.getTargetOptions(buildTarget)).pipe(
concatMap((buildOptions: BuildBuilderSchema) => {
return new Observable<BuilderOutput>((subscriber) => {
if (context.target.configuration === 'production') {
runGatsbyBuild(context.workspaceRoot, projectRoot, buildOptions)
.then(() =>
runGatsbyServe(context.workspaceRoot, projectRoot, options)
)
.then(() => {
subscriber.next({
success: true,
});
})
.catch((err) => {
context.logger.error('Error during serve', err);
});
} else {
runGatsbyDevelop(
context.workspaceRoot,
projectRoot,
createGatsbyOptions(options)
)
.then((success) => {
subscriber.next({
baseUrl,
success,
});
})
.catch((err) => {
context.logger.error('Error during serve', err?.message);
subscriber.next({
success: false,
});
subscriber.complete();
});
}
});
}),
catchError((err) => {
context.logger.error(err);
return of({ success: false });
})
);
})
);
}
function createGatsbyOptions(options) {
return Object.keys(options).reduce((acc, k) => {
if (k === 'port' || k === 'host' || k === 'https' || k === 'open')
acc.push(`--${k}=${options[k]}`);
return acc;
}, []);
}
async function runGatsbyDevelop(workspaceRoot, projectRoot, options) {
return new Promise<boolean>((resolve, reject) => {
const cp = fork(require.resolve('gatsby-cli'), ['develop', ...options], {
cwd: join(workspaceRoot, projectRoot),
env: {
...process.env,
},
stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
});
// Ensure the child process is killed when the parent exits
process.on('exit', () => cp.kill());
cp.on('message', ({ action }) => {
if (
action?.type === 'ACTIVITY_END' &&
action?.payload?.status === 'SUCCESS' &&
action?.payload?.id === 'webpack-develop'
) {
resolve(true);
}
});
cp.on('error', (err) => {
reject(err);
});
cp.on('exit', (code) => {
if (code !== 0) {
reject(code);
}
});
});
}
function runGatsbyServe(
workspaceRoot: string,
projectRoot: string,
options: GatsbyPluginBuilderSchema
) {
return new Promise((resolve, reject) => {
const cp = fork(
require.resolve('gatsby-cli'),
['serve', ...createGatsbyServeOptions(options)],
{ cwd: join(workspaceRoot, projectRoot) }
);
cp.on('error', (err) => {
reject(err);
});
cp.on('exit', (code) => {
if (code === 0) {
resolve(code);
} else {
reject(code);
}
});
});
}
function createGatsbyServeOptions(options: GatsbyPluginBuilderSchema) {
return Object.keys(options).reduce((acc, k) => {
const val = options[k];
if (typeof val === 'undefined') return acc;
switch (k) {
case 'host':
return val ? acc.concat([`--host`, val]) : acc;
case 'open':
return val ? acc.concat(`--open`) : acc;
case 'prefixPaths':
return val ? acc.concat(`--prefix-paths`) : acc;
case 'port':
return val ? acc.concat([`--port`, val]) : acc;
default:
return acc;
}
}, []);
}
export default createBuilder(runBuilder);

View File

@ -0,0 +1,9 @@
import { JsonObject } from '@angular-devkit/core';
export interface GatsbyPluginBuilderSchema extends JsonObject {
buildTarget: string;
host: string;
port: string;
open: boolean;
https: boolean;
}

View File

@ -0,0 +1,31 @@
{
"title": "Gatsby development server",
"description": "Gatsby development server",
"type": "object",
"properties": {
"buildTarget": {
"type": "string",
"description": "Target which builds the application"
},
"port": {
"type": "number",
"description": "Port to listen on.",
"default": 4200
},
"host": {
"type": "string",
"description": "Host to listen on.",
"default": "localhost"
},
"https": {
"type": "boolean",
"description": "Serve using HTTPS.",
"default": false
},
"open": {
"type": "boolean",
"description": "Open the site in your (default) browser for you."
}
},
"required": []
}

View File

View File

@ -0,0 +1,320 @@
import { Tree } from '@angular-devkit/schematics';
import { NxJson, readJsonInTree } from '@nrwl/workspace';
import { createEmptyWorkspace } from '@nrwl/workspace/testing';
import { runSchematic } from '../../utils/testing';
describe('app', () => {
let appTree: Tree;
beforeEach(() => {
appTree = Tree.empty();
appTree = createEmptyWorkspace(appTree);
});
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.projects).toEqual({
'my-app': {
tags: ['one', 'two'],
},
'my-app-e2e': {
tags: [],
implicitDependencies: ['my-app'],
},
});
});
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/tsconfig.app.json')).toBeTruthy();
expect(tree.exists('apps/my-app/src/pages/index.tsx')).toBeTruthy();
expect(tree.exists('apps/my-app/src/pages/index.spec.tsx')).toBeTruthy();
expect(tree.exists('apps/my-app/src/pages/index.module.css')).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/src/pages/index.module.scss')
).toBeTruthy();
const indexContent = result
.read('apps/my-app/src/pages/index.tsx')
.toString();
expect(indexContent).toContain(
`import styles from './index.module.scss'`
);
});
});
describe('--style less', () => {
it('should generate less styles', async () => {
const result = await runSchematic(
'app',
{ name: 'myApp', style: 'less' },
appTree
);
expect(
result.exists('apps/my-app/src/pages/index.module.less')
).toBeTruthy();
const indexContent = result
.read('apps/my-app/src/pages/index.tsx')
.toString();
expect(indexContent).toContain(
`import styles from './index.module.less'`
);
});
});
describe('--style styl', () => {
it('should generate stylus styles', async () => {
const result = await runSchematic(
'app',
{ name: 'myApp', style: 'styl' },
appTree
);
expect(
result.exists('apps/my-app/src/pages/index.module.styl')
).toBeTruthy();
const indexContent = result
.read('apps/my-app/src/pages/index.tsx')
.toString();
expect(indexContent).toContain(
`import styles from './index.module.styl'`
);
});
});
describe('--style styled-components', () => {
it('should generate scss styles', async () => {
const result = await runSchematic(
'app',
{ name: 'myApp', style: 'styled-components' },
appTree
);
expect(
result.exists('apps/my-app/src/pages/index.module.styled-components')
).toBeFalsy();
const indexContent = result
.read('apps/my-app/src/pages/index.tsx')
.toString();
expect(indexContent).not.toContain(`import styles from './index.module`);
expect(indexContent).toContain(`import styled from 'styled-components'`);
});
});
describe('--style @emotion/styled', () => {
it('should generate emotion styles', async () => {
const result = await runSchematic(
'app',
{ name: 'myApp', style: '@emotion/styled' },
appTree
);
expect(
result.exists('apps/my-app/src/pages/index.module.styled-components')
).toBeFalsy();
const indexContent = result
.read('apps/my-app/src/pages/index.tsx')
.toString();
expect(indexContent).not.toContain(`import styles from './index.module`);
expect(indexContent).toContain(`import styled from '@emotion/styled'`);
});
});
// TODO: We should also add styled-jsx support for Gatsby to keep React plugins consistent.
// This needs to be here before Nx 12 is released.
xdescribe('--style styled-jsx', () => {
it('should use <style jsx> in index page', async () => {
const result = await runSchematic(
'app',
{ name: 'myApp', style: 'styled-jsx' },
appTree
);
const indexContent = result
.read('apps/my-app/src/pages/index.tsx')
.toString();
const babelJestConfig = readJsonInTree(
result,
'apps/my-app/babel-jest.config.json'
);
expect(indexContent).toMatch(/<style jsx>/);
expect(babelJestConfig.plugins).toContain('styled-jsx/babel');
expect(
result.exists('apps/my-app/src/pages/index.module.styled-jsx')
).toBeFalsy();
expect(indexContent).not.toContain(`import styles from './index.module`);
expect(indexContent).not.toContain(
`import styled from 'styled-components'`
);
});
});
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'],`
);
});
it('should setup jest with SVGR support', async () => {
const tree = await runSchematic(
'app',
{
name: 'my-app',
},
appTree
);
expect(tree.readContent('apps/my-app/jest.config.js')).toContain(
`'^(?!.*\\\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest'`
);
});
it('should set up the nrwl gatsby 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/gatsby:build');
expect(architectConfig.build.options).toMatchObject({
outputPath: 'apps/my-app/public',
});
});
it('should set up the nrwl gatsby server 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/gatsby:server');
expect(architectConfig.serve.options).toMatchObject({
buildTarget: 'my-app:build',
});
expect(architectConfig.serve.configurations).toEqual({
production: { buildTarget: 'my-app:build:production' },
});
});
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('jest.config.js')).toBeFalsy();
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();
});
});
it('should generate an index component', async () => {
const tree = await runSchematic('app', { name: 'myApp' }, appTree);
const appContent = tree.read('apps/my-app/src/pages/index.tsx').toString();
expect(appContent).not.toMatch(/extends Component/);
});
it('should add .eslintrc.json and dependencies', async () => {
const tree = await runSchematic(
'app',
{ name: 'myApp', linter: 'eslint' },
appTree
);
const eslintJson = readJsonInTree(tree, '/apps/my-app/.eslintrc.json');
const packageJson = readJsonInTree(tree, '/package.json');
expect(eslintJson.extends).toEqual(
expect.arrayContaining(['plugin:@nrwl/nx/react'])
);
expect(packageJson).toMatchObject({
devDependencies: {
'eslint-plugin-react': expect.anything(),
'eslint-plugin-react-hooks': expect.anything(),
},
});
});
describe('--js', () => {
it('generates JS files', async () => {
const tree = await runSchematic(
'app',
{ name: 'myApp', js: true },
appTree
);
expect(tree.exists('apps/my-app/src/pages/index.js')).toBeTruthy();
expect(tree.exists('apps/my-app/src/pages/index.spec.js')).toBeTruthy();
expect(tree.exists('apps/my-app/index.d.js')).toBeFalsy();
expect(tree.exists('apps/my-app/index.d.ts')).toBeFalsy();
const tsConfig = readJsonInTree(tree, 'apps/my-app/tsconfig.json');
expect(tsConfig.compilerOptions.allowJs).toEqual(true);
const tsConfigApp = readJsonInTree(tree, 'apps/my-app/tsconfig.app.json');
expect(tsConfigApp.include).toContain('**/*.js');
expect(tsConfigApp.exclude).toContain('**/*.spec.js');
});
});
});

View File

@ -0,0 +1,282 @@
import { join, normalize } from '@angular-devkit/core';
import {
apply,
chain,
externalSchematic,
filter,
mergeWith,
move,
noop,
Rule,
SchematicContext,
template,
Tree,
url,
} from '@angular-devkit/schematics';
import {
addLintFiles,
addProjectToNxJsonInTree,
formatFiles,
generateProjectLint,
Linter,
names,
offsetFromRoot,
projectRootDir,
ProjectType,
toFileName,
updateJsonInTree,
updateWorkspaceInTree,
} from '@nrwl/workspace';
import init from '../init/init';
import { GatsbyPluginSchematicSchema } from './schema';
import { appsDir } from '@nrwl/workspace/src/utils/ast-utils';
import { updateJestConfigContent } from '@nrwl/react/src/utils/jest-utils';
import {
toJS,
updateTsConfigsToJs,
} from '@nrwl/workspace/src/utils/rules/to-js';
import {
assertValidStyle,
extraEslintDependencies,
reactEslintJson,
} from '@nrwl/react';
import { addStyleDependencies } from '../../utils/styles';
import { wrapAngularDevkitSchematic } from '@nrwl/tao/src/commands/ngcli-adapter';
const projectType = ProjectType.Application;
interface NormalizedSchema extends GatsbyPluginSchematicSchema {
projectName: string;
projectRoot: string;
projectDirectory: string;
parsedTags: string[];
styledModule: null | string;
}
export default function (options: GatsbyPluginSchematicSchema): Rule {
const normalizedOptions = normalizeOptions(options);
return chain([
init({
...options,
skipFormat: true,
}),
addLintFiles(normalizedOptions.projectRoot, Linter.EsLint, {
localConfig: {
...reactEslintJson,
overrides: [
{
files: ['*.tsx', '*.ts'],
rules: {
'@typescript-eslint/camelcase': 'off',
},
},
],
},
extraPackageDeps: extraEslintDependencies,
}),
addProject(normalizedOptions),
addProjectToNxJsonInTree(normalizedOptions.projectName, {
tags: normalizedOptions.parsedTags,
}),
createApplicationFiles(normalizedOptions),
addStyleDependencies(options.style),
addJest(normalizedOptions),
updateJestConfig(normalizedOptions),
updateEslintConfig(normalizedOptions),
addCypress(normalizedOptions),
addPrettierIgnoreEntry(normalizedOptions),
addGitIgnoreEntry(normalizedOptions),
formatFiles(),
]);
}
function normalizeOptions(
options: GatsbyPluginSchematicSchema
): NormalizedSchema {
const name = toFileName(options.name);
const projectDirectory = options.directory
? `${toFileName(options.directory)}/${name}`
: name;
const projectName = projectDirectory.replace(new RegExp('/', 'g'), '-');
const projectRoot = `${projectRootDir(projectType)}/${projectDirectory}`;
const parsedTags = options.tags
? options.tags.split(',').map((s) => s.trim())
: [];
const styledModule = /^(css|scss|less|styl)$/.test(options.style)
? null
: options.style;
assertValidStyle(options.style);
return {
...options,
name,
styledModule,
projectName,
projectRoot,
projectDirectory,
parsedTags,
};
}
function createApplicationFiles(options: NormalizedSchema): Rule {
return (tree) => {
const isPnpm = tree.exists('pnpm-lock.yaml');
return mergeWith(
apply(url(`./files`), [
template({
...options,
isPnpm,
...names(options.name),
offsetFromRoot: offsetFromRoot(options.projectRoot),
tmpl: '',
}),
options.styledModule
? filter((file) => !file.endsWith(`.${options.style}`))
: noop(),
move(options.projectRoot),
options.js ? toJS() : noop(),
options.js
? updateTsConfigsToJs({ projectRoot: options.projectRoot })
: noop(),
])
);
};
}
function addProject(options: NormalizedSchema): Rule {
return updateWorkspaceInTree((json) => {
const architect: { [key: string]: any } = {};
architect.build = {
builder: '@nrwl/gatsby:build',
options: {
outputPath: `${options.projectRoot}/public`,
uglify: true,
color: true,
profile: false,
},
configurations: {
production: {},
},
};
architect.serve = {
builder: '@nrwl/gatsby:server',
options: {
buildTarget: `${options.projectName}:build`,
},
configurations: {
production: {
buildTarget: `${options.projectName}:build:production`,
},
},
};
architect.lint = generateProjectLint(
normalize(options.projectRoot),
join(normalize(options.projectRoot), 'tsconfig.json'),
Linter.EsLint,
[`${options.projectRoot}/**/*.{ts,tsx,js,jsx}`]
);
json.projects[options.projectName] = {
root: options.projectRoot,
sourceRoot: `${options.projectRoot}/src`,
projectType,
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'
? externalSchematic('@nrwl/jest', 'jest-project', {
project: options.projectName,
supportTsx: true,
skipSerializers: true,
setupFile: 'none',
babelJest: true,
})
: noop();
}
function addPrettierIgnoreEntry(options: NormalizedSchema) {
return (tree: Tree, context: SchematicContext) => {
let prettierIgnoreFile = tree.read('.prettierignore')?.toString('utf-8');
if (prettierIgnoreFile) {
prettierIgnoreFile =
prettierIgnoreFile +
`\n/apps/${options.projectName}/node_modules\n/apps/${options.projectName}/public\n/apps/${options.projectName}/.cache\n`;
tree.overwrite('.prettierignore', prettierIgnoreFile);
} else {
context.logger.warn(`Couldn't find .prettierignore file to update`);
}
};
}
function addGitIgnoreEntry(options: NormalizedSchema) {
return (tree: Tree, context: SchematicContext) => {
let gitIgnoreFile = tree.read('.gitignore')?.toString('utf-8');
if (gitIgnoreFile) {
gitIgnoreFile =
gitIgnoreFile +
`\n/apps/${options.projectName}/node_modules\n/apps/${options.projectName}/public\n/apps/${options.projectName}/.cache\n`;
tree.overwrite('.gitignore', gitIgnoreFile);
} else {
context.logger.warn(`Couldn't find .gitignore file to update`);
}
};
}
function updateJestConfig(options: NormalizedSchema) {
return options.unitTestRunner === 'none'
? noop()
: (host) => {
const appDirectory = options.directory
? `${toFileName(options.directory)}/${toFileName(options.name)}`
: toFileName(options.name);
const appProjectRoot = `${appsDir(host)}/${appDirectory}`;
const configPath = `${appProjectRoot}/jest.config.js`;
const originalContent = host.read(configPath).toString();
const content = updateJestConfigContent(originalContent);
host.overwrite(configPath, content);
};
}
function updateEslintConfig(options: NormalizedSchema) {
const appDirectory = options.directory
? `${toFileName(options.directory)}/${toFileName(options.name)}`
: toFileName(options.name);
return (host) => {
const appProjectRoot = `${appsDir(host)}/${appDirectory}`;
const configPath = `${appProjectRoot}/.eslintrc.json`;
return updateJsonInTree(configPath, (json) => {
json.ignorePatterns = ['!**/*', 'public', '.cache'];
return json;
});
};
}
export const applicationGenerator = wrapAngularDevkitSchematic(
'@nrwl/gatsby',
'application'
);

View File

@ -0,0 +1,4 @@
{
"presets": ["@nrwl/gatsby/babel"],
"plugins": []
}

View File

@ -0,0 +1,69 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# dotenv environment variable files
.env*
# gatsby files
.cache/
public
# Mac files
.DS_Store
# Yarn
yarn-error.log
.pnp/
.pnp.js
# Yarn Integrity file
.yarn-integrity

View File

@ -0,0 +1,4 @@
.cache
package.json
package-lock.json
public

View File

@ -0,0 +1,4 @@
{
"arrowParens": "avoid",
"semi": false
}

View File

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 gatsbyjs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,99 @@
<!-- AUTO-GENERATED-CONTENT:START (STARTER) -->
<p align="center">
<a href="https://www.gatsbyjs.org">
<img alt="Gatsby" src="https://www.gatsbyjs.org/monogram.svg" width="60" />
</a>
</p>
<h1 align="center">
Gatsby's default starter
</h1>
Kick off your project with this default boilerplate. This starter ships with the main Gatsby configuration files you might need to get up and running blazing fast with the blazing fast app generator for React.
_Have another more specific idea? You may want to check out our vibrant collection of [official and community-created starters](https://www.gatsbyjs.org/docs/gatsby-starters/)._
## 🚀 Quick start
1. **Create a Gatsby site.**
Use the Gatsby CLI to create a new site, specifying the default starter.
```shell
# create a new Gatsby site using the default starter
gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default
```
1. **Start developing.**
Navigate into your new sites directory and start it up.
```shell
cd my-default-starter/
gatsby develop
```
1. **Open the source code and start editing!**
Your site is now running at `http://localhost:8000`!
_Note: You'll also see a second link: _`http://localhost:8000/___graphql`_. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the [Gatsby tutorial](https://www.gatsbyjs.org/tutorial/part-five/#introducing-graphiql)._
Open the `my-default-starter` directory in your code editor of choice and edit `src/pages/index.js`. Save your changes and the browser will update in real time!
## 🧐 What's inside?
A quick look at the top-level files and directories you'll see in a Gatsby project.
.
├── node_modules
├── src
├── .gitignore
├── .prettierrc
├── gatsby-browser.js
├── gatsby-config.js
├── gatsby-node.js
├── gatsby-ssr.js
├── LICENSE
├── package-lock.json
├── package.json
└── README.md
1. **`/node_modules`**: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed.
2. **`/src`**: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. `src` is a convention for “source code”.
3. **`.gitignore`**: This file tells git which files it should not track / not maintain a version history for.
4. **`.prettierrc`**: This is a configuration file for [Prettier](https://prettier.io/). Prettier is a tool to help keep the formatting of your code consistent.
5. **`gatsby-browser.js`**: This file is where Gatsby expects to find any usage of the [Gatsby browser APIs](https://www.gatsbyjs.org/docs/browser-apis/) (if any). These allow customization/extension of default Gatsby settings affecting the browser.
6. **`gatsby-config.js`**: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins youd like to include, etc. (Check out the [config docs](https://www.gatsbyjs.org/docs/gatsby-config/) for more detail).
7. **`gatsby-node.js`**: This file is where Gatsby expects to find any usage of the [Gatsby Node APIs](https://www.gatsbyjs.org/docs/node-apis/) (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process.
8. **`gatsby-ssr.js`**: This file is where Gatsby expects to find any usage of the [Gatsby server-side rendering APIs](https://www.gatsbyjs.org/docs/ssr-apis/) (if any). These allow customization of default Gatsby settings affecting server-side rendering.
9. **`LICENSE`**: Gatsby is licensed under the MIT license.
10. **`package-lock.json`** (See `package.json` below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. **(You wont change this file directly).**
11. **`package.json`**: A manifest file for Node.js projects, which includes things like metadata (the projects name, author, etc). This manifest is how npm knows which packages to install for your project.
12. **`README.md`**: A text file containing useful reference information about your project.
## 🎓 Learning Gatsby
Looking for more guidance? Full documentation for Gatsby lives [on the website](https://www.gatsbyjs.org/). Here are some places to start:
- **For most developers, we recommend starting with our [in-depth tutorial for creating a site with Gatsby](https://www.gatsbyjs.org/tutorial/).** It starts with zero assumptions about your level of ability and walks through every step of the process.
- **To dive straight into code samples, head [to our documentation](https://www.gatsbyjs.org/docs/).** In particular, check out the _Guides_, _API Reference_, and _Advanced Tutorials_ sections in the sidebar.
## 💫 Deploy
[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/gatsbyjs/gatsby-starter-default)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/gatsbyjs/gatsby-starter-default)
<!-- AUTO-GENERATED-CONTENT:END -->

View File

@ -0,0 +1,7 @@
/**
* Implement Gatsby's Browser APIs in this file.
*
* See: https://www.gatsbyjs.org/docs/browser-apis/
*/
// You can delete this file if you're not using it

View File

@ -0,0 +1,56 @@
module.exports = {
siteMetadata: {
title: `<%= name %>`,
description: `This is a gatsby application created by Nx.`
},
plugins: [
<% if (style === 'less') { %>'gatsby-plugin-less',<% } %>
<% if (style === 'scss') { %>'gatsby-plugin-sass',<% } %>
<% if (style === 'styl') { %>'gatsby-plugin-stylus',<% } %>
<% if (style === 'styled-components') { %>'gatsby-plugin-styled-components',<% } %>
<% if (style === '@emotion/styled') { %>'gatsby-plugin-emotion',<% } %>
<% if (isPnpm) { %>
{
resolve: 'gatsby-plugin-pnpm',
options: {
strict: false
}
},
<% } %>
{
resolve: 'gatsby-plugin-svgr',
options: {
svgo: false,
ref: true
}
},
`gatsby-plugin-react-helmet`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images`
}
},
`gatsby-transformer-sharp`,
{
resolve: require.resolve(`@nrwl/gatsby/plugins/nx-gatsby-ext-plugin`),
options: {
path: __dirname
}
},
`gatsby-plugin-sharp`,
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `<%= name %>`,
short_name: `starter`,
start_url: `/`,
background_color: `#663399`,
theme_color: `#663399`,
display: `minimal-ui`,
icon: `src/images/logo.png`
}
}
]
};

View File

@ -0,0 +1,7 @@
/**
* Implement Gatsby's Node APIs in this file.
*
* See: https://www.gatsbyjs.org/docs/node-apis/
*/
// You can delete this file if you're not using it

View File

@ -0,0 +1,7 @@
/**
* Implement Gatsby's SSR (Server Side Rendering) APIs in this file.
*
* See: https://www.gatsbyjs.org/docs/ssr-apis/
*/
// You can delete this file if you're not using it

View File

@ -0,0 +1,10 @@
{
"name": "gatsby-starter-default",
"private": true,
"description": "A simple starter to get up and developing quickly with Gatsby",
"version": "0.0.0",
"license": "MIT",
"dependencies": {
"gatsby": "*"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,5 @@
import React from "react"
const NotFoundPage = () => <h1>NOT FOUND</h1>
export default NotFoundPage

View File

@ -0,0 +1,132 @@
/*
* Remove template code below
*/
.page {
font-family: sans-serif;
min-width: 300px;
max-width: 600px;
margin: 50px auto;
}
.page :global(.gutter-left) {
margin-left: 9px;
}
.page :global(.col-span-2) {
grid-column: span 2;
}
.page :global(.flex) {
display: flex;
align-items: center;
justify-content: center;
}
.page :global(header) {
background-color: #143055;
color: white;
padding: 5px;
border-radius: 3px;
}
.page :global(main) {
padding: 0 36px;
}
.page :global(p) {
text-align: center;
}
.page :global(h1) {
text-align: center;
margin-left: 18px;
font-size: 24px;
}
.page :global(h2) {
text-align: center;
font-size: 20px;
margin: 40px 0 10px 0;
}
.page :global(.resources) {
text-align: center;
list-style: none;
padding: 0;
display: grid;
grid-gap: 9px;
grid-template-columns: 1fr 1fr;
}
.page :global(.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;
}
.page :global(.resource:hover) {
background-color: rgba(68, 138, 255, 0.04);
}
.page :global(pre) {
padding: 9px;
border-radius: 4px;
background-color: black;
color: #eee;
}
.page :global(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;
}
.page :global(summary) {
outline: none;
height: 36px;
line-height: 36px;
}
.page :global(.github-star-container) {
margin-top: 12px;
line-height: 20px;
}
.page :global(.github-star-container a) {
display: flex;
align-items: center;
text-decoration: none;
color: #333;
}
.page :global(.github-star-badge) {
color: #24292e;
display: flex;
align-items: center;
font-size: 12px;
padding: 3px 10px;
border: 1px solid rgba(27, 31, 35, 0.2);
border-radius: 3px;
background-image: linear-gradient(-180deg, #fafbfc, #eff3f6 90%);
margin-left: 4px;
font-weight: 600;
}
.page :global(.github-star-badge:hover) {
background-image: linear-gradient(-180deg, #f0f3f6, #e6ebf1 90%);
border-color: rgba(27, 31, 35, 0.35);
background-position: -0.5em;
}
.page :global(.github-star-badge .material-icons) {
height: 16px;
width: 16px;
margin-right: 4px;
}

View File

@ -0,0 +1,13 @@
import React from 'react';
import { render } from '@testing-library/react';
import Index from './index';
describe('Index', () => {
it('should render successfully', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const props: any = {};
const { getByText } = render(<Index {...props} />);
expect(getByText('Welcome to <%= projectName %>!')).toBeTruthy();
});
});

View File

@ -0,0 +1,256 @@
import React from 'react';
<% if (styledModule) {
var wrapper = 'StyledApp';
%>import styled from '<%= styledModule %>';<% } else {
var wrapper = 'div';
%>
import styles from './index.module.<%= style %>';
<% }
%>
import { ReactComponent as Logo } from './logo.svg';
import star from './star.svg';
<% 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">
<Logo width="75" height="75"/>
<h1>Welcome to ${name}!</h1>
</header>
<main>
<h2>Resources &amp; 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">
<img src={star} className="material-icons" alt="" />
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://connect.nrwl.io/app/courses/nx-workspaces/intro"
>
Nx video course
</a>
</li>
<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>
`;
%>
export function Index() {
/*
* Replace the elements below with your own.
*
* Note: The corresponding styles are in the ./${fileName}.${style} file.
*/
return (
<<%= wrapper %><% if (!styledModule) {%> className={styles.page}<% } %>>
<%= innerJsx %>
</<%= wrapper %>>
);
};
export default Index;

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="262px" height="163px" viewBox="0 0 262 163" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Styles-&amp;-Quick-Wins" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Nx---Quick-Wins" transform="translate(-476.000000, -1284.000000)" fill-rule="nonzero">
<g id="Logos" transform="translate(-11.000000, 782.000000)">
<g id="Nx_Flat_White" transform="translate(487.000000, 502.000000)">
<polygon id="Path" fill="#FFFFFF" points="130.68 104.59 97.49 52.71 97.44 96.3 40.24 0 0 0 0 162.57 39.79 162.57 39.92 66.39 96.53 158.26"/>
<polygon id="Path" fill="#FFFFFF" points="97.5 41.79 137.24 41.79 137.33 41.33 137.33 0 97.54 0 97.49 41.33"/>
<path d="M198.66,86.86 C189.139872,86.6795216 180.538723,92.516445 177.19,101.43 C182.764789,93.0931021 193.379673,89.7432211 202.73,93.37 C207.05,95.13 212.73,97.97 217.23,96.45 C212.950306,90.4438814 206.034895,86.8725952 198.66,86.86 L198.66,86.86 Z" id="Path" fill="#96D8E9"/>
<path d="M243.75,106.42 C243.75,101.55 241.1,100.42 235.6,98.42 C231.52,97 226.89,95.4 223.52,91 C222.86,90.13 222.25,89.15 221.6,88.11 C220.14382,85.4164099 218.169266,83.037429 215.79,81.11 C212.58,78.75 208.37,77.6 202.91,77.6 C191.954261,77.6076705 182.084192,84.2206169 177.91,94.35 C183.186964,87.0278244 191.956716,83.0605026 200.940147,83.9314609 C209.923578,84.8024193 217.767888,90.3805017 221.54,98.58 C223.424615,101.689762 227.141337,103.174819 230.65,102.22 C236.02,101.07 235.65,106.15 243.76,107.87 L243.75,106.42 Z" id="Path" fill="#48C4E5"/>
<path d="M261.46,105.38 L261.46,105.27 C261.34,73.03 235.17,45.45 202.91,45.45 C183.207085,45.4363165 164.821777,55.3450614 154,71.81 L153.79,71.45 L137.23,45.45 L97.5,45.4499858 L135.25,104.57 L98.41,162.57 L137,162.57 L153.79,136.78 L170.88,162.57 L209.48,162.57 L174.48,107.49 C173.899005,106.416838 173.583536,105.220114 173.56,104 C173.557346,96.2203871 176.64661,88.7586448 182.147627,83.2576275 C187.648645,77.7566101 195.110387,74.6673462 202.89,74.67 C219.11,74.67 221.82,84.37 225.32,88.93 C232.23,97.93 246.03,93.99 246.03,105.73 L246.03,105.73 C246.071086,108.480945 247.576662,111.001004 249.979593,112.340896 C252.382524,113.680787 255.317747,113.636949 257.679593,112.225896 C260.041438,110.814842 261.471086,108.250945 261.43,105.5 L261.43,105.5 L261.43,105.38 L261.46,105.38 Z" id="Path" fill="#FFFFFF"/>
<path d="M261.5,113.68 C261.892278,116.421801 261.504116,119.218653 260.38,121.75 C258.18,126.84 254.51,125.14 254.51,125.14 C254.51,125.14 251.35,123.6 253.27,120.65 C255.4,117.36 259.61,117.74 261.5,113.68 Z" id="Path" fill="#FFFFFF"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>

After

Width:  |  Height:  |  Size: 347 B

View File

@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "<%= offsetFromRoot %>dist/out-tsc",
"types": ["node", "jest"]
},
"exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
"include": ["**/*.ts", "**/*.tsx"]
}

View File

@ -0,0 +1,22 @@
{
"extends": "<%= offsetFromRoot %>tsconfig.base.json",
"compilerOptions": {
"jsx": "preserve",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"resolveJsonModule": true,
"isolatedModules": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.app.json"
}
],
"exclude": ["node_modules"]
}

View File

@ -0,0 +1,9 @@
export interface GatsbyPluginSchematicSchema {
name: string;
tags?: string;
style: string;
directory?: string;
unitTestRunner: 'jest' | 'none';
e2eTestRunner: 'cypress' | 'none';
js: boolean;
}

View File

@ -0,0 +1,85 @@
{
"$schema": "http://json-schema.org/schema",
"id": "NxGatsbyApp",
"title": "",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "",
"$default": {
"$source": "argv",
"index": 0
},
"x-prompt": "What name would you like to use?"
},
"tags": {
"type": "string",
"description": "Add tags to the project (used for linting)",
"alias": "t"
},
"directory": {
"type": "string",
"description": "A directory where the project is placed",
"alias": "d"
},
"unitTestRunner": {
"description": "Adds the specified unit test runner",
"type": "string",
"enum": ["jest", "none"],
"default": "jest"
},
"e2eTestRunner": {
"description": "Adds the specified e2e test runner",
"type": "string",
"enum": ["cypress", "none"],
"default": "cypress"
},
"style": {
"description": "The file extension to be used for style files.",
"type": "string",
"alias": "s",
"default": "css",
"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 ]"
},
{
"value": "none",
"label": "None"
}
]
}
},
"js": {
"type": "boolean",
"description": "Generate JavaScript files rather than TypeScript files",
"default": false
}
},
"required": ["name"]
}

View File

@ -0,0 +1,35 @@
import { chain, externalSchematic, Rule } from '@angular-devkit/schematics';
import { addStyleDependencies } from '../../utils/styles';
import { wrapAngularDevkitSchematic } from '@nrwl/tao/src/commands/ngcli-adapter';
interface Schema {
name: string;
project: string;
style: string;
directory?: string;
flat?: boolean;
}
/*
* This schematic is basically the React one, but for Next we need
* extra dependencies for css, sass, less, styl style options.
*/
export default function (options: Schema): Rule {
return chain([
externalSchematic('@nrwl/react', 'component', {
...options,
directory: options.directory || 'components',
pascalCaseFiles: false,
export: false,
classComponent: false,
routing: false,
flat: true,
}),
addStyleDependencies(options.style),
]);
}
export const componentGenerator = wrapAngularDevkitSchematic(
'@nrwl/gatsby',
'component'
);

View File

@ -0,0 +1,103 @@
{
"$schema": "http://json-schema.org/schema",
"id": "NxReactApp",
"title": "Create a React Component for Gatsby",
"type": "object",
"examples": [
{
"command": "g component my-component --project=mylib",
"description": "Generate a component in the mylib library"
},
{
"command": "g component my-component --project=mylib --classComponent",
"description": "Generate a class component in the mylib library"
}
],
"properties": {
"project": {
"type": "string",
"description": "The name of the project.",
"alias": "p",
"$default": {
"$source": "projectName"
},
"x-prompt": "What is the name of the project for this component?"
},
"name": {
"type": "string",
"description": "The name of the component.",
"$default": {
"$source": "argv",
"index": 0
},
"x-prompt": "What name would you like to use for the component?"
},
"style": {
"description": "The file extension to be used for style files.",
"type": "string",
"alias": "s",
"default": "css",
"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 ]"
},
{
"value": "none",
"label": "None"
}
]
}
},
"skipTests": {
"type": "boolean",
"description": "When true, does not create \"spec.ts\" test files for the new component.",
"default": false
},
"directory": {
"type": "string",
"description": "Create the component under this directory (can be nested).",
"alias": "d"
},
"export": {
"type": "boolean",
"description": "When true, the component is exported from the project index.ts (if it exists).",
"alias": "e",
"default": false
},
"js": {
"type": "boolean",
"description": "Generate JavaScript files rather than TypeScript files.",
"default": false
},
"flat": {
"type": "boolean",
"description": "Create component at the source root rather than its own directory.",
"default": false
}
},
"required": ["name", "project"]
}

View File

@ -0,0 +1,94 @@
import { JsonObject } from '@angular-devkit/core';
import { chain, noop, Rule } from '@angular-devkit/schematics';
import {
addDepsToPackageJson,
addPackageWithInit,
updateWorkspace,
} from '@nrwl/workspace';
import { setDefaultCollection } from '@nrwl/workspace/src/utils/rules/workspace';
import {
babelPluginModuleResolverVersion,
babelPresetGatsbyVersion,
gatsbyImageVersion,
gatsbyPluginManifestVersion,
gatsbyPluginOfflineVersion,
gatsbyPluginPnpm,
gatsbyPluginReactHelmetVersion,
gatsbyPluginSharpVersion,
gatsbyPluginSvgrVersion,
gatsbyPluginTypescriptVersion,
gatsbySourceFilesystemVersion,
gatsbyTransformerSharpVersion,
gatsbyVersion,
nxVersion,
propTypesVersion,
reactDomVersion,
reactHelmetVersion,
reactVersion,
testingLibraryReactVersion,
} from '../../utils/versions';
import { Schema } from './schema';
function jsonIdentity(x: any): JsonObject {
return x as JsonObject;
}
function setDefault(): Rule {
const updateProjectWorkspace = updateWorkspace((workspace) => {
workspace.extensions.schematics =
jsonIdentity(workspace.extensions.schematics) || {};
const gatsbySchematics =
jsonIdentity(workspace.extensions.schematics['@nrwl/gatsby']) || {};
workspace.extensions.schematics = {
...workspace.extensions.schematics,
'@nrwl/gatsby': {
application: {
...jsonIdentity(gatsbySchematics.application),
},
},
};
});
return chain([setDefaultCollection('@nrwl/gatsby'), updateProjectWorkspace]);
}
export default function (schema: Schema) {
return (tree) => {
const isPnpm = tree.exists('pnpm-lock.yaml');
return chain([
setDefault(),
schema.unitTestRunner === 'jest'
? addPackageWithInit('@nrwl/jest')
: noop(),
schema.e2eTestRunner === 'cypress'
? addPackageWithInit('@nrwl/cypress')
: noop(),
addDepsToPackageJson(
{
gatsby: gatsbyVersion,
'gatsby-image': gatsbyImageVersion,
'gatsby-plugin-svgr': gatsbyPluginSvgrVersion,
'gatsby-plugin-manifest': gatsbyPluginManifestVersion,
'gatsby-plugin-offline': gatsbyPluginOfflineVersion,
'gatsby-plugin-react-helmet': gatsbyPluginReactHelmetVersion,
'gatsby-plugin-sharp': gatsbyPluginSharpVersion,
'gatsby-source-filesystem': gatsbySourceFilesystemVersion,
'gatsby-transformer-sharp': gatsbyTransformerSharpVersion,
'prop-types': propTypesVersion,
react: reactVersion,
'react-dom': reactDomVersion,
'react-helmet': reactHelmetVersion,
'gatsby-plugin-typescript': gatsbyPluginTypescriptVersion,
...(isPnpm ? { 'gatsby-plugin-pnpm': gatsbyPluginPnpm } : {}),
},
{
'@nrwl/react': nxVersion,
'@testing-library/react': testingLibraryReactVersion,
'babel-plugin-module-resolver': babelPluginModuleResolverVersion,
'babel-preset-gatsby': babelPresetGatsbyVersion,
}
),
]);
};
}

View File

@ -0,0 +1,5 @@
export interface Schema {
unitTestRunner: 'jest' | 'none';
e2eTestRunner: 'cypress' | 'none';
skipFormat: boolean;
}

View File

@ -0,0 +1,26 @@
{
"$schema": "http://json-schema.org/schema",
"id": "NxGatsbyInit",
"title": "Add Nx Gatsby Schematics",
"type": "object",
"properties": {
"unitTestRunner": {
"description": "Adds the specified unit test runner",
"type": "string",
"enum": ["jest", "none"],
"default": "jest"
},
"e2eTestRunner": {
"description": "Adds the specified e2e test runner",
"type": "string",
"enum": ["cypress", "none"],
"default": "cypress"
},
"skipFormat": {
"description": "Skip formatting files",
"type": "boolean",
"default": false
}
},
"required": []
}

View File

@ -0,0 +1,32 @@
import { chain, externalSchematic, Rule } from '@angular-devkit/schematics';
import { addStyleDependencies } from '../../utils/styles';
import { wrapAngularDevkitSchematic } from '@nrwl/tao/src/commands/ngcli-adapter';
interface Schema {
name: string;
project: string;
style: string;
directory?: string;
flat?: boolean;
}
/*
* This schematic is basically the React one, but for Gatsby we need
* extra dependencies for css, sass, less, styl style options.
*/
export default function (options: Schema): Rule {
return chain([
externalSchematic('@nrwl/react', 'component', {
...options,
directory: options.directory || 'pages',
pascalCaseFiles: false,
export: false,
classComponent: false,
routing: false,
flat: true,
}),
addStyleDependencies(options.style),
]);
}
export const pageGenerator = wrapAngularDevkitSchematic('@nrwl/gatsby', 'page');

View File

@ -0,0 +1,103 @@
{
"$schema": "http://json-schema.org/schema",
"id": "NxReactApp",
"title": "Create a React Page for Gatsby",
"type": "object",
"examples": [
{
"command": "g page my-page --project=mylib",
"description": "Generate a page in the mylib library"
},
{
"command": "g page my-page --project=mylib --classComponent",
"description": "Generate a class component in the mylib library"
}
],
"properties": {
"project": {
"type": "string",
"description": "The name of the project.",
"alias": "p",
"$default": {
"$source": "projectName"
},
"x-prompt": "What is the name of the project for this component?"
},
"name": {
"type": "string",
"description": "The name of the component.",
"$default": {
"$source": "argv",
"index": 0
},
"x-prompt": "What name would you like to use for the component?"
},
"style": {
"description": "The file extension to be used for style files.",
"type": "string",
"alias": "s",
"default": "css",
"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 ]"
},
{
"value": "none",
"label": "None"
}
]
}
},
"skipTests": {
"type": "boolean",
"description": "When true, does not create \"spec.ts\" test files for the new component.",
"default": false
},
"directory": {
"type": "string",
"description": "Create the component under this directory (can be nested).",
"alias": "d"
},
"export": {
"type": "boolean",
"description": "When true, the component is exported from the project index.ts (if it exists).",
"alias": "e",
"default": false
},
"js": {
"type": "boolean",
"description": "Generate JavaScript files rather than TypeScript files.",
"default": false
},
"flat": {
"type": "boolean",
"description": "Create component at the source root rather than its own directory.",
"default": false
}
},
"required": ["name", "project"]
}

View File

@ -0,0 +1,13 @@
import { BuilderContext } from '@angular-devkit/architect';
export async function getProjectRoot(context: BuilderContext): Promise<string> {
const projectMeta = await context.getProjectMetadata(context.target.project);
if (projectMeta.root) {
return projectMeta.root as string;
} else {
context.reportStatus('Error');
const message = `${context.target.project} does not have a sourceRoot. Please define one.`;
context.logger.error(message);
throw new Error(message);
}
}

View File

@ -0,0 +1,55 @@
import { noop, Rule } from '@angular-devkit/schematics';
import { addDepsToPackageJson } from '@nrwl/workspace';
import { CSS_IN_JS_DEPENDENCIES } from '@nrwl/react';
import {
gatsbyPluginStyledComponentsVersion,
gatsbyPluginEmotionVersion,
gatsbyPluginLessVersion,
nodeSassVersion,
gatsbyPluginSassVersion,
gatsbyPluginStylusVersion,
} from './versions';
export const NEXT_SPECIFIC_STYLE_DEPENDENCIES = {
'styled-components': {
dependencies: CSS_IN_JS_DEPENDENCIES['styled-components'].dependencies,
devDependencies: {
'gatsby-plugin-styled-components': gatsbyPluginStyledComponentsVersion,
},
},
'@emotion/styled': {
dependencies: CSS_IN_JS_DEPENDENCIES['@emotion/styled'].dependencies,
devDependencies: {
'gatsby-plugin-emotion': gatsbyPluginEmotionVersion,
},
},
scss: {
dependencies: {},
devDependencies: {
'node-sass': nodeSassVersion,
'gatsby-plugin-sass': gatsbyPluginSassVersion,
},
},
less: {
dependencies: {},
devDependencies: {
'gatsby-plugin-less': gatsbyPluginLessVersion,
},
},
styl: {
dependencies: {},
devDependencies: {
'gatsby-plugin-stylus': gatsbyPluginStylusVersion,
},
},
};
export function addStyleDependencies(style: string): Rule {
const extraDependencies = NEXT_SPECIFIC_STYLE_DEPENDENCIES[style];
return extraDependencies
? addDepsToPackageJson(
extraDependencies.dependencies,
extraDependencies.devDependencies
)
: noop();
}

View File

@ -0,0 +1,27 @@
import { Tree } from '@angular-devkit/schematics';
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
import { join } from 'path';
const testRunner = new SchematicTestRunner(
'@nrwl/gatsby',
join(__dirname, '../../collection.json')
);
testRunner.registerCollection(
'@nrwl/jest',
join(__dirname, '../../../jest/collection.json')
);
testRunner.registerCollection(
'@nrwl/cypress',
join(__dirname, '../../../cypress/collection.json')
);
testRunner.registerCollection(
'@nrwl/react',
join(__dirname, '../../../react/collection.json')
);
export function runSchematic(schematicName: string, options: any, tree: Tree) {
return testRunner.runSchematicAsync(schematicName, options, tree).toPromise();
}

View File

@ -0,0 +1,26 @@
export const nxVersion = '*';
export const gatsbyVersion = '2.27.4';
export const gatsbyImageVersion = '2.6.0';
export const gatsbyPluginManifestVersion = '2.6.1';
export const gatsbyPluginOfflineVersion = '3.4.0';
export const gatsbyPluginReactHelmetVersion = '3.4.0';
export const gatsbyPluginSharpVersion = '2.8.0';
export const gatsbySourceFilesystemVersion = '2.5.0';
export const gatsbyTransformerSharpVersion = '2.6.0';
export const propTypesVersion = '15.7.2';
export const reactVersion = '17.0.1';
export const reactDomVersion = '17.0.1';
export const reactHelmetVersion = '6.1.0';
export const gatsbyPluginTypescriptVersion = '2.7.0';
export const babelPluginModuleResolverVersion = '4.0.0';
export const babelPresetGatsbyVersion = '0.7.0';
export const testingLibraryReactVersion = '11.2.2';
export const gatsbyPluginEmotionVersion = '4.5.0';
export const gatsbyPluginStyledComponentsVersion = '3.5.0';
export const gatsbyPluginSassVersion = '2.6.0';
export const gatsbyPluginLessVersion = '4.2.0';
export const gatsbyPluginStylusVersion = '2.5.0';
export const nodeSassVersion = '4.14.1';
export const gatsbyPluginSvgrVersion = '2.0.2';
export const gatsbyPluginPnpm = '1.2.5';

View File

@ -0,0 +1,16 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"types": ["node", "jest"]
},
"include": [],
"files": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}

View File

@ -0,0 +1,11 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "../../dist/out-tsc",
"declaration": true,
"types": ["node"]
},
"exclude": ["**/*.spec.ts", "**/*_spec.ts"],
"include": ["**/*.ts"]
}

View File

@ -0,0 +1,16 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"**/*.spec.ts",
"**/*_spec.ts",
"**/*.spec.tsx",
"**/*.spec.js",
"**/*.spec.jsx",
"**/*.d.ts"
]
}

View File

@ -26,6 +26,7 @@ export enum Preset {
React = 'react', React = 'react',
ReactWithExpress = 'react-express', ReactWithExpress = 'react-express',
NextJs = 'next', NextJs = 'next',
Gatsby = 'gatsby',
Nest = 'nest', Nest = 'nest',
} }
@ -245,6 +246,12 @@ const presetDependencies: Omit<
'@nrwl/next': nxVersion, '@nrwl/next': nxVersion,
}, },
}, },
[Preset.Gatsby]: {
dependencies: {},
dev: {
'@nrwl/gatsby': nxVersion,
},
},
}; };
function addPresetDependencies(host: Tree, options: Schema) { function addPresetDependencies(host: Tree, options: Schema) {

View File

@ -44,6 +44,7 @@ function check() {
...allFilesInDir('packages/create-nx-plugin'), ...allFilesInDir('packages/create-nx-plugin'),
...allFilesInDir('packages/cypress'), ...allFilesInDir('packages/cypress'),
...allFilesInDir('packages/express'), ...allFilesInDir('packages/express'),
...allFilesInDir('packages/gatsby'),
...allFilesInDir('packages/jest'), ...allFilesInDir('packages/jest'),
...allFilesInDir('packages/nest'), ...allFilesInDir('packages/nest'),
...allFilesInDir('packages/node'), ...allFilesInDir('packages/node'),

View File

@ -20,6 +20,7 @@ const IGNORE_MATCHES = {
cli: ['@nrwl/cli'], cli: ['@nrwl/cli'],
cypress: ['cypress'], cypress: ['cypress'],
devkit: ['@angular-devkit/architect', 'rxjs'], devkit: ['@angular-devkit/architect', 'rxjs'],
gatsby: ['@angular-devkit/architect', 'babel-preset-gatsby', 'rxjs'],
jest: [ jest: [
'jest', 'jest',
'@jest/types', '@jest/types',

View File

@ -142,6 +142,7 @@ const pkgFiles = [
'build/npm/angular/package.json', 'build/npm/angular/package.json',
'build/npm/react/package.json', 'build/npm/react/package.json',
'build/npm/next/package.json', 'build/npm/next/package.json',
'build/npm/gatsby/package.json',
'build/npm/web/package.json', 'build/npm/web/package.json',
'build/npm/node/package.json', 'build/npm/node/package.json',
'build/npm/express/package.json', 'build/npm/express/package.json',

View File

@ -17,8 +17,8 @@ npx nx run-many --target=build --all --parallel || { echo 'Build failed' ; exit
cd build/packages cd build/packages
if [[ "$OSTYPE" == "darwin"* ]]; then if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i "" "s|exports.nxVersion = '\*';|exports.nxVersion = '$NX_VERSION';|g" {react,next,web,jest,node,linter,express,nest,cypress,storybook,angular,workspace}/src/utils/versions.js sed -i "" "s|exports.nxVersion = '\*';|exports.nxVersion = '$NX_VERSION';|g" {react,next,gatsby,web,jest,node,linter,express,nest,cypress,storybook,angular,workspace}/src/utils/versions.js
sed -i "" "s|\*|$NX_VERSION|g" {react,next,web,jest,node,express,nest,cypress,storybook,angular,workspace,cli,linter,tao,devkit,eslint-plugin-nx,create-nx-workspace,create-nx-plugin,nx-plugin}/package.json sed -i "" "s|\*|$NX_VERSION|g" {react,next,gatsby,web,jest,node,express,nest,cypress,storybook,angular,workspace,cli,linter,tao,devkit,eslint-plugin-nx,create-nx-workspace,create-nx-plugin,nx-plugin}/package.json
sed -i "" "s|NX_VERSION|$NX_VERSION|g" create-nx-workspace/bin/create-nx-workspace.js sed -i "" "s|NX_VERSION|$NX_VERSION|g" create-nx-workspace/bin/create-nx-workspace.js
sed -i "" "s|ANGULAR_CLI_VERSION|$ANGULAR_CLI_VERSION|g" create-nx-workspace/bin/create-nx-workspace.js sed -i "" "s|ANGULAR_CLI_VERSION|$ANGULAR_CLI_VERSION|g" create-nx-workspace/bin/create-nx-workspace.js
sed -i "" "s|TYPESCRIPT_VERSION|$TYPESCRIPT_VERSION|g" create-nx-workspace/bin/create-nx-workspace.js sed -i "" "s|TYPESCRIPT_VERSION|$TYPESCRIPT_VERSION|g" create-nx-workspace/bin/create-nx-workspace.js
@ -28,8 +28,8 @@ if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i "" "s|TYPESCRIPT_VERSION|$TYPESCRIPT_VERSION|g" create-nx-plugin/bin/create-nx-plugin.js sed -i "" "s|TYPESCRIPT_VERSION|$TYPESCRIPT_VERSION|g" create-nx-plugin/bin/create-nx-plugin.js
sed -i "" "s|PRETTIER_VERSION|$PRETTIER_VERSION|g" create-nx-plugin/bin/create-nx-plugin.js sed -i "" "s|PRETTIER_VERSION|$PRETTIER_VERSION|g" create-nx-plugin/bin/create-nx-plugin.js
else else
sed -i "s|exports.nxVersion = '\*';|exports.nxVersion = '$NX_VERSION';|g" {react,next,web,jest,node,linter,express,nest,cypress,storybook,angular,workspace}/src/utils/versions.js sed -i "s|exports.nxVersion = '\*';|exports.nxVersion = '$NX_VERSION';|g" {react,next,gatsby,web,jest,node,linter,express,nest,cypress,storybook,angular,workspace}/src/utils/versions.js
sed -i "s|\*|$NX_VERSION|g" {react,next,web,jest,node,express,nest,cypress,storybook,angular,workspace,cli,linter,tao,devkit,eslint-plugin-nx,create-nx-workspace,create-nx-plugin,nx-plugin}/package.json sed -i "s|\*|$NX_VERSION|g" {react,next,gatsby,web,jest,node,express,nest,cypress,storybook,angular,workspace,cli,linter,tao,devkit,eslint-plugin-nx,create-nx-workspace,create-nx-plugin,nx-plugin}/package.json
sed -i "s|NX_VERSION|$NX_VERSION|g" create-nx-workspace/bin/create-nx-workspace.js sed -i "s|NX_VERSION|$NX_VERSION|g" create-nx-workspace/bin/create-nx-workspace.js
sed -i "s|ANGULAR_CLI_VERSION|$ANGULAR_CLI_VERSION|g" create-nx-workspace/bin/create-nx-workspace.js sed -i "s|ANGULAR_CLI_VERSION|$ANGULAR_CLI_VERSION|g" create-nx-workspace/bin/create-nx-workspace.js
sed -i "s|TYPESCRIPT_VERSION|$TYPESCRIPT_VERSION|g" create-nx-workspace/bin/create-nx-workspace.js sed -i "s|TYPESCRIPT_VERSION|$TYPESCRIPT_VERSION|g" create-nx-workspace/bin/create-nx-workspace.js
@ -42,9 +42,9 @@ fi
if [[ $NX_VERSION == "*" ]]; then if [[ $NX_VERSION == "*" ]]; then
if [[ "$OSTYPE" == "darwin"* ]]; then if [[ "$OSTYPE" == "darwin"* ]]; then
sed -E -i "" "s|\"@nrwl\/([^\"]+)\": \"\\*\"|\"@nrwl\/\1\": \"file:$PWD\/\1\"|" {jest,web,react,next,node,express,nest,cypress,storybook,angular,workspace,linter,cli,tao,devkit,eslint-plugin-nx,create-nx-workspace,create-nx-plugin,nx-plugin}/package.json sed -E -i "" "s|\"@nrwl\/([^\"]+)\": \"\\*\"|\"@nrwl\/\1\": \"file:$PWD\/\1\"|" {jest,web,react,next,gatsby,node,express,nest,cypress,storybook,angular,workspace,linter,cli,tao,devkit,eslint-plugin-nx,create-nx-workspace,create-nx-plugin,nx-plugin}/package.json
else else
echo $PWD echo $PWD
sed -E -i "s|\"@nrwl\/([^\"]+)\": \"\\*\"|\"@nrwl\/\1\": \"file:$PWD\/\1\"|" {jest,web,react,next,node,express,nest,cypress,storybook,angular,workspace,linter,cli,tao,devkit,eslint-plugin-nx,create-nx-workspace,create-nx-plugin,nx-plugin}/package.json sed -E -i "s|\"@nrwl\/([^\"]+)\": \"\\*\"|\"@nrwl\/\1\": \"file:$PWD\/\1\"|" {jest,web,react,next,gatsby,node,express,nest,cypress,storybook,angular,workspace,linter,cli,tao,devkit,eslint-plugin-nx,create-nx-workspace,create-nx-plugin,nx-plugin}/package.json
fi fi
fi fi

View File

@ -22,6 +22,7 @@ export function build(
...[ ...[
'react', 'react',
'next', 'next',
'gatsby',
'web', 'web',
'jest', 'jest',
'node', 'node',
@ -35,6 +36,7 @@ export function build(
...[ ...[
'react', 'react',
'next', 'next',
'gatsby',
'web', 'web',
'jest', 'jest',
'node', 'node',

View File

@ -1907,6 +1907,22 @@
} }
} }
}, },
"e2e-gatsby": {
"root": "e2e/gatsby",
"sourceRoot": "e2e/gatsby",
"projectType": "application",
"targets": {
"e2e": {
"executor": "@nrwl/jest:jest",
"options": {
"jestConfig": "e2e/gatsby/jest.config.js",
"passWithNoTests": true,
"runInBand": true
},
"outputs": ["coverage/e2e/gatsby"]
}
}
},
"dep-graph-client": { "dep-graph-client": {
"root": "apps/dep-graph-client", "root": "apps/dep-graph-client",
"sourceRoot": "apps/dep-graph-client/src", "sourceRoot": "apps/dep-graph-client/src",
@ -2010,6 +2026,94 @@
} }
} }
} }
},
"gatsby": {
"root": "packages/gatsby",
"sourceRoot": "packages/gatsby",
"projectType": "library",
"targets": {
"test": {
"executor": "@nrwl/jest:jest",
"options": {
"jestConfig": "packages/gatsby/jest.config.js",
"passWithNoTests": true
},
"outputs": ["coverage/packages/gatsby"]
},
"build-base": {
"executor": "@nrwl/node:package",
"options": {
"outputPath": "build/packages/gatsby",
"tsConfig": "packages/gatsby/tsconfig.lib.json",
"packageJson": "packages/gatsby/package.json",
"main": "packages/gatsby/index.ts",
"updateBuildableProjectDepsInPackageJson": false,
"assets": [
{
"input": "packages/gatsby/src",
"glob": "**/.babelrc*",
"output": "./src"
},
{
"input": "packages/gatsby/src",
"glob": "**/*.!(ts)",
"output": "./src"
},
{
"input": "packages/gatsby/plugins",
"glob": "**/*.!(ts)",
"output": "./plugins"
},
{
"input": "packages/gatsby",
"glob": "**/*.json",
"output": "/"
},
{
"input": "packages/gatsby",
"glob": "**/*.js",
"output": "/"
},
{
"input": "packages/gatsby",
"glob": "**/*.d.ts",
"output": "/"
},
"LICENSE"
]
},
"outputs": ["{options.outputPath}"]
},
"build": {
"executor": "@nrwl/workspace:run-commands",
"outputs": ["build/packages/gatsby"],
"options": {
"commands": [
{
"command": "nx build-base gatsby"
},
{
"command": "node ./scripts/copy-readme.js gatsby"
}
],
"parallel": false
}
},
"lint": {
"executor": "@nrwl/linter:eslint",
"options": {
"lintFilePatterns": [
"packages/gatsby/**/*.ts",
"packages/gatsby/**/*.spec.ts",
"packages/gatsby/**/*_spec.ts",
"packages/gatsby/**/*.spec.tsx",
"packages/gatsby/**/*.spec.js",
"packages/gatsby/**/*.spec.jsx",
"packages/gatsby/**/*.d.ts"
]
}
}
}
} }
}, },
"cli": { "cli": {
@ -2072,6 +2176,14 @@
"library": { "library": {
"linter": "eslint" "linter": "eslint"
} }
},
"@nrwl/gatsby": {
"application": {
"linter": "eslint"
},
"library": {
"linter": "eslint"
}
} }
} }
} }