Skip to content

Commit

Permalink
Allow using custom nodemon config for dev mode
Browse files Browse the repository at this point in the history
Addresses #8
  • Loading branch information
yamalight committed Sep 10, 2020
1 parent 7b5cb9d commit 62773a0
Show file tree
Hide file tree
Showing 6 changed files with 263 additions and 4 deletions.
12 changes: 12 additions & 0 deletions docs/Advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,15 @@ exports.compose = ({ schemaComposer, typedef }) => {
Property `model` your `resolvers` function will receive here is a [Mongoose model](https://mongoosejs.com/docs/models.html) generated from schema definition in current file.

Property `schemaComposer` passed to `compose` function is instance of [SchemaCompose from graphql-compose](https://graphql-compose.github.io/docs/api/SchemaComposer.html), while `typedef` is a [graphql-compose type](https://graphql-compose.github.io/docs/basics/understanding-types.html) generated from Mongoose model created in current file.

## Ignoring files and folders to prevent reloads during development mode

By default Graffiti will use [nodemon](https://github.com/remy/nodemon) in development mode to auto-restart server on file changes.
This can lead to undesirable reloads (e.g. when working with Next.js).
To change that behaviour you can create a custom `nodemon.json` config that ignores specific files or folders (e.g. `pages/` in case of Next.js):

```json
{
"ignore": [".git", "node_modules", "pages/**/*"]
}
```
218 changes: 218 additions & 0 deletions docs/TutorialNotesNext.md
Original file line number Diff line number Diff line change
@@ -1 +1,219 @@
# Build a simple note-taking app with Graffiti and Next

## Prerequisites

- Node.js v14
- MongoDB:
- install it locally
- start via docker (e.g. `docker run --name mongodb -p 27017:27017 -d mongo`)

## Step 1: Create new project

```sh
mkdir graffiti-notes && cd graffiti-notes
npm init -y
```

## Step 2: Install Graffiti

```sh
npm install graffiti
```

## Step 3: Add Graffiti start and dev scripts to package.json

```json
{
// rest of your package.json
"scripts": {
"start": "NODE_ENV=production graffiti",
"develop": "graffiti dev"
}
// rest of your package.json
}
```

## Step 4: Define notes schema

First, create new schema folder:

```sh
mkdir schema
```

Then, create new `note.js` file in it and describe our notes schema:

```js
// schema/note.js
exports.schema = {
name: String,
body: String,
};
```

## Step 5: Test in playground

Make sure your MongoDB is running.
Once it is - execute `npm run develop` to start your Graffiti app in dev mode
and navigate to [http://localhost:3000/playground](http://localhost:3000/playground).

Playground should now allow you to execute variety of queries and mutations for notes.

## Step 6: Add Next.js plugin

First, install the plugin using npm:

```sh
npm install graffiti-plugin-next
```

Then, create new file `graffiti.config.js` and add the following:

```js
const nextPlugin = require('graffiti-plugin-next');

module.exports = {
mongoUrl: 'mongodb://localhost/graffiti',
plugins: [nextPlugin()],
};
```

## Step 7: Add new page

First, create `pages/` folder for Next.js to use:

```sh
mkdir pages
```

Then, create new `index.js` file and create your page using React (as you normally would using Next.js):

```js
export default () => <h1>Hello Graffiti + Next.js!</h1>;
```

## Step 8: Test in browser

Execute `npm run develop` to start your Graffiti app in dev mode
and navigate to [http://localhost:3000/](http://localhost:3000/).

You should see your newly created React page.

## Step 9: Add notes creation and browsing

First, let's add simplest GraphQL client for us to use - we'll use [graphql-request](https://github.com/prisma-labs/graphql-request):

```sh
npm install graphql-request graphql
```

Edit your `pages/index.js` and create new form for notes creation and new list of current notes, e.g.:

```js
import { gql, GraphQLClient } from 'graphql-request';
import { useState } from 'react';

// create a GraphQL client instance to send requests
const client = new GraphQLClient('http://localhost:3000/graphql', {
headers: {},
});

// define notes query
const notesQuery = gql`
{
noteMany {
_id
name
body
}
}
`;

// define create note mutation
const createNoteQuery = gql`
mutation AddNote($name: String!, $body: String!) {
noteCreate(record: { name: $name, body: $body }) {
record {
_id
name
body
}
}
}
`;

// define simple create note function that returns new note
const createNote = async ({ name, body }) => {
const variables = {
name,
body,
};
const data = await client.request(createNoteQuery, variables);
return data?.noteCreate?.record;
};

// define our page
export default ({ notes }) => {
const [allNotes, setAllNotes] = useState(notes);
const [name, setName] = useState();
const [body, setBody] = useState();

// add button handler
const handleAdd = async () => {
const newNote = await createNote({ name, body });
if (newNote) {
// add new note to render list
setAllNotes(allNotes.concat(newNote));
}
// reset old values
setName('');
setBody('');
};

return (
<div>
<div style={{ marginBottom: 20 }}>
<div>
<input
type="text"
placeholder="Note name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</div>
<div>
<textarea
placeholder="Note body"
value={body}
onChange={(e) => setBody(e.target.value)}
/>
</div>
<div>
<button onClick={handleAdd}>Add note</button>
</div>
</div>
{allNotes.map((note) => (
<div key={note._id} style={{ marginBottom: 10 }}>
<strong>{note.name}</strong>
<p>{note.body}</p>
</div>
))}
</div>
);
};

// define server-side props that load initial list of notes
export async function getServerSideProps(context) {
const data = await client.request(notesQuery);
return {
props: { notes: data?.noteMany ?? [] }, // will be passed to the page component as props
};
}
```
## Step 10: Try it out!
Execute `npm run develop` to start your Graffiti app in dev mode
and navigate to [http://localhost:3000/](http://localhost:3000/).
You should see your newly created page with form that should create notes and add them to page.
11 changes: 11 additions & 0 deletions packages/graffiti-plugin-next/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ module.exports = {
};
```

## Development mode

By default Graffiti will use [nodemon](https://github.com/remy/nodemon) in development mode to auto-restart server on file changes.
This makes Next.js development experience suboptimal. If you wish to use hot reload provided by Next.js, you'll need to create custom `nodemon.json` config that ignores changes to `pages/` folder, e.g.:

```json
{
"ignore": [".git", "node_modules", "pages/**/*"]
}
```

## Building for production

To create Next.js build for production you can either:
Expand Down
4 changes: 4 additions & 0 deletions packages/graffiti/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 0.8.0 / 2020-09-10

- Allow providing custom nodemon config

# 0.7.0 / 2020-09-08

- Add plugins support
Expand Down
20 changes: 17 additions & 3 deletions packages/graffiti/bin/graffiti.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,25 @@ const main = () => {
// get current workdir
const currentPath = process.cwd();

// start nodemon
nodemon({
// create default nodemon config
let nodemonConfig = {
script: entrypointPath,
ignore: ['.git', 'node_modules'],
ext: 'js',
});
};
// try to read local nodemon config if present
const fs = require('fs');
const localConfigPath = path.join(currentPath, 'nodemon.json');
// if it is present - merge it with default config
if (fs.existsSync(localConfigPath)) {
nodemonConfig = {
...nodemonConfig,
...require(localConfigPath),
};
}

// start nodemon
nodemon(nodemonConfig);

// report changes
nodemon
Expand Down
2 changes: 1 addition & 1 deletion packages/graffiti/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "graffiti",
"version": "0.7.0",
"version": "0.8.0",
"description": "Minimalistic GraphQL framework",
"repository": "yamalight/graffiti",
"bugs": "https://github.com/yamalight/graffiti/issues",
Expand Down

0 comments on commit 62773a0

Please sign in to comment.