Skip to content
This repository has been archived by the owner on Jul 29, 2022. It is now read-only.

Commit

Permalink
fix: return absolute paths if one of the globs is absolute (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
brillout committed Mar 30, 2022
1 parent 16e7c7e commit 394c0c9
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 31 deletions.
12 changes: 6 additions & 6 deletions src/index.ts
Expand Up @@ -9,16 +9,16 @@ export default function(options: PluginOptions = {}): Plugin {
const map = new Map<string, string[][]>()

function updateMap(id: string, info: ParsedImportGlob[]) {
const globs = info.map(i => i.absoluteGlobs)
map.set(id, globs)
// add those globs to the wather
server?.watcher.add(globs.flatMap(i => i.filter(i => i[0] !== '!')))
const allGlobs = info.map(i => i.globsResolved)
map.set(id, allGlobs)
// add those allGlobs to the watcher
server?.watcher.add(allGlobs.flatMap(i => i.filter(i => i[0] !== '!')))
}

function getAffectedModules(file: string) {
const modules: ModuleNode[] = []
for (const [id, globs] of map) {
if (globs.some(glob => isMatch(file, glob)))
for (const [id, allGlobs] of map) {
if (allGlobs.some(glob => isMatch(file, glob)))
modules.push(...(server?.moduleGraph.getModulesByFile(id) || []))
}
return modules
Expand Down
6 changes: 4 additions & 2 deletions src/parse.ts
Expand Up @@ -158,13 +158,15 @@ export function parseImportGlob(

const end = ast.range![1] + 1

const absoluteGlobs = globs.map(glob => toAbsoluteGlob(glob, root, dir))
const globsResolved = globs.map(glob => toAbsoluteGlob(glob, root, dir))
const isRelative = globs.every(i => '.!'.includes(i[0]))

return {
match,
index,
globs,
absoluteGlobs,
globsResolved,
isRelative,
options,
type,
start,
Expand Down
51 changes: 34 additions & 17 deletions src/transform.ts
Expand Up @@ -4,19 +4,18 @@ import fg from 'fast-glob'
import { stringifyQuery } from 'ufo'
import type { PluginOptions } from '../types'
import { parseImportGlob } from './parse'
import { isCSSRequest } from './utils'
import { assert, isCSSRequest } from './utils'

const importPrefix = '__vite_glob_next_'

const { basename, dirname, relative } = posix
const { dirname, relative } = posix

export async function transform(
code: string,
id: string,
root: string,
options?: PluginOptions,
) {
const filename = basename(id)
const dir = dirname(id)
let matches = parseImportGlob(code, dir, root)

Expand All @@ -40,17 +39,9 @@ export async function transform(
const s = new MagicString(code)

const staticImports = (await Promise.all(
matches.map(async({ absoluteGlobs, options, index, start, end }) => {
const files = (await fg(absoluteGlobs, { dot: true, absolute: true, cwd: root }))
.map((i) => {
const path = relative(dir, i)
if (path === filename)
return undefined!
if ('./'.includes(path[0]))
return path
return `./${path}`
})
.filter(Boolean)
matches.map(async({ globsResolved, isRelative, options, index, start, end }) => {
const files = (await fg(globsResolved, { dot: true, absolute: true, cwd: root }))
.filter(file => file !== id)
.sort()

const objectProps: string[] = []
Expand All @@ -65,8 +56,34 @@ export async function transform(
if (query && !query.startsWith('?'))
query = `?${query}`

const resolvePaths = (file: string) => {
assert(file.startsWith('/'))

let importPath = relative(dir, file)
assert(!importPath.startsWith('/'))
if (!importPath.startsWith('.'))
importPath = `./${importPath}`

let filePath: string
if (isRelative) {
filePath = importPath
}
else {
filePath = relative(root, file)
assert(!filePath.startsWith('/'))
if (!filePath.startsWith('.'))
filePath = `/${filePath}`
}

return { filePath, importPath }
}

files.forEach((file, i) => {
let importPath = `${file}${query}`
const paths = resolvePaths(file)
const { filePath } = paths
let { importPath } = paths

importPath = `${importPath}${query}`
if (isCSSRequest(file))
importPath = query ? `${importPath}&used` : `${importPath}?used`

Expand All @@ -76,13 +93,13 @@ export async function transform(
? `{ ${options.export} as ${variableName} }`
: `* as ${variableName}`
staticImports.push(`import ${expression} from ${JSON.stringify(importPath)}`)
objectProps.push(`${JSON.stringify(file)}: ${variableName}`)
objectProps.push(`${JSON.stringify(filePath)}: ${variableName}`)
}
else {
let importStatement = `import(${JSON.stringify(importPath)})`
if (options.export)
importStatement += `.then(m => m[${JSON.stringify(options.export)}])`
objectProps.push(`${JSON.stringify(file)}: () => ${importStatement}`)
objectProps.push(`${JSON.stringify(filePath)}: () => ${importStatement}`)
}
})

Expand Down
12 changes: 12 additions & 0 deletions src/utils.ts
Expand Up @@ -3,3 +3,15 @@ const cssLangRE = new RegExp(cssLangs)

export const isCSSRequest = (request: string): boolean =>
cssLangRE.test(request)

export function assert(condition: unknown): asserts condition {
if (condition)
return

throw new Error(
[
'[vite-plugin-glob][Bug] You stumbled upon a bug in vite-plugin-glob\'s source code.',
'Reach out at https://github.com/antfu/vite-plugin-glob/issues/new and include this error stack (the error stack is usually enough to fix the problem).',
].join(' '),
)
}
10 changes: 5 additions & 5 deletions test/fixture.test.ts
Expand Up @@ -74,11 +74,11 @@ describe('fixture', async() => {
}
export const rootMixedRelative = {
\\"../../build.config.ts\\": () => import(\\"../../build.config.ts?url\\").then(m => m[\\"default\\"]),
\\"../../client.d.ts\\": () => import(\\"../../client.d.ts?url\\").then(m => m[\\"default\\"]),
\\"../../playground/package.json\\": () => import(\\"../../playground/package.json?url\\").then(m => m[\\"default\\"]),
\\"../../takeover.d.ts\\": () => import(\\"../../takeover.d.ts?url\\").then(m => m[\\"default\\"]),
\\"../../types.ts\\": () => import(\\"../../types.ts?url\\").then(m => m[\\"default\\"])
\\"/build.config.ts\\": () => import(\\"../../build.config.ts?url\\").then(m => m[\\"default\\"]),
\\"/client.d.ts\\": () => import(\\"../../client.d.ts?url\\").then(m => m[\\"default\\"]),
\\"/playground/package.json\\": () => import(\\"../../playground/package.json?url\\").then(m => m[\\"default\\"]),
\\"/takeover.d.ts\\": () => import(\\"../../takeover.d.ts?url\\").then(m => m[\\"default\\"]),
\\"/types.ts\\": () => import(\\"../../types.ts?url\\").then(m => m[\\"default\\"])
}
"
`)
Expand Down
3 changes: 2 additions & 1 deletion types.ts
Expand Up @@ -25,7 +25,8 @@ export interface ParsedImportGlob {
match: RegExpMatchArray
index: number
globs: string[]
absoluteGlobs: string[]
globsResolved: string[]
isRelative: boolean
options: GeneralGlobOptions
type: string
start: number
Expand Down

0 comments on commit 394c0c9

Please sign in to comment.