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

Parcel emulates require('underscore') incorrectly #2865

Closed
ShanksRH opened this issue Jul 24, 2020 · 3 comments
Closed

Parcel emulates require('underscore') incorrectly #2865

ShanksRH opened this issue Jul 24, 2020 · 3 comments
Labels

Comments

@ShanksRH
Copy link

Hello, after underscore 1.10 update, OOP style broke down with _ is not a function error, if use const _ = require('underscore') on client.

Sandbox example: https://codesandbox.io/s/eloquent-galileo-tf9je?file=/src/index.js

@jgonggrijp
Copy link
Collaborator

Thanks for reaching out.

Your sandbox is importing Underscore twice in the same module, once with ESM syntax and once with CommonJS syntax. This is probably causing Parcel to use the same underlying ESM module in both cases and then to emulate the require call as import * as _r from 'underscore/modules/index-all.js'. Note that the wildcard import is not equivalent to the default import. This problem is easy to avoid by using only the ESM import.

Is your actual code different? Otherwise, this is just a case of "sorry, incorrect usage is not expected to work".

@ShanksRH
Copy link
Author

Thanks for answer.
But if I remove import and leave only require() the problem still occurs.
Sandbox edited.

@jgonggrijp
Copy link
Collaborator

In that case, Parcel is resolving the path for your require call incorrectly. It should be node_modules/underscore/underscore.js (the main field of the package.json) but it appears to be using node_modules/underscore/modules/index-all.js instead (the module field of the package.json). Using the module path is never correct for CommonJS imports, so this is a bug in Parcel.

Adding to that, emulating require() using import * as is also incorrect in general. The older single-export conventions, such as CommonJS, allow every module to export only one thing, but it can be anything. It can be a namespace object, a function, a string or even undefined. So this aligns with the semantics of a default import, not a wildcard import which can only be a namespace object. This would however not be a problem if Parcel wasn't also resolving the import to the wrong file.

WebPack has roughly the same issue, see #2852 and webpack/webpack#5756. Browserify and Rollup do not suffer from these problems.

Please report these bugs to the Parcel developers (maybe someone already did that). Until they have solved it, you have a couple of options to work around the problem:

  • Look into a way to configure Parcel's module resolution strategy (and perhaps also its import emulation strategy). Maybe there is a way to get it to behave correctly with some help. Overriding the module path for Underscore might be enough.
  • Keep Underscore external and embed the UMD bundle from a CDN instead.
  • Use _ = require('underscore').default instead. This should work regardless of whether your tool is resolving to the ESM module or the UMD bundle.
  • Use import _ from 'underscore' instead. This should also work in both cases.
  • Switch to a different build tool such as Browserify or Rollup.

I will close this ticket now, but please feel welcome to continue the discussion.

@jgonggrijp jgonggrijp changed the title OOP style doesn't work with require() Parcel emulates require() incorrectly Jul 24, 2020
@jgonggrijp jgonggrijp changed the title Parcel emulates require() incorrectly Parcel emulates require('underscore') incorrectly Jul 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants