Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gatsby-page-utils): extract logic for watching a directory from gatsby-page-creator so can reuse for custom page creation #14051

Merged
merged 16 commits into from
Jun 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/gatsby-page-utils/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": [["babel-preset-gatsby-package", { "browser": true }]]
}
32 changes: 32 additions & 0 deletions packages/gatsby-page-utils/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules

decls
dist

/*.js
96 changes: 96 additions & 0 deletions packages/gatsby-page-utils/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# gatsby-page-utils

## Usage

```sh
npm install gatsby-page-utils
```

### Example

```js
const {
createPath,
ignorePath,
validatePath,
watchDirectory,
} = require(`gatsby-page-utils`)

// ...

const pagesDirectory = "/pages"
watchDirectory(
pagesDirectory,
"**/*.{js, jsx}",
addedPath => {
// Filter out special components that shouldn't be made into
// pages.
if (!validatePath(addedPath)) {
return
}

// Filter out anything matching the given ignore patterns and options
if (ignorePath(addedPath, "*/connexion")) {
return
}

// Create page object
const createdPath = createPath(addedPath)
const page = {
path: createdPath,
component: systemPath.join(pagesDirectory, addedPath),
}

// Add page
createPage(page)
},
removedPath => {
// Delete the page for the now deleted component.
const componentPath = systemPath.join(pagesDirectory, removedPath)
store.getState().pages.forEach(page => {
if (page.component === componentPath) {
deletePage({
path: createPath(removedPath),
component: componentPath,
})
}
})
}
)
```

#### watchDirectory

Watch activity on a directory and call functions each time a file is added or removed

| property | description | type |
| ------------- | ----------------------------------------------- | -------- |
| path | Directory path in which pages are stored | String |
| glob | A glob that select files to watch | String |
| onNewFile | A function called each time a new file is added | Function |
| onRemovedFile | A function called each time a file is removed | Function |

#### createPath

Create a page path from a file path. It returns the page path.

| property | description | type |
| -------- | ----------- | ------ |
| path | File path | String |

#### validatePath

Validate a file path. It veryfies that it doesn't contains specific characters or strings. It returns `true` if path is valid otherwise it returns `false`.

| property | description | type |
| -------- | ----------- | ------ |
| path | File path | String |

#### ignorePath

Determines if path should be ignored regarding of a ignore pattern passed as parameter. It returns `true` if the passed path should be ignored otherwise it returns `false`.

| property | description | type |
| -------- | --------------------------------- | ------- |
| path | File path | String |
| ignore | A pattern to match with file path | (Object | String | Array) |
39 changes: 39 additions & 0 deletions packages/gatsby-page-utils/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "gatsby-page-utils",
"version": "0.0.1",
"description": "Gatsby library that helps creating pages",
"main": "dist/index.js",
"scripts": {
"build": "babel src --out-dir dist/ --ignore **/__tests__",
"watch": "babel -w src --out-dir dist/ --ignore **/__tests__",
"prepare": "cross-env NODE_ENV=production npm run build"
},
"keywords": [
"gatsby"
],
"author": "Yvonnick FRIN <frin.yvonnick@gmail.com>",
"license": "MIT",
"repository": "https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-page-utils",
"dependencies": {
"@babel/runtime": "^7.0.0",
"bluebird": "^3.5.0",
"chokidar": "2.1.2",
"fs-exists-cached": "^1.0.0",
"glob": "^7.1.1",
"lodash": "^4.17.10",
"micromatch": "^3.1.10",
"slash": "^1.0.0"
},
"devDependencies": {
"@babel/cli": "^7.0.0",
"@babel/core": "^7.0.0",
"babel-preset-gatsby-package": "^0.1.4",
"cross-env": "^5.0.5"
},
"peerDependencies": {
"gatsby": "^2.0.0"
},
"files": [
"dist/*"
]
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`JavaScript page creator create-path should create unix paths 1`] = `
exports[`create-path should create unix paths 1`] = `
Array [
"/b/c/de/",
"/bee/",
Expand Down
9 changes: 9 additions & 0 deletions packages/gatsby-page-utils/src/__tests__/create-path.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const createPath = require(`../create-path`)

describe(`create-path`, () => {
it(`should create unix paths`, () => {
const paths = [`b/c/de`, `bee`, `b/d/c/`]

expect(paths.map(p => createPath(p))).toMatchSnapshot()
})
})
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const validatePath = require(`../validate-path`)
const createPath = require(`../create-path`)

describe(`JavaScript page creator`, () => {
describe(`validatePath`, () => {
it(`includes the correct file types`, () => {
const validFiles = [
{ path: `test1.js` },
Expand Down Expand Up @@ -116,12 +115,4 @@ describe(`JavaScript page creator`, () => {
validFiles
)
})

describe(`create-path`, () => {
it(`should create unix paths`, () => {
const paths = [`b/c/de`, `bee`, `b/d/c/`]

expect(paths.map(p => createPath(p))).toMatchSnapshot()
})
})
})
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @flow
import path from "path"
const path = require(`path`)

module.exports = (filePath: string): string => {
const { dir, name } = path.parse(filePath)
Expand Down
6 changes: 6 additions & 0 deletions packages/gatsby-page-utils/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
validatePath: require(`./validate-path`),
createPath: require(`./create-path`),
ignorePath: require(`./ignore-path`),
watchDirectory: require(`./watch-directory`),
}
18 changes: 18 additions & 0 deletions packages/gatsby-page-utils/src/watch-directory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const Promise = require(`bluebird`)
const chokidar = require(`chokidar`)
const slash = require(`slash`)

module.exports = async (path, glob, onNewFile, onRemovedFile) =>
new Promise((resolve, reject) => {
chokidar
.watch(glob, { cwd: path })
.on(`add`, path => {
path = slash(path)
onNewFile(path)
})
.on(`unlink`, path => {
path = slash(path)
onRemovedFile(path)
})
.on(`ready`, () => resolve())
})
5 changes: 2 additions & 3 deletions packages/gatsby-plugin-page-creator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,11 @@
"dependencies": {
wardpeet marked this conversation as resolved.
Show resolved Hide resolved
"@babel/runtime": "^7.0.0",
"bluebird": "^3.5.0",
"chokidar": "2.1.2",
"fs-exists-cached": "^1.0.0",
"gatsby-page-utils": "^0.0.1",
"glob": "^7.1.1",
"lodash": "^4.17.10",
"micromatch": "^3.1.10",
"slash": "^1.0.0"
"micromatch": "^3.1.10"
},
"devDependencies": {
"@babel/cli": "^7.0.0",
Expand Down
41 changes: 20 additions & 21 deletions packages/gatsby-plugin-page-creator/src/gatsby-node.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
const globCB = require(`glob`)
const Promise = require(`bluebird`)
const _ = require(`lodash`)
const chokidar = require(`chokidar`)
const systemPath = require(`path`)
const existsSync = require(`fs-exists-cached`).sync

const glob = Promise.promisify(globCB)

const createPath = require(`./create-path`)
const validatePath = require(`./validate-path`)
const ignorePath = require(`./ignore-path`)
const slash = require(`slash`)
const {
createPath,
validatePath,
ignorePath,
watchDirectory,
} = require(`gatsby-page-utils`)

// Path creator.
// Auto-create pages.
Expand Down Expand Up @@ -56,31 +57,29 @@ exports.createPagesStatefully = async (
let files = await glob(pagesGlob, { cwd: pagesPath })
files.forEach(file => _createPage(file, pagesDirectory, createPage, ignore))

// Listen for new component pages to be added or removed.
chokidar
.watch(pagesGlob, { cwd: pagesPath })
.on(`add`, path => {
path = slash(path)
if (!_.includes(files, path)) {
_createPage(path, pagesDirectory, createPage, ignore)
files.push(path)
watchDirectory(
pagesPath,
pagesGlob,
addedPath => {
if (!_.includes(files, addedPath)) {
_createPage(addedPath, pagesDirectory, createPage, ignore)
files.push(addedPath)
}
})
.on(`unlink`, path => {
path = slash(path)
},
removedPath => {
// Delete the page for the now deleted component.
const componentPath = systemPath.join(pagesDirectory, removedPath)
store.getState().pages.forEach(page => {
const componentPath = systemPath.join(pagesDirectory, path)
if (page.component === componentPath) {
deletePage({
path: createPath(path),
path: createPath(removedPath),
component: componentPath,
})
}
})
files = files.filter(f => f !== path)
})
.on(`ready`, () => doneCb())
files = files.filter(f => f !== removedPath)
}
).then(() => doneCb())
}
const _createPage = (filePath, pagesDirectory, createPage, ignore) => {
// Filter out special components that shouldn't be made into
Expand Down