From f526b48b4f634a167958447d6eaa19762b2f6d6c Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Tue, 10 Aug 2021 12:24:07 +0200 Subject: [PATCH] Use ESM resolving algorithm --- lib/generate/config.js | 11 +++-- lib/generate/find-example.js | 47 ++++++++++--------- lib/generate/find-package.js | 4 +- lib/generate/instrument.js | 42 +++++++++-------- lib/generate/write.js | 6 ++- package.json | 2 +- .../normal-custom-example/config.json | 2 +- .../example.js | 2 +- 8 files changed, 63 insertions(+), 53 deletions(-) diff --git a/lib/generate/config.js b/lib/generate/config.js index fd738f4..7098503 100644 --- a/lib/generate/config.js +++ b/lib/generate/config.js @@ -1,17 +1,18 @@ +import url from 'url' +import {resolve} from 'import-meta-resolve' import {nanoid} from 'nanoid' -import resolveFrom from 'resolve-from' import {relativeModule} from '../util/relative-module.js' -export function config(ctx) { +export async function config(ctx) { const options = ctx.options const pkg = ctx.pkg || {} const cwd = ctx.file.cwd - const mainRoot = options.main ? cwd : ctx.pkgRoot || cwd - const mainId = relativeModule(options.main || pkg.main || '') + const mainRoot = url.pathToFileURL(options.main ? cwd : ctx.pkgRoot || cwd) + const mainId = relativeModule(options.main || pkg.main || 'index.js') let main try { - main = resolveFrom(mainRoot, mainId) + main = await resolve(mainId, mainRoot.href + '/') } catch {} ctx.cwd = cwd diff --git a/lib/generate/find-example.js b/lib/generate/find-example.js index 257f9b5..d743bc3 100644 --- a/lib/generate/find-example.js +++ b/lib/generate/find-example.js @@ -1,47 +1,52 @@ +import url from 'url' import {promises as fs} from 'fs' -import resolveFrom from 'resolve-from' +import {resolve} from 'import-meta-resolve' import {relativeModule} from '../util/relative-module.js' export async function findExample(ctx) { const fn = ctx.options.example ? findExplicitExample : findImplicitExample - const filePath = await fn(ctx) + const fileUrl = await fn(ctx) - if (!filePath) { + if (!fileUrl) { throw new Error('Could not find example') } - const example = String(await fs.readFile(filePath)) + const example = String(await fs.readFile(new URL(fileUrl))) - ctx.examplePath = filePath + ctx.exampleFileUrl = fileUrl // Make sure there is a final line feed. ctx.example = example.charAt(example.length - 1) === '\n' ? example : example + '\n' } function findExplicitExample(ctx) { - const moduleId = relativeModule(ctx.options.example) - - try { - return resolveFrom(ctx.cwd, moduleId) - // Catch just to be sure. - /* c8 ignore next */ - } catch {} + return resolve( + relativeModule(ctx.options.example), + url.pathToFileURL(ctx.cwd).href + '/' + ) } async function findImplicitExample(ctx) { - const examples = [ - './example', - './examples', - './doc/example', - './docs/example' - ] + const from = url.pathToFileURL(ctx.cwd).href + '/' + const promises = [ + './example.js', + './example/index.js', + './examples.js', + './examples/index.js', + './doc/example.js', + './doc/example/index.js', + './docs/example.js', + './docs/example/index.js' + ].map((d) => resolve(d, from)) + + const examples = await Promise.allSettled(promises) let index = -1 while (++index < examples.length) { - const filePath = resolveFrom.silent(ctx.cwd, examples[index]) + const example = examples[index] - if (filePath) { - return filePath + if (example.status === 'fulfilled') { + return example.value } } } diff --git a/lib/generate/find-package.js b/lib/generate/find-package.js index aaf985c..ebea6d8 100644 --- a/lib/generate/find-package.js +++ b/lib/generate/find-package.js @@ -13,9 +13,9 @@ export async function findPackage(ctx) { try { await read(pkgFile) - } catch (error) { // Doesn’t consistently happen. - /* c8 ignore next 3 */ + /* c8 ignore next 5 */ + } catch (error) { if (error.code !== 'ENOENT') { throw new Error('Could not read package: ' + error) } diff --git a/lib/generate/instrument.js b/lib/generate/instrument.js index 18d66a6..715a4df 100644 --- a/lib/generate/instrument.js +++ b/lib/generate/instrument.js @@ -1,17 +1,17 @@ -import path from 'path' +import {resolve} from 'import-meta-resolve' import babel from '@babel/core' -import resolveFrom from 'resolve-from' export async function instrument(ctx) { const logs = [] const mainReferences = [] + const nodes = [] let result try { result = await babel.transformAsync(ctx.example, { plugins: [addIdToConsoleLog], cwd: ctx.cwd, - filename: ctx.examplePath, + filename: ctx.exampleFileUrl, caller: {name: 'remark-usage'}, sourceType: 'unambiguous' }) @@ -19,6 +19,24 @@ export async function instrument(ctx) { throw new Error('Could not parse example: ' + error) } + const promises = nodes.map((node) => { + return resolve(node.value, ctx.exampleFileUrl).then((resolved) => { + if (resolved === ctx.main) { + // Babel always adds raw, but just to be sure. + /* c8 ignore next */ + const raw = (node && node.extra && node.extra.raw) || "'" + + mainReferences.push({ + start: node.start, + end: node.end, + quote: raw.charAt(0) + }) + } + }) + }) + + await Promise.allSettled(promises) + ctx.exampleInstrumented = result.code ctx.logs = logs ctx.mainReferences = mainReferences @@ -50,23 +68,7 @@ export async function instrument(ctx) { } function instrumentMainReference(node) { - let raw = node && node.extra && node.extra.raw - const filePath = resolveFrom.silent( - path.dirname(ctx.examplePath), - node.value - ) - - // Babel always adds raw, but just to be sure. - /* c8 ignore next */ - if (!raw) raw = "'" - - if (filePath && filePath === ctx.main) { - mainReferences.push({ - start: node.start, - end: node.end, - quote: raw.charAt(0) - }) - } + nodes.push(node) } function instrumentConsoleLog(path) { diff --git a/lib/generate/write.js b/lib/generate/write.js index 45eb242..09a85dc 100644 --- a/lib/generate/write.js +++ b/lib/generate/write.js @@ -1,10 +1,12 @@ +import url from 'url' import {promises as fs} from 'fs' import path from 'path' export async function write(ctx) { + const examplePath = url.fileURLToPath(ctx.exampleFileUrl) const filePath = path.join( - path.dirname(ctx.examplePath), - ctx.id + path.extname(ctx.examplePath) + path.dirname(examplePath), + ctx.id + path.extname(examplePath) ) await fs.writeFile(filePath, ctx.exampleInstrumented) diff --git a/package.json b/package.json index 9acb551..f8b1ee8 100644 --- a/package.json +++ b/package.json @@ -34,10 +34,10 @@ ], "dependencies": { "@babel/core": "^7.0.0", + "import-meta-resolve": "^1.0.0", "mdast-util-heading-range": "^3.0.0", "nanoid": "^3.0.0", "remark-parse": "^10.0.0", - "resolve-from": "^5.0.0", "to-vfile": "^7.0.0", "trough": "^2.0.0", "unified": "^10.0.0", diff --git a/test/fixtures/normal-custom-example/config.json b/test/fixtures/normal-custom-example/config.json index f66f9c2..8e6cf63 100644 --- a/test/fixtures/normal-custom-example/config.json +++ b/test/fixtures/normal-custom-example/config.json @@ -1,3 +1,3 @@ { - "example": "./ex" + "example": "./ex.js" } diff --git a/test/fixtures/normal-custom-name-without-package/example.js b/test/fixtures/normal-custom-name-without-package/example.js index 7579560..ff50019 100644 --- a/test/fixtures/normal-custom-name-without-package/example.js +++ b/test/fixtures/normal-custom-name-without-package/example.js @@ -1,5 +1,5 @@ // Require `pi`: -var pi = require('.') +var pi = require('./index.js') // Logs: console.log('text', pi)