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

When "main" matches source and "browser" field set, bundle fails. #1746

Closed
benwiley4000 opened this issue Jul 13, 2017 · 14 comments
Closed

When "main" matches source and "browser" field set, bundle fails. #1746

benwiley4000 opened this issue Jul 13, 2017 · 14 comments

Comments

@benwiley4000
Copy link

benwiley4000 commented Jul 13, 2017

Using browserify 14.4.0. masOS Sierra.

Quite a weird repro. When running this command:

browserify module.js -o dist/module.js

And under this set of circumstances:

  • The "main" field in package.json matches the source file ("module.js")
  • The "browser" field is also set (with any value, but in our case "dist/module.js")

We get this error when bundling:

Error: module not found: "/<pathroot>/module/module.js" from file /<pathroot>/module/_fake.js

Changing the "main" field to something else allows browserify to succeed. Removing the "browser" field also works. Of course these aren't options for distribution.

@benwiley4000
Copy link
Author

After some simple A/B testing it appears to me this issue was introduced by v14.1.0.

@benwiley4000
Copy link
Author

The error above is emitted by the readonly stream returned by b.bundle().

If I change this line:

bundle.pipe(fs.createWriteStream(tmpfile));

to:

bundle.pipe(fs.createWriteStream(outfile));

and comment out this this line:

// bundle.on('end', successExit);

I have no issues.

Maybe at some stage the pipeline is expecting the stream to be written to a file matching the specified outfile?

I've had trouble finding why the "main" and "browser" fields in package.json would affect this.

@benwiley4000
Copy link
Author

benwiley4000 commented Aug 27, 2017

I'd love to see some additional heads looking at this issue. It's quite a serious problem for browser-targeted distribution of a module written using ES2015+.

Since the syntax is fully supported in recent Node versions I don't want to point main to a transpiled copy, yet of course I also need a browser entry for the web, which points to a transpiled version.
See later comment

@ljharb
Copy link
Member

ljharb commented Aug 27, 2017

You should always point "main" to a CJS ES5 copy; that's not going to change.

@benwiley4000
Copy link
Author

benwiley4000 commented Aug 27, 2017

Sorry, I actually wasn't precise about (or actually stated wrongly) the issue: I want to be able to include a bundled copy of my library as the browser entry (separate from the main entry). For some reason browserify is no longer accommodating for the case where the main entry of an npm package is the browserify source and the browser entry is the browserify target. The issue doesn't exist before 14.1.0.

This actually isn't related to ES2015 (which should work fine with require on the Node side). I've experienced this same problem with an ES5 module. In the case of my ES2015 library, browserify is also running babelify.

ETA: I could transpile without bundling but I'm using browserify here to create a UMD module for script consumption.

@ljharb
Copy link
Member

ljharb commented Aug 27, 2017

Right, gotcha.

so you're saying if you did browserify module.js -o dist/module2.js (and set the package.json fields) it'd work? ie, is it just that the base filename is the same that's causing the problem?

@benwiley4000
Copy link
Author

benwiley4000 commented Aug 27, 2017

Correct, I think. If I have:

  "main": "module.js",
  "browser": "dist/module2.js",

and run the above, I have a problem.

If I delete or change either main or browser in my package.json, the problem disappears (but now I have new problems).

ETA: So maybe incorrect - I don't think it's related to the base filename (but let me check...)

ETA Again: Yeah, unrelated to the actual filenames matching each other. If my main is index.js and my browser is dist/module.js and they match the browserify source/dest, it's an issue.

@smoke
Copy link

smoke commented May 15, 2018

Any news with that?
With Angular 6 upgrade and the fact that it now requires browser specific builds to be pointed with the browser property in package.json this issue here is more relevant than ever (see angular/angular-cli#9827 (comment) and angular/angular-cli#10844 (comment)).

For example I have been trying to set the property so that I can fix dtjohnson/xlsx-populate#130 but I have no luck.

What seems to happen is the following: When browserify (16.2.2) starts to build the xlsx-populate it sees that there is browser property in the package.json and uses the pointed sources, so no fresh build is produced.
If I delete the files browser/xlsx-populate* then it throws:

smoke@rkirilov-work-pc /home/smoke/xlsx-populate $ ./node_modules/.bin/gulp browser
[14:14:59] Using gulpfile /home/smoke/xlsx-populate/gulpfile.js
[14:14:59] Starting 'blank'...
[14:14:59] Finished 'blank' after 4.04 ms
[14:14:59] Starting 'browser-full'...
[14:14:59] Starting 'browser-no-encryption'...
events.js:183
      throw er; // Unhandled 'error' event
      ^

Error: module not found: "/home/smoke/xlsx-populate/lib/XlsxPopulate.js" from file /home/smoke/xlsx-populate/lib/_fake.js
    at onresolve (/home/smoke/xlsx-populate/node_modules/module-deps/index.js:181:30)
    at /home/smoke/xlsx-populate/node_modules/browserify/index.js:530:20
    at /home/smoke/xlsx-populate/node_modules/browser-resolve/index.js:247:21
    at /home/smoke/xlsx-populate/node_modules/browser-resolve/node_modules/resolve/lib/async.js:55:18
    at load (/home/smoke/xlsx-populate/node_modules/browser-resolve/node_modules/resolve/lib/async.js:69:43)
    at onex (/home/smoke/xlsx-populate/node_modules/browser-resolve/node_modules/resolve/lib/async.js:92:31)
    at /home/smoke/xlsx-populate/node_modules/browser-resolve/node_modules/resolve/lib/async.js:22:47
    at FSReqWrap.oncomplete (fs.js:152:21)

@goto-bus-stop
Copy link
Member

goto-bus-stop commented May 15, 2018

It looks like browserify or browser-resolve replaces the path matching the main field (eg. /xls-populate/lib/XlsxPopulate.js) by the path in the browser field (browser/xlsx-populateXXX.js) in some situations. I imagine this is good behaviour for modules inside node_modules, but not for local files. #1834 reproduces the problem.

@scottrippey
Copy link

I'm having this issue too. I can confirm that the steps to repro are simple:

{
  "main": "index.js",
  "browser": "browser.js",
  "scripts": {
    "build": "browserify index.js -o browser.js"
  }
}

This seems like a pretty common setup, right?

Anyway, I found a workaround:

"build": "cp index.js browser.js && browserify browser.js -o browser.js"

I'm making a copy of index.js, so that the filename doesn't match the main entry, and then use that as the input to browserify.
Also, instead of copying to a temp file, I'm just using the same filename as the final output, and it works just fine.

Hopefully this helps others, until a fix is implemented.

@goto-bus-stop
Copy link
Member

It's a common setup but I don't think it can be fixed without breaking major other use cases. This is just how the browser field works I'm afraid, the file it points to should be a CommonJS module and not a browserified bundle.

@stevenvachon
Copy link

stevenvachon commented Apr 22, 2019

Both of my files are CommonJS modules, but I still experience this error.

{
  "main": "lib",
  "browser": "lib-es5",
  "scripts": {
    "posttest": "browserify lib --global-transform [ babelify --presets [ @babel/env ] ] | terser --compress --mangle | gzip-size",
    "prepublishOnly": "babel lib/ --out-dir=lib-es5/ --presets=@babel/env --source-maps"
  }
}

@silibdev
Copy link

I have just encountered this problem with browserify v16.3.0

@scottrippey your workaround is great :)

@goto-bus-stop
Copy link
Member

goto-bus-stop commented Jul 22, 2019

@stevenvachon

Both of my files are CommonJS modules, but I still experience this error.

When you do browserify lib, your browser field maps lib to lib-es5. It has to exist before that can be used.

I'll close this since it's actually the correct behaviour.

joshgummersall pushed a commit to microsoft/botbuilder-js that referenced this issue Sep 28, 2020
- build a concatenated browser friendly bundle
- exorcist for source map support
- also fix @module throughout

Note for history: the somewhat odd `postbuild` command is intentional.
We want to export `lib/browser.js` via `package.json` but doing so
causes browserify to rewrite `lib/index.js` to `lib/browser.js`. The
copy command breaks this cycle while ensuring that the proper entrypoint
is used to produce the concatenated browser bundle.

See this Github issue for more details:
browserify/browserify#1746 (comment)
joshgummersall pushed a commit to microsoft/botbuilder-js that referenced this issue Sep 28, 2020
- build a concatenated browser friendly bundle
- exorcist for source map support
- also fix @module throughout

Note for history: the somewhat odd `postbuild` command is intentional.
We want to export `lib/browser.js` via `package.json` but doing so
causes browserify to rewrite `lib/index.js` to `lib/browser.js`. The
copy command breaks this cycle while ensuring that the proper entrypoint
is used to produce the concatenated browser bundle.

See this Github issue for more details:
browserify/browserify#1746 (comment)
joshgummersall pushed a commit to microsoft/botbuilder-js that referenced this issue Sep 29, 2020
- build a concatenated browser friendly bundle
- exorcist for source map support
- also fix @module throughout

Note for history: the somewhat odd `postbuild` command is intentional.
We want to export `lib/browser.js` via `package.json` but doing so
causes browserify to rewrite `lib/index.js` to `lib/browser.js`. The
copy command breaks this cycle while ensuring that the proper entrypoint
is used to produce the concatenated browser bundle.

See this Github issue for more details:
browserify/browserify#1746 (comment)
stevengum pushed a commit to microsoft/botbuilder-js that referenced this issue Sep 29, 2020
* browserify bundle of botframework-connector

- build a concatenated browser friendly bundle
- exorcist for source map support
- also fix @module throughout

Note for history: the somewhat odd `postbuild` command is intentional.
We want to export `lib/browser.js` via `package.json` but doing so
causes browserify to rewrite `lib/index.js` to `lib/browser.js`. The
copy command breaks this cycle while ensuring that the proper entrypoint
is used to produce the concatenated browser bundle.

See this Github issue for more details:
browserify/browserify#1746 (comment)

* Remove unused form-data dependency
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

7 participants