Skip to content

Commit

Permalink
feat!: auto interop file url and path
Browse files Browse the repository at this point in the history
  • Loading branch information
sxzz committed Feb 11, 2025
1 parent 71d4fa9 commit d9ad0a5
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 12 deletions.
7 changes: 3 additions & 4 deletions playground/demo.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// @ts-check

import { readFile } from 'node:fs/promises'
import { fileURLToPath } from 'node:url'
import MagicString from 'magic-string'
import type { Plugin, PluginContext } from '../src'

Expand All @@ -21,18 +20,18 @@ export function demoPlugin(): Plugin {
if (source.startsWith('node:')) return

if (source === 'virtual-mod') {
return 'file:///virtual-mod.ts'
return '/virtual-mod'
}

const result = await this.resolve(`${source}.js`, importer, options)
if (result) return result
},
async load(id) {
if (id === 'file:///virtual-mod.ts') {
if (id === '/virtual-mod') {
return { code: 'export const count = 42' }
}
if (id.endsWith('trace.js')) {
const code = await readFile(fileURLToPath(id), 'utf8')
const code = await readFile(id, 'utf8')
const s = new MagicString(code)
s.prepend('// header\n')
const map = s.generateMap({
Expand Down
34 changes: 26 additions & 8 deletions src/loader/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import process from 'node:process'
import { fileURLToPath, pathToFileURL } from 'node:url'
import remapping from '@ampproject/remapping'
import type {
FalsyValue,
Expand Down Expand Up @@ -56,8 +57,8 @@ export const resolve: ResolveHook = async (specifier, context, nextResolve) => {
for (const plugin of plugins) {
const result = await plugin.resolveId?.call(
{ resolve },
specifier,
context.parentURL,
urlToPath(specifier),
urlToPath(context.parentURL),
{
conditions: context.conditions,
attributes: context.importAttributes,
Expand All @@ -67,13 +68,13 @@ export const resolve: ResolveHook = async (specifier, context, nextResolve) => {
if (result) {
if (typeof result === 'string')
return {
url: result,
url: pathToUrl(result),
importAttributes: context.importAttributes,
shortCircuit: true,
}

return {
url: result.id,
url: pathToUrl(result.id),
format: result.format,
importAttributes: result.attributes || context.importAttributes,
shortCircuit: true,
Expand All @@ -90,13 +91,13 @@ export const resolve: ResolveHook = async (specifier, context, nextResolve) => {
options?: ResolveMeta,
): Promise<ResolvedId | null> {
try {
const resolved = await nextResolve(source, {
const resolved = await nextResolve(pathToUrl(source), {
parentURL: importer,
conditions: options?.conditions,
importAttributes: options?.attributes,
})
return {
id: resolved.url,
id: urlToPath(resolved.url),
attributes: resolved.importAttributes,
format: resolved.format,
}
Expand All @@ -115,7 +116,7 @@ export const load: LoadHook = async (url, context, nextLoad) => {

// load hook
for (const plugin of plugins) {
const loadResult = await plugin.load?.(url, {
const loadResult = await plugin.load?.(urlToPath(url), {
format: context.format,
conditions: context.conditions,
attributes: context.importAttributes,
Expand Down Expand Up @@ -145,7 +146,7 @@ export const load: LoadHook = async (url, context, nextLoad) => {
// transform hook
for (const plugin of plugins) {
const transformResult: ModuleSource | LoadResult | FalsyValue =
await plugin.transform?.(result.source, url, {
await plugin.transform?.(result.source, urlToPath(url), {
format: result.format,
conditions: context.conditions,
attributes: context.importAttributes,
Expand Down Expand Up @@ -178,3 +179,20 @@ function isModuleSource(v: unknown): v is ModuleSource {
typeof v === 'string' || ArrayBuffer.isView(v) || v instanceof ArrayBuffer
)
}

export function urlToPath(url: string): string
export function urlToPath(url: string | undefined): string | undefined
export function urlToPath(url: string | undefined): string | undefined {
if (!url) return url
return url.startsWith('file://') ? fileURLToPath(url) : url
}

export function pathToUrl(path: string): string {
if (
path.startsWith('file://') ||
path.startsWith('data://') ||
path.startsWith('node:')
)
return path
return pathToFileURL(path).href
}

0 comments on commit d9ad0a5

Please sign in to comment.