Skip to content

Commit

Permalink
fix: correctly ignore folders
Browse files Browse the repository at this point in the history
BREAKING CHANGE: if you were relying on the broken behavior of
`exclude`, you will have to adapt the paths provided to it. They are no
longer relative to the `routesFolder.src`, instead they are relative
to the cwd, like other paths.
  • Loading branch information
posva committed May 18, 2023
1 parent ec916a8 commit cbd14b9
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 32 deletions.
7 changes: 5 additions & 2 deletions playground/vite.config.ts
Expand Up @@ -80,7 +80,9 @@ export default defineConfig({
{
src: 'src/docs',
path: 'docs/:lang/',
// doesn't take into account files directly at src/docs, only subfolders
filePatterns: ['*/**/*'],
// ignores .vue files
extensions: ['.md'],
},
// {
Expand All @@ -91,10 +93,11 @@ export default defineConfig({
logs: true,
// getRouteName: getPascalCaseRouteName,
exclude: [
'ignored',
'**/ignored/**',
// '**/ignored/**/*',
'**/__*',
'**/__**/*',
'!*.component.vue',
// '!*.component.vue',
// resolve(__dirname, './src/pages/ignored'),
//
// './src/pages/**/*.spec.ts',
Expand Down
42 changes: 28 additions & 14 deletions src/core/RoutesFolderWatcher.ts
@@ -1,16 +1,16 @@
import chokidar from 'chokidar'
import { normalize } from 'pathe'
import { resolve } from 'pathe'
import {
ResolvedOptions,
RoutesFolderOption,
RoutesFolderOptionResolved,
_OverridableOption,
} from '../options'
import { asRoutePath } from './utils'
import { appendExtensionListToPattern, asRoutePath } from './utils'

// TODO: export an implementable interface to create a watcher and let users provide a different watcher than chokidar to improve performance on windows

export class RoutesFolderWatcher implements RoutesFolderOptionResolved {
export class RoutesFolderWatcher {
src: string
path: string
extensions: string[]
Expand All @@ -26,11 +26,13 @@ export class RoutesFolderWatcher implements RoutesFolderOptionResolved {
this.extensions = folderOptions.extensions
this.filePatterns = folderOptions.filePatterns

this.watcher = chokidar.watch(this.src, {
this.watcher = chokidar.watch(folderOptions.pattern, {
cwd: this.src,
ignoreInitial: true,
// disableGlobbing: true,
ignorePermissionErrors: true,
ignored: this.exclude,

// useFsEvents: true,
// TODO: allow user options
})
Expand All @@ -41,12 +43,14 @@ export class RoutesFolderWatcher implements RoutesFolderOptionResolved {
handler: (context: HandlerContext) => void
) {
this.watcher.on(event, (filePath: string) => {
// ensure consistent path for Windows and Unix
filePath = normalize(filePath)
// skip other extensions
if (this.extensions.every((extension) => !filePath.endsWith(extension))) {
return
}

// ensure consistent absolute path for Windows and Unix
filePath = resolve(this.src, filePath)

handler({
filePath,
routePath: asRoutePath({ src: this.src, path: this.path }, filePath),
Expand All @@ -71,17 +75,27 @@ export function resolveFolderOptions(
globalOptions: ResolvedOptions,
folderOptions: RoutesFolderOption
): RoutesFolderOptionResolved {
const extensions = overrideOption(
globalOptions.extensions,
folderOptions.extensions
)
const filePatterns = overrideOption(
globalOptions.filePatterns,
folderOptions.filePatterns
)

return {
src: folderOptions.src,
path: folderOptions.path || '',
extensions: overrideOption(
globalOptions.extensions,
folderOptions.extensions
pattern: appendExtensionListToPattern(
filePatterns,
// also override the extensions if the folder has a custom extensions
extensions
),
exclude: overrideOption(globalOptions.exclude, folderOptions.exclude),
filePatterns: overrideOption(
globalOptions.filePatterns,
folderOptions.filePatterns
path: folderOptions.path || '',
extensions,
filePatterns,
exclude: overrideOption(globalOptions.exclude, folderOptions.exclude).map(
(p) => (p.startsWith('**') ? p : resolve(p))
),
}
}
Expand Down
30 changes: 16 additions & 14 deletions src/core/context.ts
Expand Up @@ -12,7 +12,7 @@ import { generateRouteNamedMap } from '../codegen/generateRouteMap'
import { MODULE_ROUTES_PATH, MODULE_VUE_ROUTER } from './moduleConstants'
import { generateRouteRecord } from '../codegen/generateRouteRecords'
import fg from 'fast-glob'
import { resolve } from 'pathe'
import { relative, resolve } from 'pathe'
import { ServerContext } from '../options'
import { getRouteBlock } from './customBlock'
import {
Expand Down Expand Up @@ -68,28 +68,30 @@ export function createRoutesContext(options: ResolvedOptions) {
watchers.push(setupWatcher(new RoutesFolderWatcher(folder)))
}

// override the pattern if the folder has a custom pattern
const pattern = appendExtensionListToPattern(
folder.filePatterns,
// also override the extensions if the folder has a custom extensions
folder.extensions
// the ignore option must be relative to cwd or absolute
const ignorePattern = folder.exclude.map((f) =>
// if it starts with ** then it will work as expected
f.startsWith('**') ? f : relative(folder.src, f)
)

return fg(pattern, {
return fg(folder.pattern, {
cwd: folder.src,
// TODO: do they return the symbolic link path or the original file?
// followSymbolicLinks: false,
ignore: folder.exclude,
ignore: ignorePattern,
})
.then((files) => files.map((file) => resolve(folder.src, file)))
.then((files) =>
Promise.all(
files.map((file) =>
addPage({
routePath: asRoutePath(folder, file),
filePath: file,
})
)
files
// ensure consistent files in Windows/Unix and absolute paths
.map((file) => resolve(folder.src, file))
.map((file) =>
addPage({
routePath: asRoutePath(folder, file),
filePath: file,
})
)
)
)
})
Expand Down
8 changes: 8 additions & 0 deletions src/core/utils.ts
Expand Up @@ -259,6 +259,14 @@ export function asRoutePath(
* @param extensions array of extensions to append to the pattern e.g. ['.vue', '.js']
* @returns
*/
export function appendExtensionListToPattern(
filePatterns: string,
extensions: string[]
): string
export function appendExtensionListToPattern(
filePatterns: string[],
extensions: string[]
): string[]
export function appendExtensionListToPattern(
filePatterns: string | string[],
extensions: string[]
Expand Down
9 changes: 7 additions & 2 deletions src/options.ts
Expand Up @@ -41,6 +41,10 @@ export interface RoutesFolderOption {
*/
export interface RoutesFolderOptionResolved extends RoutesFolderOption {
path: string
/**
* Final glob pattern to match files in the folder.
*/
pattern: string[]
filePatterns: string[]
exclude: string[]
extensions: string[]
Expand Down Expand Up @@ -68,8 +72,9 @@ export interface ResolvedOptions {
routesFolder: RoutesFolderOption[]

/**
* Array of `picomatch` globs to ignore. Defaults to `[]`. Note the globs are relative to the `routesFolder`, so avoid
* writing something like `['src/pages']` as **it won't match anything**.
* Array of `picomatch` globs to ignore. Defaults to `[]`. Note the globs are relative to the cwd, so avoid writing
* something like `['ignored']` to match folders named that way, instead provide a path similar to the `routesFolder`:
* `['src/pages/ignored/**']` or use `['**​/ignored']` to match every folder named `ignored`.
*/
exclude: string[]

Expand Down

0 comments on commit cbd14b9

Please sign in to comment.