Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PnP resolver #255

Merged
merged 13 commits into from
Oct 14, 2023
Merged
5 changes: 4 additions & 1 deletion src/esmockArgs.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import resolver from 'resolvewithplus'
import resolvewithplus from 'resolvewithplus'
import pnpResolver from './pnpResolver.js'

// extracts path or fileurl from stack,
// ' at <anonymous> (/root/test.js:11:31)' -> /root/test.js
Expand All @@ -7,6 +8,8 @@ import resolver from 'resolvewithplus'
// ' at file:///D:/a/test.js:7:9' -> file:///D:/a/test.js
const stackpathre = /^.*(\(|at )(.*):[\d]*:[\d]*.*$/

const resolver = pnpResolver || resolvewithplus

// this function normalizes "overloaded" args signatures, returning
// one predictable args list. ex,
// [moduleId, defs, gdefs, opts]
Expand Down
18 changes: 18 additions & 0 deletions src/pnpResolver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { isBuiltin } from 'node:module'
import { pathToFileURL } from 'node:url'

const pnpapi = process.versions.pnp && (await import('pnpapi')).default

export default pnpapi && ((id, parent) => {
if (isBuiltin(id)) {
return id.startsWith('node:') ? id : `node:${id}`
}

if (id === 'import') {
return null
}

const path = pnpapi.resolveRequest(id, parent)

return path !== null ? pathToFileURL(path).href : null
})
1 change: 1 addition & 0 deletions tests/local/pnp/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default {}
1 change: 1 addition & 0 deletions tests/local/pnp/disable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
delete process.versions.pnp
12 changes: 12 additions & 0 deletions tests/local/pnp/enable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import module from 'node:module'

async function resolve (specifier, context, next) {
return next(
specifier === 'pnpapi'
? '../tests/local/pnp/api.js'
: specifier, context)
}

module.register && (process.versions.pnp = '3') && module.register(`
data:text/javascript,
export ${encodeURIComponent(resolve)}`.slice(1))
2 changes: 1 addition & 1 deletion tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"sinon": "^12.0.1"
},
"scripts": {
"mini:esmock": "cd .. && cd src && npx esbuild esmock.js --minify --bundle --allow-overwrite --platform=node --format=esm --outfile=esmock.js",
"mini:esmock": "cd .. && cd src && npx esbuild esmock.js --minify --bundle --allow-overwrite --platform=node --format=esm --external:pnpapi --outfile=esmock.js",
"mini:esmockLoader": "cd .. && cd src && npx esbuild esmockLoader.js --minify --bundle --allow-overwrite --platform=node --format=esm --outfile=esmockLoader.js",
"mini": "npm run mini:esmock && npm run mini:esmockLoader",
"isnodelt18": "node -e \"+process.versions.node.split('.')[0] < 18 || process.exit(1)\"",
Expand Down
35 changes: 35 additions & 0 deletions tests/tests-node/esmock.node.resolver-pnp.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import test from 'node:test'
import assert from 'node:assert/strict'
import module from 'node:module'
import { fileURLToPath } from 'node:url'
import resolvewithplus from 'resolvewithplus'
import '../local/pnp/enable.js'
import esmock from 'esmock'
import '../local/pnp/disable.js'
import pnpapi from '../local/pnp/api.js'

const resolver = (id, parent) => {
const url = resolvewithplus(id, parent)
return url !== null ? fileURLToPath(url) : null
}

test.beforeEach(() => {
delete pnpapi.resolveRequest
})

test('should work with pnp resolver', async ({ mock }) => {
if (!module.register)
return assert.ok('skip test')

pnpapi.resolveRequest = mock.fn(resolver)

const main = await esmock('../local/main.js', {
'../local/mainUtil.js': {
createString: () => 'test string'
}
})

assert.equal(typeof main, 'function')
assert.strictEqual(main(), 'main string, test string')
assert.equal(pnpapi.resolveRequest.mock.callCount(), 2)
})