feat(v2): add support to ignore files in pages plugin (#3196)

* add support to ignore pages

* fix import problem

* Update website/docs/guides/creating-pages.md

Co-authored-by: Sébastien Lorber <slorber@users.noreply.github.com>

* Revert "fix import problem"

This reverts commit 4457a2e938.

* revert

* fix slash

* forbid frontmatter

* fix formatting

* Update website/docs/guides/creating-pages.md

* Update website/src/pages/examples/_chapter1.md

* Update website/src/pages/examples/_chapter2.mdx

* Update website/src/pages/examples/markdownPageExample.md

* Update website/src/pages/examples/markdownPageExample.md

* Update website/src/pages/examples/markdownPageExample.md

* Update website/src/pages/examples/markdownPageExample.md

Co-authored-by: Sébastien Lorber <slorber@users.noreply.github.com>
This commit is contained in:
Anshul Goyal 2020-08-06 01:05:55 +05:30 committed by GitHub
parent 592fc48fd3
commit f234c407f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 82 additions and 7 deletions

View file

@ -72,6 +72,17 @@ module.exports = async function (fileString) {
} }
} }
if (
options.forbidFrontMatter &&
typeof options.forbidFrontMatter === 'function'
) {
if (
options.forbidFrontMatter(this.resourcePath) &&
Object.keys(data).length > 0
) {
return callback(new Error(`Front matter is forbidden in this file`));
}
}
const code = ` const code = `
import React from 'react'; import React from 'react';
import { mdx } from '@mdx-js/react'; import { mdx } from '@mdx-js/react';

View file

@ -23,7 +23,9 @@
"@hapi/joi": "17.1.1", "@hapi/joi": "17.1.1",
"globby": "^10.0.1", "globby": "^10.0.1",
"loader-utils": "^1.2.3", "loader-utils": "^1.2.3",
"remark-admonitions": "^1.2.1" "minimatch": "^3.0.4",
"remark-admonitions": "^1.2.1",
"slash": "^3.0.0"
}, },
"peerDependencies": { "peerDependencies": {
"@docusaurus/core": "^2.0.0", "@docusaurus/core": "^2.0.0",

View file

@ -0,0 +1 @@
export default (a:number,b:number)=>a+b;

View file

@ -10,7 +10,7 @@ import {PluginOptions} from '../types';
export default function normalizePluginOptions( export default function normalizePluginOptions(
options: Partial<PluginOptions>, options: Partial<PluginOptions>,
) { ): PluginOptions {
const {value, error} = PluginOptionSchema.validate(options, { const {value, error} = PluginOptionSchema.validate(options, {
convert: false, convert: false,
}); });
@ -37,6 +37,7 @@ describe('normalizePagesPluginOptions', () => {
path: 'src/my-pages', path: 'src/my-pages',
routeBasePath: 'my-pages', routeBasePath: 'my-pages',
include: ['**/*.{js,jsx,ts,tsx}'], include: ['**/*.{js,jsx,ts,tsx}'],
exclude: ['**/$*/'],
}; };
const value = normalizePluginOptions(userOptions); const value = normalizePluginOptions(userOptions);
expect(value).toEqual({...DEFAULT_OPTIONS, ...userOptions}); expect(value).toEqual({...DEFAULT_OPTIONS, ...userOptions});

View file

@ -8,6 +8,8 @@
import globby from 'globby'; import globby from 'globby';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import minimatch from 'minimatch';
import slash from 'slash';
import { import {
encodePath, encodePath,
fileToPath, fileToPath,
@ -51,6 +53,11 @@ export default function pluginContentPages(
); );
const dataDir = path.join(pluginDataDirRoot, options.id ?? DEFAULT_PLUGIN_ID); const dataDir = path.join(pluginDataDirRoot, options.id ?? DEFAULT_PLUGIN_ID);
const excludeRegex = new RegExp(
options.exclude
.map((pattern) => minimatch.makeRe(pattern).source)
.join('|'),
);
return { return {
name: 'docusaurus-plugin-content-pages', name: 'docusaurus-plugin-content-pages',
@ -81,6 +88,7 @@ export default function pluginContentPages(
const {baseUrl} = siteConfig; const {baseUrl} = siteConfig;
const pagesFiles = await globby(include, { const pagesFiles = await globby(include, {
cwd: pagesDir, cwd: pagesDir,
ignore: options.exclude,
}); });
function toMetadata(relativeSource: string): Metadata { function toMetadata(relativeSource: string): Metadata {
@ -173,12 +181,17 @@ export default function pluginContentPages(
// Note that metadataPath must be the same/in-sync as // Note that metadataPath must be the same/in-sync as
// the path from createData for each MDX. // the path from createData for each MDX.
metadataPath: (mdxPath: string) => { metadataPath: (mdxPath: string) => {
const aliasedPath = aliasedSitePath(mdxPath, siteDir); if (excludeRegex.test(slash(mdxPath))) {
return null;
}
const aliasedSource = aliasedSitePath(mdxPath, siteDir);
return path.join( return path.join(
dataDir, dataDir,
`${docuHash(aliasedPath)}.json`, `${docuHash(aliasedSource)}.json`,
); );
}, },
forbidFrontMatter: (mdxPath: string) =>
excludeRegex.test(slash(mdxPath)),
}, },
}, },
{ {

View file

@ -20,12 +20,18 @@ export const DEFAULT_OPTIONS: PluginOptions = {
remarkPlugins: [], remarkPlugins: [],
rehypePlugins: [], rehypePlugins: [],
admonitions: {}, admonitions: {},
exclude: [
'**/_*.{js,jsx,ts,tsx,md,mdx}',
'**/*.test.{js,ts}',
'**/__tests__/**',
],
}; };
export const PluginOptionSchema = Joi.object({ export const PluginOptionSchema = Joi.object({
path: Joi.string().default(DEFAULT_OPTIONS.path), path: Joi.string().default(DEFAULT_OPTIONS.path),
routeBasePath: Joi.string().default(DEFAULT_OPTIONS.routeBasePath), routeBasePath: Joi.string().default(DEFAULT_OPTIONS.routeBasePath),
include: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.include), include: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.include),
exclude: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.exclude),
mdxPageComponent: Joi.string().default(DEFAULT_OPTIONS.mdxPageComponent), mdxPageComponent: Joi.string().default(DEFAULT_OPTIONS.mdxPageComponent),
remarkPlugins: RemarkPluginsSchema.default(DEFAULT_OPTIONS.remarkPlugins), remarkPlugins: RemarkPluginsSchema.default(DEFAULT_OPTIONS.remarkPlugins),
rehypePlugins: RehypePluginsSchema.default(DEFAULT_OPTIONS.rehypePlugins), rehypePlugins: RehypePluginsSchema.default(DEFAULT_OPTIONS.rehypePlugins),

View file

@ -10,6 +10,7 @@ export interface PluginOptions {
path: string; path: string;
routeBasePath: string; routeBasePath: string;
include: string[]; include: string[];
exclude: string[];
mdxPageComponent: string; mdxPageComponent: string;
remarkPlugins: ([Function, object] | Function)[]; remarkPlugins: ([Function, object] | Function)[];
rehypePlugins: string[]; rehypePlugins: string[];

View file

@ -91,7 +91,7 @@ In this component-based development era, it is encouraged to co-locate your styl
- Add a `/src/pages/support.js` file - Add a `/src/pages/support.js` file
- Create a `/src/pages/support/` directory and a `/src/pages/support/index.js` file. - Create a `/src/pages/support/` directory and a `/src/pages/support/index.js` file.
The latter is preferred as it has the benefits of letting you put files related to the page within that directory. For example, a CSS module file (`styles.module.css`) with styles meant to only be used on the "Support" page. **Note:** this is merely a recommended directory structure and you will still need to manually import the CSS module file within your component module (`support/index.js`). The latter is preferred as it has the benefits of letting you put files related to the page within that directory. For example, a CSS module file (`styles.module.css`) with styles meant to only be used on the "Support" page. **Note:** this is merely a recommended directory structure and you will still need to manually import the CSS module file within your component module (`support/index.js`). By default, any Markdown or Javascript file starting with `_` will be ignored, and no routes will be created for that file (see the `exclude` option).
```sh ```sh
my-website my-website
@ -99,6 +99,7 @@ my-website
│ └── pages │ └── pages
│ ├── styles.module.css │ ├── styles.module.css
│ ├── index.js │ ├── index.js
| ├──_ignored.js
│ └── support │ └── support
│ ├── index.js │ ├── index.js
│ └── styles.module.css │ └── styles.module.css
@ -107,7 +108,7 @@ my-website
:::caution :::caution
All JavaScript/TypeScript files within the `src/pages/` directory will have corresponding website paths generated for them. Do not put reusable components or test files (ending with `.test.js`) into that directory otherwise they will be turned into pages, which might not be intended. All JavaScript/TypeScript files within the `src/pages/` directory will have corresponding website paths generated for them. If you want to create reusable components into that directory, use the `exclude` option (by default, files prefixed with `_`, test files(`.test.js`) and files in `__tests__` directory are not turned into pages).
::: :::

View file

@ -375,7 +375,15 @@ module.exports = {
* do not include trailing slash * do not include trailing slash
*/ */
routeBasePath: '', routeBasePath: '',
include: ['**/*.{js,jsx}'], include: ['**/*.{js,jsx,ts,tsx,md,mdx}'],
/**
* No Route will be created for matching files
*/
exclude: [
'**/_*.{js,jsx,ts,tsx,md,mdx}',
'**/*.test.{js,ts}',
'**/__tests__/**',
],
/** /**
* Theme component used by markdown pages. * Theme component used by markdown pages.
*/ */

View file

@ -0,0 +1,3 @@
# Chapter 1
Lorem ipsum chapter 1

View file

@ -0,0 +1,3 @@
# Chapter 2
Lorem ipsum chapter 2

View file

@ -32,3 +32,25 @@ import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
<Tabs defaultValue="apple" values={[ {label: 'Apple', value: 'apple'}, {label: 'Orange', value: 'orange'}, {label: 'Banana', value: 'banana'} ]}><TabItem value="apple">This is an apple 🍎</TabItem><TabItem value="orange">This is an orange 🍊</TabItem><TabItem value="banana">This is a banana 🍌</TabItem></Tabs> <Tabs defaultValue="apple" values={[ {label: 'Apple', value: 'apple'}, {label: 'Orange', value: 'orange'}, {label: 'Banana', value: 'banana'} ]}><TabItem value="apple">This is an apple 🍎</TabItem><TabItem value="orange">This is an orange 🍊</TabItem><TabItem value="banana">This is a banana 🍌</TabItem></Tabs>
## Import Mdx and Md files
```js
// *.md file
import Chapter1 from './_chapter1.md';
<Chapter1 />
// *.mdx file
import Chapter2 from './_chapter2.mdx';
<Chapter2 />
```
import Chapter1 from './\_chapter2.mdx';
<Chapter1/>
import Chapter2 from './\_chapter2.mdx';
<Chapter2/>