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

Invalid OnResolveArgs.Importer for stdin in >= 0.8.21 #736

Closed
bep opened this issue Feb 1, 2021 · 3 comments
Closed

Invalid OnResolveArgs.Importer for stdin in >= 0.8.21 #736

bep opened this issue Feb 1, 2021 · 3 comments

Comments

@bep
Copy link

bep commented Feb 1, 2021

Before 0.8.21 we got the value stdin which is a constant I know how to handle.

After 0.8.21 we get what looks like an absolute filename, but it points to a file that does not exist -- but most importantly I don't know the origin of it to resolve imports relative to it.

gohugoio/hugo#8189

@evanw
Copy link
Owner

evanw commented Feb 1, 2021

I've got some tests that cover various cases with stdin here:

async stdinImporter({ esbuild, testDir }) {
const output = path.join(testDir, 'out.js')
await esbuild.build({
stdin: {
contents: `import x from "plugin"; export default x`,
sourcefile: 'stdin-sourcefile',
},
bundle: true, outfile: output, format: 'cjs', plugins: [{
name: 'name',
setup(build) {
build.onResolve({ filter: /^plugin$/ }, args => {
assert.strictEqual(args.namespace, '')
assert.strictEqual(args.importer, 'stdin-sourcefile')
assert.strictEqual(args.resolveDir, '')
assert.strictEqual(args.path, 'plugin')
return { path: args.path, namespace: 'worked' }
})
build.onLoad({ filter: /.*/, namespace: 'worked' }, () => {
return { contents: `export default 123` }
})
},
}],
})
const result = require(output)
assert.strictEqual(result.default, 123)
},
async stdinImporterResolveDir({ esbuild, testDir }) {
const output = path.join(testDir, 'out.js')
await esbuild.build({
stdin: {
contents: `import x from "plugin"; export default x`,
sourcefile: 'stdin-sourcefile',
resolveDir: testDir,
},
bundle: true, outfile: output, format: 'cjs', plugins: [{
name: 'name',
setup(build) {
build.onResolve({ filter: /^plugin$/ }, args => {
assert.strictEqual(args.namespace, 'file')
assert.strictEqual(args.importer, path.join(testDir, 'stdin-sourcefile'))
assert.strictEqual(args.resolveDir, testDir)
assert.strictEqual(args.path, 'plugin')
return { path: args.path, namespace: 'worked' }
})
build.onLoad({ filter: /.*/, namespace: 'worked' }, () => {
return { contents: `export default 123` }
})
},
}],
})
const result = require(output)
assert.strictEqual(result.default, 123)
},
async stdinAbsoluteImporterResolveDir({ esbuild, testDir }) {
const output = path.join(testDir, 'out.js')
await esbuild.build({
stdin: {
contents: `import x from "plugin"; export default x`,
sourcefile: path.join(testDir, 'stdin-sourcefile'),
resolveDir: testDir,
},
bundle: true, outfile: output, format: 'cjs', plugins: [{
name: 'name',
setup(build) {
build.onResolve({ filter: /^plugin$/ }, args => {
assert.strictEqual(args.namespace, 'file')
assert.strictEqual(args.importer, path.join(testDir, 'stdin-sourcefile'))
assert.strictEqual(args.resolveDir, testDir)
assert.strictEqual(args.path, 'plugin')
return { path: args.path, namespace: 'worked' }
})
build.onLoad({ filter: /.*/, namespace: 'worked' }, () => {
return { contents: `export default 123` }
})
},
}],
})
const result = require(output)
assert.strictEqual(result.default, 123)
},
async stdinRelative({ esbuild, testDir }) {
const output = path.join(testDir, 'out.js')
await esbuild.build({
stdin: {
contents: `import x from "./stdinRelative.js"; export default x`,
},
bundle: true, outfile: output, format: 'cjs', plugins: [{
name: 'name',
setup(build) {
build.onResolve({ filter: /.*/ }, args => {
assert.strictEqual(args.namespace, '')
assert.strictEqual(args.importer, '<stdin>')
assert.strictEqual(args.resolveDir, '')
assert.strictEqual(args.path, './stdinRelative.js')
return { path: args.path, namespace: 'worked' }
})
build.onLoad({ filter: /.*/, namespace: 'worked' }, () => {
return { contents: `export default 123` }
})
},
}],
})
const result = require(output)
assert.strictEqual(result.default, 123)
},
async stdinRelativeResolveDir({ esbuild, testDir }) {
const output = path.join(testDir, 'out', 'out.js')
await esbuild.build({
stdin: {
contents: `import x from "./stdinRelative.js"; export default x`,
resolveDir: testDir,
},
bundle: true, outfile: output, format: 'cjs', plugins: [{
name: 'name',
setup(build) {
build.onResolve({ filter: /.*/ }, args => {
assert.strictEqual(args.namespace, '')
assert.strictEqual(args.importer, '<stdin>')
assert.strictEqual(args.resolveDir, testDir)
assert.strictEqual(args.path, './stdinRelative.js')
return { path: args.path, namespace: 'worked' }
})
build.onLoad({ filter: /.*/, namespace: 'worked' }, () => {
return { contents: `export default 123` }
})
},
}],
})
const result = require(output)
assert.strictEqual(result.default, 123)
},

There you can see what various combinations of Stdin options and the resulting Importer are. It looks like if you pass both a ResolveDir and a Sourcefile, the importer will now be the Sourcefile path resolved relative to the ResolveDir. The behavior is somewhat arbitrary but I probably did it that way so that it's consistent with how the importer for other files behave. Sorry about the breakage–I don't think I had test coverage for these cases before that change.

It looks like you should be able to get <stdin> back by not passing the Sourcefile option to Stdin. I think that should fix your use case unless you needed the Sourcefile for something. Alternatively, you can also avoid using Stdin altogether and just provide the contents of the entry point file with a plugin. An example of doing that is here: #720 (comment).

Unrelated: While I have your attention, I believe there's also a bug with Hugo's use of esbuild's API that causes Hugo to crash with a null pointer error. Details are here. It seems like an easy fix.

@bep
Copy link
Author

bep commented Feb 1, 2021

Thanks; I will have a look at it. The nilpointer is fixed (I'm pretty sure ...)

@bep
Copy link
Author

bep commented Feb 1, 2021

Yes, that works, and I guess the current behaviour makes sense. Closing.

@bep bep closed this as completed Feb 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants