-
Notifications
You must be signed in to change notification settings - Fork 4
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
"main" and "browser" root fields in package.json #9
Comments
@rvagg added a feature flag for this but the latest esbuild supports export maps now, would be best to upgrade. |
we updated esbuild but we still see these issues. i still need to research more about what is happening here but independent from esbuild if ipjs outputs the browser field like this, it would be useful to do it in a more canonical way. I'm guessing this |
It's more complicated than that unfortunately. I think js-multiformats is the best example because it has to do things very differently in the browser where implementations used are entirely different (although https://unpkg.com/browse/[email protected]/package.json This works with WebPack, but of course that's just one of many and they all seem to have different opinions. I don't know what the majority opinion is on how to use We could switch |
There’s a spec for the browser field https://github.com/defunctzombie/package-browser-field-spec TBH, esbuild is doing some good stuff but the enthusiasm for its performance is a bit premature since it hasn’t actually met the feature set of other build tools. Everywhere I’ve seen it adopted I’ve also seen new problems, many of which have not yet been resolved. It’s promising but still immature. |
I'm the author of esbuild. Unfortunately that spec for the browser field you linked doesn't really specify much, is unmaintained, and comes without any tests, so has been pretty much impossible for me to know what the behavior should be without getting bug reports about cases that don't work. Please feel free to reach out if something isn't working. I'm happy to fix path resolution in esbuild if something is wrong. I just tried giving this a go and it looks like using the browser field to remap Click to see the source code{
"dependencies": {
"@ipld/car": "0.1.2",
"browserify": "17.0.0",
"esbuild": "0.9.2",
"webpack": "5.26.2",
"webpack-cli": "4.5.0"
}
} const fs = require('fs')
// Make sure we're testing "browser" not "exports"
const jsonPath = __dirname + '/node_modules/@ipld/car/package.json'
const json = JSON.parse(fs.readFileSync(jsonPath, 'utf8'))
delete json.exports
fs.writeFileSync(jsonPath, JSON.stringify(json, null, 2))
// Check multiple import paths
const tests = [
'@ipld/car',
'@ipld/car/indexed-reader',
]
async function main() {
const entryPath = __dirname + '/entry.js'
// Try esbuild
console.log('\nesbuild:')
for (const test of tests) {
fs.writeFileSync(entryPath, `require(${JSON.stringify(test)})`)
try {
const esbuild = require('esbuild')
await esbuild.build({
entryPoints: [entryPath],
bundle: true,
write: false,
logLevel: 'silent',
})
console.log(`✅ ${test}`)
} catch (e) {
console.log(`🚫 ${test}\n${e.message}`.replace(/\n/g, '\n '))
}
}
// Try webpack
console.log('\nwebpack:')
for (const test of tests) {
fs.writeFileSync(entryPath, `require(${JSON.stringify(test)})`)
try {
const webpack = require('webpack')
await new Promise((resolve, reject) => webpack({
mode: 'development',
entry: entryPath,
devtool: 'hidden-source-map',
}, (err, stats) => {
if (err) reject(err);
if (stats.hasErrors()) reject(stats.toString());
else resolve();
}));
console.log(`✅ ${test}`)
} catch (e) {
console.log(`🚫 ${test}\n${e.split('\n').slice(3, 5).join('\n')}`.replace(/\n/g, '\n '))
}
}
// Try browserify
console.log('\nbrowserify:')
for (const test of tests) {
fs.writeFileSync(entryPath, `require(${JSON.stringify(test)})`)
try {
const browserify = require('browserify')
const result = await new Promise((resolve, reject) => {
browserify(entryPath).bundle((err, data) => {
if (err) reject(err)
else resolve(data)
})
})
console.log(`✅ ${test}`)
} catch (e) {
console.log(`🚫 ${test}\n${e}`.replace(/\n\s*/g, '\n '))
}
}
}
main()
With only the |
@defunctzombie @FredKSchott thoughts? |
I think Rollup does have some handling for a browser map like you have here (which esinstall/Snowpack/Skypack all take advantage of), but I agree with @evanw that that behavior has always felt undefined to me. imo the sooner you can move over to 100% export maps, the better. (also: "browser" pointing to CJS instead of ESM? blasphemy! :) |
This is a bug in esbuild btw. The bug caused export maps to not work with scoped packages in esbuild. I'll push out the fix for it soon. This isn't surprising since export maps is a brand new feature in esbuild and isn't battle-tested yet. But even with the fix, the "exports": {
".": {
"require": "./cjs/car.js",
"import": "./esm/car.js",
"browser": "./esm/car-browser.js"
}, If |
Semantic map key ordering, wonderful idea.. I bet you have fun with that in Go @evanw. We can get that order switched around here pretty easily I think, I think it would make sense to put So re the top-level |
FYI I already released |
I suspect Parcel doesn't support |
while debugging and build issue with @ipld/car i noticed that the browser field can't be resolved by esbuild
i think this is trying to mimic how export maps work with abstract entry points to the package but the old
main
andbrowser
fields dont care about that, they just care about "real" files and mapping "real" files to other "real" files.In the snippet above we can see that
"."
or"./reader"
etc don't actually exist inside@ipld/car
and so esbuild can't bundle and errors saying cant resolve@ipld/car
.A fix would be to output this instead
Theres other ways to fix this but this seems to be most canonical one.
The text was updated successfully, but these errors were encountered: