-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
feat(vite-node): provide import.meta.resolve
#5188
Open
hi-ogawa
wants to merge
9
commits into
vitest-dev:main
Choose a base branch
from
hi-ogawa:feat-vite-node-expose-import-meta-resolve
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 5 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
060a638
feat(vite-node): provide `import.meta.resolve`
hi-ogawa 5dd2075
chore: lockfile
hi-ogawa bfc2f4f
chore: comment
hi-ogawa b4a9b72
chore: comment
hi-ogawa 0a0b73c
test: test vite-node cjs
hi-ogawa 74ca778
fix: check `import.meta.resolve`
hi-ogawa 2cc0ba9
fix: define only when "parent" feature is available
hi-ogawa f8c05b4
fix: await to avoid unhandled rejection in old node
hi-ogawa c11c3ea
chore: still define but throw when called
hi-ogawa File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"name": "@vitest/test-import-meta-resolve", | ||
"type": "module", | ||
"private": true, | ||
"scripts": { | ||
"test": "vitest" | ||
}, | ||
"devDependencies": { | ||
"vitest": "workspace:*" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { expect, test } from 'vitest' | ||
|
||
test('basic', () => { | ||
// relative path | ||
expect( | ||
cleanDir(import.meta.resolve('../package.json')), | ||
).toMatchInlineSnapshot(`"__DIR__/test/import-meta-resolve/package.json"`) | ||
|
||
// not throw in latest NodeJS | ||
expect(cleanDir(import.meta.resolve('../no-such-file'))).toMatchInlineSnapshot( | ||
`"__DIR__/test/import-meta-resolve/no-such-file"`, | ||
) | ||
|
||
// with 2nd argument `parent` | ||
expect( | ||
cleanDir( | ||
import.meta.resolve('./package.json', new URL('..', import.meta.url)), | ||
), | ||
).toMatchInlineSnapshot(`"__DIR__/test/import-meta-resolve/package.json"`) | ||
|
||
// node_module | ||
expect(cleanDir(import.meta.resolve('vitest'))).toMatchInlineSnapshot( | ||
`"__DIR__/packages/vitest/dist/index.js"`, | ||
) | ||
|
||
expect(() => | ||
cleanDir(import.meta.resolve('@vitest/not-such-module')), | ||
).toThrow( | ||
expect.objectContaining({ | ||
message: expect.stringContaining( | ||
'Cannot find package \'@vitest/not-such-module\' imported from', | ||
), | ||
}), | ||
) | ||
}) | ||
|
||
// make output deterministic | ||
function cleanDir(out: string) { | ||
const dir = new URL('../../..', import.meta.url).toString() | ||
return out.replace(dir, '__DIR__/') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { defineConfig } from 'vitest/config' | ||
|
||
export default defineConfig({ | ||
test: { | ||
poolOptions: { | ||
threads: { | ||
execArgv: ['--experimental-import-meta-resolve'], | ||
}, | ||
forks: { | ||
execArgv: ['--experimental-import-meta-resolve'], | ||
}, | ||
vmThreads: { | ||
// vmThreads already enables this flag | ||
// execArgv: ['--experimental-import-meta-resolve'], | ||
}, | ||
}, | ||
}, | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
require('vite-node/client') | ||
require('vite-node/server') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { execFile } from 'node:child_process' | ||
import { fileURLToPath } from 'node:url' | ||
import { promisify } from 'node:util' | ||
import { it } from 'vitest' | ||
|
||
const execFileAsync = promisify(execFile) | ||
|
||
it('require vite-node', async () => { | ||
// verify `import.meta.resolve` usage doesn't cause syntax error on vite-node cjs build | ||
await execFileAsync( | ||
'node', | ||
[fileURLToPath(new URL('../src/require-vite-node.cjs', import.meta.url))], | ||
) | ||
}) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'resolve' in import.meta
will resolve different values in Node and Vitest, right?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For latest Node (from v20.0.6 https://nodejs.org/docs/latest-v20.x/api/esm.html#importmetaresolvespecifier),
import.meta.resolve
is always defined and--experimental-import-meta-resolve
only switches 2nd argumentparent
feature. But for older node,--experimental-import-meta-resolve
is required to haveimport.meta.resolve
defined.So,
'resolve' in import.meta
should be same for the latest Node (regardless of--experimental-import-meta-resolve
), but that's not the case for old ones.I just put next to filename/dirname here, but it's probably better to define this only when
import.meta.resolve
is available.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe you were asking some enumerable property kind of difference?
For now, I updated it to define
import.meta.resolve
by checking it first 74ca778There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just defining with an
if
is fine for me. I do have another question tho - shouldn't it give an error on the new Node.js version when you don't pass down a flag and use a relative path because it doesn't supportparent
? Since all relative URL are resolved relative to the vite-node file.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's very much desired, but I don't know how to do it. I thought about just checking
execArgv
, but the flag might also come fromNODE_OPTIONS
. Do you know some trick for this?Another way would be to detect feature during runtime by actually testing
import.meta.resolve
, something like:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When users didn't pass
--experimental-import-meta-resolve
, that's going to happen silently, so that's why I thought we need to detect that first.If
--experimental-import-meta-resolve
is passed, then the we can override the default parent value, soimport.meta.resolve('./dumy')
should work same both on Node and vite-node.I updated to check if the 2nd argument feature is available by running this inside vite-node
(Actually evaluating this for every module is unnecessary, so probably we can check just once.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, but even if we detect it, we can't fix it with
import.meta.resolve
, can't we? Since it doesn't accept the second argument. Do you only want to support it if there is a flag?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's what I was thinking. But, I totally get that exposing this feature only with
--experimental-import-meta-resolve
wouldn't be that good. I'm okay with that putting this PR on hold for now.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already bundle
import-meta-resolve
package, we can just use it here 😄There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wrote it in vitejs/vite#15871 (comment) but there are some known differences with a polyfill https://github.com/wooorm/import-meta-resolve?tab=readme-ov-file#differences-to-node
It totally depends on the use case, but my feeling is that if users really want to integrate
import.meta.resolve
feature in NodeJs app/library, then they would use it together with custom loader or custom conditions etc...(actually I had this use case on my own tiny typescript import/export checker https://github.com/hi-ogawa/js-utils/tree/main/packages/icheck-ts where it doesn't make sense to use polyfill)
If that's not the case, then they would've used
createRequire + require.resolve
(for node_modules) ornew URL("./...", ...)
(for relative path) or maybe polyfill by themselves.I guess this feature request came for the first time, so I think we can wait a little to determine the use cases better. (I didn't even get the response from OP yet...)