parcel: Parcel WebExtension fails to bundle modules under some conditions (build + mv2, or mv3 & --no-scope-hoist)

🐛 bug report

Under some conditions/configurations Parcel fails to package dependecies into bundles and fails in runtime.
Here is a set of conditions and results I’ve discovered so far (see configs below for price command definitions)

🎛 Configuration (.babelrc, package.json, cli command)

.parcelrc

{
  "extends": "@parcel/config-webextension",
  "validators": {
	"*.{ts,tsx}": [
	  "@parcel/validator-typescript"
	]
  }
}

package.json parts

"watch": "parcel watch source/mv2/manifest.json --dist-dir build/dev --no-cache",
"build:chrome": "parcel build source/mv3/manifest.json --no-content-hash --no-source-maps --dist-dir build/chrome --no-cache --detailed-report 0",
"build:firefox": "parcel build source/mv2/manifest.json --no-content-hash --no-source-maps --dist-dir build/firefox --no-cache --detailed-report 0",

🤔 Expected Behavior

When I run either of the build commands above - all the dependencies are bundled

😯 Current Behavior

Some (all?) dependencies are missing from the bundle and the extension fails at load time with the error like:

Uncaught Error: Cannot find module 'lbnQL'
    at parcelRequire (background.c6210b5c.js:15:15)
    at background.c6210b5c.js:19:57
    at background.c6210b5c.js:33:3

🔦 Context

Building https://github.com/transclude-me/extension

I’ve noticed this problem after migrating to Parcel 2.5.0 from 2.3.2. One noteable change that accompanied that is having to use 2 manifests so both FF and Chrome can be supported. So my directory stracture is as follows now

src/
  mv2/manifest.json
  mv3/manifest.json

And code in manifest points to files up level (e.g. "service_worker": "../background.ts",).

I’ve tried reverting to src/manifest.json structure in case this was relevant, but it didn’t make the difference.


I’ve also tried adding the following in package.json, in case it got reset somehow, it didn’t make any difference:

	"targets": {
		"default": {
			"includeNodeModules": true
		}
	}

💻 Code Sample

https://github.com/transclude-me/extension/commit/78b529ef1af32ba076b3b852f21145f48dfdb1b9 I discovered issue after this commit

🌍 Your Environment

Software Version(s)
Parcel 2.5.0
Node 17.5.0 (also tried 16.4.2)
Yarn 1.22.17
Operating System macOS 12.3.1

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 11
  • Comments: 23 (11 by maintainers)

Commits related to this issue

Most upvoted comments

Getting the same issue here as @Stvad. Seems like web extension production build is not robust (it works well in parcel watch dev mode)?

I followed the changes from @Kjoep and simply added this to package.json and my production build seems to work.

"@parcel/bundler-default": {
  "minBundles": 10000000,
  "minBundleSize": 3000,
  "maxParallelRequests": 20
}

Command: parcel build manifest.json --no-content-hash

Without no content hash, I get this error: Error: Cannot read properties of undefined (reading 'hashReferences')

Thanks, I’ve reproduced the issue and am working on fixing it now.

I haven’t been able to properly look at this. For now we should probably just document the issue and add the code-splitting removal fix into the docs.

@101arrowz Thank you for replying, great, that’s something!

Can you please share here for now how to remove code-splitting?

@101arrowz here’s my reproduction: https://github.com/lukaw3d/reproduce-parcel-webextension-codesplitting-broken

  • uses parcel@2.6.0 and @parcel/config-webextension@2.6.0
  • manifest v2 with two entry points: background.ts and popup.html
  • both entry points import something large (lodash)
  • users browserslist to target an old browser (Chrome 60)

background page throws Cannot find module when initializing

To be fair, the codesplitting does not seem very important for webextensions, as they are loaded locally, not over the network. It might be acceptable to automatically turn the feature off.

I’d say PREFERABLE

I have the same problem (at least it looks like it) and did some digging. Turns out the WebExtensionPackager is not compatile wit the code-splitting feature. If bundles get split off, it does not add the split-off bundles to the manifest. From what it looks like it only does a naive find-and-replace.

I have a simple workaround here: https://github.com/Kjoep/parcel/tree/prevent_losing_webextension_deps (use it for config-webextension). This turns off the code-splitting for web extensions.

@101arrowz I’m using Parcel 2.7.0 and below config doesn’t work for me:

    "@parcel/bundler-default": {
        "minBundles": 10000000,
        "minBundleSize": 3000,
        "maxParallelRequests": 20
    }

I still get only 1 file: manifest-firefox.js #8404

To be fair, the codesplitting does not seem very important for webextensions, as they are loaded locally, not over the network. It might be acceptable to automatically turn the feature off.

Manifest v3 with --no-scope-hoist is an interesting case, as in it content script is broken, but background is fine, and content script is failing to import ../options/options-storage module, which is what background script fails to import in the other broken cases 🤔