Parcel fails to build js-ipfs (and many other things) #1344
Description
- Version: 0.28.2
- Platform: All
- Subsystem: All
Type:
Bug / Warning to others
Severity:
High
Description:
It's not currently possible use parcel to create production builds of apps that depend on js-ipfs. This is due to an issue in parcel, not js-ipfs.
The parcel build
command tries to dedupe modules to reduce bundle size, but an error in the logic is leading it to incorrectly dedupe ipld-git
and ipld-dag-cbor
to the same module, which causes an error in js-ipld, when we try to add two identical resolvers. Ipld correctly throws an error in that case. The error is that the parcel build has resolved require('ipld-git')
to the same module as require('ipld-dag-cbor')
grep ipld-git dist/app*.js
dist/app.79643623.js:},{"ipfs-block":111,"pull-stream":124,"cids":38,"async/doUntil":125,"ipfs-repo":109,"ipfs-block-service":28,"path":96,"pull-defer":129,"pull-traverse":130,"async/map":126,"async/series":127,"async/waterfall":128,"interface-datastore":112,"ipld-dag-pb":33,"ipld-dag-cbor":31,"ipld-git":31,"ipld-bitcoin":114,"ipld-ethereum":115,"ipld-raw":116,"ipld-zcash":114}],337:[function(require,module,exports) {
Notice how ipld-git and ipld-dag-cbor map to the same integer. The same bad dedupe has happened to ipld-bitcoin
and pld-zcash
as well, but we hit the ipld-git error first.
This issue is here as warning to others.
The fix for this issue is in parcel-bundler/parcel#1011
Workarounds
- Use https://github.com/tableflip/window.ipfs-fallback which will pull in js-ipfs from unpkg if needed or use window.ipfs where available.
- Use a pre-built version of js-ipfs from unpkg directly.
- Use browserify or webpack
- Use parcel, but don't use the
build
command. Not ideal as your bundle will be unoptimised.
Steps to reproduce the error:
You can see it on the circuit-relaying example in this repo:
cd examples/circuit-relaying
npm i
# Create a production build with parcel
npm run build
# Serve the app
npx http-server@latest dist
Loading the app in a browser shows the following error:
index.js:48 Uncaught Error: dag-cboralready supported
at Object.IPLDResolver.support.add (index.js:48)
at new IPLDResolver (index.js:72)
at new IPFS (index.js:80)
at Object.parcelRequire.6.ipfs (app.js:29)
at newRequire (rsa-utils.js:73)
at parcelRequire.28 (index.js:75)
at index.js:101