Skip to content

Commit

Permalink
feat(config): update ignores to advanced pattern (#2035)
Browse files Browse the repository at this point in the history
  • Loading branch information
davestewart committed Jun 9, 2023
1 parent d0e5d6a commit 0fb0d63
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 93 deletions.
29 changes: 4 additions & 25 deletions docs/content/4.api/3.configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,40 +117,19 @@ It is highly recommended to prevent modifying default source. If you want to loa

## `ignores`

- Type: `string[] | object[]`{lang=ts}
- Type: `string[]`{lang=ts}
- Default: `['\\.', '-']`{lang=ts}

List of ignore patterns to exclude content from parsing, rendering and watching.

Note that under the hood:
Note that:

- paths are managed by [unstorage](https://unstorage.unjs.io/usage#usage-1), so you will need to use `:` in place of `/`
- patterns are converted to Regular Expressions, so you will need to escape appropriately
- patterns are actually _prefixes_; use a match-all pattern to negate this (see final example)
- patterns are converted to regular expressions
- `.` and `-` prefixed files are ignored by default

```ts [nuxt.config.ts]
export default defineNuxtConfig({
content: {
ignores: [
'hidden', // any file or folder prefixed with the word "hidden"
'hidden:', // any folder that exactly matches the word "hidden"
'path:to:file', // any file path matching "/path/to/file"
'.+\\.bak$', // any file with the extension ".bak"
]
}
})
```

From version 2.7 `ignores` will support a more flexible, idiomatic format.

You can use this from version 2.6 using the `experimental.advancedIgnoresPattern` flag:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
content: {
experimental: {
advancedIgnoresPattern: true
},
ignores: [
'hidden', // any file or folder that contains the word "hidden"
'/hidden/', // any folder that exactly matches the word "hidden"
Expand Down
4 changes: 0 additions & 4 deletions playground/basic/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ export default defineNuxtConfig({
}
},

experimental: {
advancedIgnoresPattern: true
},

ignores: [
'\\.bak$',
'ignored/folder'
Expand Down
16 changes: 4 additions & 12 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,7 @@ export interface ModuleOptions {
},
experimental: {
clientDB: boolean
stripQueryParameters: boolean,
advancedIgnoresPattern: boolean
stripQueryParameters: boolean
}
}

Expand Down Expand Up @@ -284,8 +283,7 @@ export default defineNuxtModule<ModuleOptions>({
documentDriven: false,
experimental: {
clientDB: false,
stripQueryParameters: false,
advancedIgnoresPattern: false
stripQueryParameters: false
}
},
async setup (options, nuxt) {
Expand Down Expand Up @@ -605,8 +603,7 @@ export default defineNuxtModule<ModuleOptions>({
integrity: buildIntegrity,
experimental: {
stripQueryParameters: options.experimental.stripQueryParameters,
clientDB: options.experimental.clientDB && nuxt.options.ssr === false,
advancedIgnoresPattern: options.experimental.advancedIgnoresPattern
clientDB: options.experimental.clientDB && nuxt.options.ssr === false
},
api: {
baseURL: options.api.baseURL
Expand Down Expand Up @@ -646,11 +643,7 @@ export default defineNuxtModule<ModuleOptions>({
})

// ignore files
const { advancedIgnoresPattern } = contentContext.experimental
const isIgnored = makeIgnored(contentContext.ignores, advancedIgnoresPattern)
if (contentContext.ignores.length && !advancedIgnoresPattern) {
logger.warn('The `ignores` config is being made more flexible in version 2.7. See the docs for more information: `https://content.nuxtjs.org/api/configuration#ignores`')
}
const isIgnored = makeIgnored(contentContext.ignores)

// Setup content dev module
if (!nuxt.options.dev) {
Expand Down Expand Up @@ -735,7 +728,6 @@ interface ModulePublicRuntimeConfig {
experimental: {
stripQueryParameters: boolean
clientDB: boolean
advancedIgnoresPattern: boolean
}

defaultLocale: ModuleOptions['defaultLocale']
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/server/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const contentConfig = useRuntimeConfig().content
/**
* Content ignore patterns
*/
const isIgnored = makeIgnored(contentConfig.ignores, contentConfig.experimental.advancedIgnoresPattern)
const isIgnored = makeIgnored(contentConfig.ignores)

/**
* Invalid key characters
Expand Down
20 changes: 4 additions & 16 deletions src/runtime/utils/config.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
/**
* Creates a predicate to test storage keys `foo:bar:baz` against configured `ignores` patterns
*/
export function makeIgnored (ignores: string[], experimental = false): (key: string) => boolean {
// filter empty
ignores = ignores.map(e => e)

// 2.7+ supports free regexp + slashes
if (experimental) {
const rxAll = ['/\\.', '/-', ...ignores].map(p => new RegExp(p))
return function isIgnored (key: string): boolean {
const path = '/' + key.replaceAll(':', '/')
return rxAll.some(rx => rx.test(path))
}
}

// 2.6 prefixed by unstorage delimiters
const rxAll = ['\\.', '-', ...ignores].map(p => new RegExp(`^${p}|:${p}`))
export function makeIgnored (ignores: string[]): (key: string) => boolean {
const rxAll = ['/\\.', '/-', ...ignores.filter(p => p)].map(p => new RegExp(p))
return function isIgnored (key: string): boolean {
return rxAll.some(rx => rx.test(key))
const path = '/' + key.replaceAll(':', '/')
return rxAll.some(rx => rx.test(path))
}
}
52 changes: 17 additions & 35 deletions test/features/ignores.ts
Original file line number Diff line number Diff line change
@@ -1,64 +1,46 @@
import { describe, test, expect } from 'vitest'
import { makeIgnored } from '../../src/runtime/utils/config'

function run (key: string, pattern: string, result: boolean, experimental: boolean) {
const predicate = makeIgnored([pattern], experimental)
const label: string = experimental ? 'new format' : 'old format'
test(label, () => {
expect(predicate(key)).toBe(result)
})
}

function runOld (pattern: string, key: string, result: boolean) {
return run(key, pattern, result, false)
}

function runNew (pattern: string, key: string, result: boolean) {
return run(key, pattern, result, true)
function run (pattern: string, key: string, result: boolean) {
const isIgnored = makeIgnored([pattern])
expect(isIgnored(key)).toBe(result)
}

export const testIgnores = () => {
describe('Ignores Options', () => {
describe('any file or folder that contains the word "hidden"', () => {
test('ignore any file or folder that contains the word "hidden"', () => {
const key = 'source:content:my-hidden-folder:index.md'
runOld('.+hidden', key, true)
runNew('hidden', key, true)
run('hidden', key, true)
})

describe('any file or folder prefixed with the word "hidden"', () => {
test('ignore any file or folder prefixed with the word "hidden"', () => {
const key = 'source:content:hidden-folder:index.md'
runOld('hidden', key, true)
runNew('/hidden', key, true)
run('/hidden', key, true)
})

describe('any folder that exactly matches the word "hidden"', () => {
test('ignore any folder that exactly matches the word "hidden"', () => {
const key = 'source:content:hidden:index.md'
runOld('hidden:', key, true)
runNew('/hidden/', key, true)
run('/hidden/', key, true)
})

describe('any file path matching "/path/to/file"', () => {
test('ignore any file path matching "/path/to/file"', () => {
const key = 'source:content:path:to:file.md'
runOld('path:to:file', key, true)
runNew('/path/to/file', key, true)
run('/path/to/file', key, true)
})

describe('any file with the extension ".bak"', () => {
test('ignore any file with the extension ".bak"', () => {
const key = 'source:content:path:to:ignored.bak'
runOld('.+\\.bak$', key, true)
runNew('\\.bak$', key, true)
run('\\.bak$', key, true)
})

describe('any file with a leading dash', () => {
test('ignore any file with a leading dash', () => {
const key = 'source:content:path:to:-dash.txt'
runOld('', key, true)
runNew('', key, true)
run('', key, true)
})

describe('any file with a leading dot', () => {
test('ignore any file with a leading dot', () => {
const key = 'source:content:path:to:.dot.txt'
runOld('', key, true)
runNew('', key, true)
run('', key, true)
})
})
}

0 comments on commit 0fb0d63

Please sign in to comment.