diff --git a/README.md b/README.md index 32ae8ef..d2aff4f 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,8 @@ import { loadModule } from 'mlly' await loadModule('./hello.mjs', { from: import.meta.url }) ``` +Options are same as for `evalModule` + ### `evalModule` Evaluates JavaScript module code using dynamic imports with [`data:`](https://nodejs.org/api/esm.html#esm_data_imports) using `toDataURL`. @@ -124,14 +126,22 @@ await evalModule(` `, { from: import.meta.url }) ``` +**Options:** + +- [ resolve options ] +- `url`: If provided, all `import.meta.url` usages within module will be rewritten. Also used as default `from` for relative import resolution + ### `readModule` -Resolves id using `resolve` and reads sourcecode. +Resolve module path and read source contents. (currently only file protocol supported) ```js -import { readModule } from 'mlly' +import { resolve, readModule } from 'mlly' -console.log(await readModule('./index.mjs', { from: import.meta.url })) +const indexPath = await resolve('./index.mjs', { from: import.meta.url }) + +// { code: '...", url: '...' } +console.log(await readModule(indexPath)) ``` ### `toDataURL` @@ -140,6 +150,8 @@ Convert code to [`data:`](https://nodejs.org/api/esm.html#esm_data_imports) URL All relative imports will be automatically resolved with `from` param using `resolveImports`. +If `url` option is provided, all usages of `import.meta.url` will be rewritten too. + ```js import { toDataURL } from 'mlly' diff --git a/lib/index.d.ts b/lib/index.d.ts index f39d3b6..d3de1e3 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -24,12 +24,14 @@ export function resolveImports (code: string, opts: ResolveOptions) : Promise export function evalModule (code: string, opts?: EvaluateOptions) : Promise - -export function readModule (id: string, opts?: ResolveOptions) : Promise -export function toDataURL(code: string, opts?: ResolveOptions) : Promise +export function readModule (id: string, opts?: EvaluateOptions) : Promise<{ url: string, code: string}> +export function toDataURL(code: string, opts?: EvaluateOptions) : Promise // Utils diff --git a/lib/index.mjs b/lib/index.mjs index aa5a94b..fbd0cd3 100644 --- a/lib/index.mjs +++ b/lib/index.mjs @@ -70,8 +70,11 @@ export function createResolve (defaults) { const ESM_IMPORT_RE = /(?<=import .* from ['"])([^'"]+)(?=['"])|(?<=export .* from ['"])([^'"]+)(?=['"])|(?<=import\s*['"])([^'"]+)(?=['"])|(?<=import\s*\(['"])([^'"]+)(?=['"]\))/g export async function loadModule (id, opts = {}) { - const code = await readModule(id, opts) - return evalModule(code, opts) + const { url, code } = await readModule(id, opts) + return evalModule(code, { + url, + ...opts + }) } export async function evalModule (code, opts = {}) { @@ -79,13 +82,28 @@ export async function evalModule (code, opts = {}) { } export async function readModule (id, opts) { - const resolved = await resolve(id, opts) - const code = await fsp.readFile(fileURLToPath(resolved), 'utf-8') - return code + const url = await resolve(id, opts) + const code = await fsp.readFile(fileURLToPath(url), 'utf-8') + return { url, code } } export async function toDataURL (code, opts) { + // Use url <> from as defaults of each other + if (!opts.url && opts.from) { + opts.url = opts.from + } else if (opts.url && !opts.from) { + opts.from = opts.url + } + + // Resolve relative imports code = await resolveImports(code, opts) + + // Rewrite import.meta.url + if (opts.url) { + code = code.replace(/import\.meta\.url/g, `'${opts.url}'`) + } + + // Convert to base64 const base64 = Buffer.from(code).toString('base64') return `data:text/javascript;base64,${base64}` } diff --git a/test/hello.mjs b/test/hello.mjs index 1e2e7be..c1ab03b 100644 --- a/test/hello.mjs +++ b/test/hello.mjs @@ -1 +1 @@ -console.log('Hello world!') +console.log('Hello world from', import.meta.url)