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

ES Module type=module cause "parcelRequire is not defined" error #1401

Closed
tarepan opened this issue May 20, 2018 · 53 comments
Closed

ES Module type=module cause "parcelRequire is not defined" error #1401

tarepan opened this issue May 20, 2018 · 53 comments

Comments

@tarepan
Copy link

tarepan commented May 20, 2018

🐛 bug report

Using ES Module in main HTML cause "parcelRequire is not defined" error.
If we use type="module", minimal code in Getting Started (Parcel official) make this error.

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

zero configuration.

🤔 Expected Behavior

If we write super simple code with ES Module like below,

<!-- index.html -->
<html>
<body>
<script src="./index.js" type="module"></script>
</body>
</html>
// index.js
console.log("hello parcel");

I hope it is bundled properly and get "hello parcel" in console without error.

😯 Current Behavior

In console,

hello parcel.   index.js 1
Uncaught ReferenceError: parcelRequire is not defined at test.904c6489.js:10

💁 Possible Solution

Apparently ES Module cause this error.
When I removed type="module" from script element, no error observed.

It suggest that we can avoid error by avoiding type="module" for parcel.
But I think this approach is not good.
ES Module (type="module") is generally available (now 2018-05, all popular browsers supported!!), so ES module is straight forward way to import module.

🔦 Context

I do not know what problem is caused by this error.

🌍 Your Environment

Software Version(s)
Parcel parcel-bundler@1.8.1
Node (problem happen both) 8.9.3 & 9.11.1
npm/Yarn
Operating System Windows10 Pro, build 17134

Thank you good library, I hope this project become better and better.

@itshizhan
Copy link

since you use type="module",why use parcel?

@tarepan
Copy link
Author

tarepan commented May 21, 2018

Mainly for module resolution.
And for old browser users (ES module not supported, need Bundle.)

@Schubidu
Copy link

A good point to use Parcel in this case is the minification and files with hashes

@emirotin
Copy link

emirotin commented Jun 6, 2018

I have the same problem in different context. I'm trying to consume parcel-bundled module from my webpack-bundled app. Since ES6 modules (my app) run in strict context an attempt to consume the module results in assignment to undefined variable and crashes my app.

@alexeyraspopov
Copy link

alexeyraspopov commented Jul 3, 2018

Seems like this is no longer reproducible in v1.9.4.

Edit: disregard this, still reproducible.

@alexeyraspopov
Copy link

Maybe it makes sense for Parcel to remove type="module" for an entry that is being built?

@davidnagli
Copy link
Contributor

This is an issue with the way parcelRequire is defined in Strict Mode. ES6 modules are by default executed in strict mode (AFIK), which prohibits implicit variable declerations.

Here's what Parcel's output looks like:

parcelRequire = (function (modules, cache, entry, globalName) {
  // Save the require from previous bundle to this closure if any
  var previousRequire = typeof parcelRequire === 'function' && parcelRequire;
  var nodeRequire = typeof require === 'function' && require;

  function newRequire(name, jumped) {

Notice how the global parcelRequire is implicitly declared without let/var!

By editing the output file and naively adding let before parcelRequire I was able to eliminate the issue. However, adding let can affect scoping...

An alternative that works is changing it to window.parcelRequire, but that would break in Node; which probably doesn't really matter since we can avoid doing that in --target node.

I ran into this in the wild in a slightly separate case when attempting to require a library I bundled with Parcel in a Webpack project. The Webpack project had a top level "use strict" pragma automatically injected which is what broke everything in the same way as this issue.

@cameron-martin
Copy link

Looks like a duplicate of #864

@kleinfreund
Copy link

Adding the Firefox error message so this issue pops up in searches:

ReferenceError: assignment to undeclared variable parcelRequire

Can this issue be resolved without altering the generated output (e.g. assigning to window.parcelRequire instead of parcelRequire) at the moment?

@GrosSacASac
Copy link

it should not be hard to add var or let or const

@outkine
Copy link

outkine commented Sep 19, 2018

(duplicate of #864 (comment))
Since require may be used inside of the modules, defining it with let/const/var causes a ReferenceError: require is not defined

@dfkaye
Copy link

dfkaye commented Sep 25, 2018

temporary fix for your work environment or localhost - https://twitter.com/dfkaye/status/1044693110700171264

@idanilt
Copy link

idanilt commented Nov 11, 2018

nicer work around:
yarn add parcel-plugin-wrapper --dev

.assetWarpper.js

const path = require('path')

const CWD = process.cwd()
const PACKAGE = require(path.join(CWD, 'package.json'))

const varRequire = async ({name, bundler}) => {
    // name = app.ere76r5e76r5e76r.js
    if (name.split('.').pop() === 'js' && bundler.options.production) {
        return {
            header: `var parcelRequire = undefined;`,
            footer: ``
        }
    }
}

module.exports = varRequire;

@kirillgroshkov
Copy link

We're having same issue!

@dandv
Copy link
Contributor

dandv commented Dec 11, 2018

Note that simply removing type="module" didn't work, even after re-launching parcel. I had to also delete the .cache directory.

@Buslowicz
Copy link

Sooo, am I reading this correctly? Parcel does not allow for a standard ES Module output?

@lvalencia
Copy link

yeah I'm having this issue when I use a raw .ts file as my input and I bundle my node_modules with it into a single file e.g.

parcel build ./src/index.ts --target node --bundle-node-modules

when i run it in node I'll get an error like

ReferenceError: parcelRequire is not defined

when I look at the non-minified version I can see

// eslint-disable-next-line no-global-assign
parcelRequire = (function (modules, cache, entry, globalName) {

so my guess is the assumption was that it would globally assign. it appears that it doesn't.

Obviously if I add var in front of it the lexical scoping lookup of JavaScript assigns it to global. but from what I can gather that would break things for other environments i.e. not --target node

I came up with a workaround

parcel build ./src/index.ts --target node --bundle-node-modules --out-dir ./dist --no-minify --out-file main.js && sed -i '' '1s;^;var ;' ./dist/main.js

obviously the bummer here is I can't use watch because how would I append it for my needs.

anyway is there an ETA for this fix? the set-up (or lack thereof) is super convenient so I'd like to use Parcel for a recommended way of doing something except this is kind of a blocker.

@dfkaye
Copy link

dfkaye commented Jan 21, 2019

We ran into another issue specific to our app, so we had to come up with a post-bundling process file that uses the parcel-bundler API directly (see https://parceljs.org/api.html) in order to solve that as well as the "parcelRequire is not defined" issue.

https://gist.github.com/dfkaye/f43dbdfbcdee427dbe4339870ed979d0

@heldrida
Copy link

heldrida commented Feb 5, 2019

Have the same issue here!

"ReferenceError: parcelRequire is not defined"

While working in:
index.js, imports fileA
fileA.js, imports fileB
fileB.js

Command:
parcel build ./src/index.js --target browser

Can fix if manually add let,const before parcelRequire= in the dist/output file

@twome
Copy link

twome commented Feb 20, 2019

A workaround for Gulp / stream-based build system users, using gulp-insert to prepend the parcelRequire global declaration. Thanks for the idea @idanilt!

const gInsert = require('gulp-insert')

let parcelPatchTask = ()=>{
	return gulp.src(p(paths.dist, '**/*.js'))
		.pipe(gInsert.prepend(';var parcelRequire;\n'))
		.pipe(gulp.dest(paths.dist))
}

twome added a commit to twome/parcel that referenced this issue Mar 16, 2019
twome added a commit to twome/parcel that referenced this issue Mar 16, 2019
@twome
Copy link

twome commented Mar 16, 2019

Please see my PR above. It's pretty disappointing that there was no fix or PR for this show-stopper bug that requires literally a 4-character fix, for a 30k star project used by so many people :/

@SteveALee
Copy link

SteveALee commented Jul 9, 2020

My use is to use native ES modules for dev and then bundler for production for older browsers. I also happen to be using snowpack.

If you say Parcel will not work in this case without rewriting the script include structure between dev and deploy it cannot be used. :(

While I get the error everyhting seems to work. So does the error matter?

@SteveALee
Copy link

if you strip <script type="module"> you need to add defer to get the same behaviour

@sippeangelo
Copy link

sippeangelo commented Sep 22, 2020

I'm not using type="module" anywhere yet I'm getting this error in Parcel v2. wtf am I doing wrong?! It works fine with serve, but the build is all messed up.

@psytron
Copy link

psytron commented Sep 26, 2020

Observation: In addition to that LOL fix from Twitter, this issue can also be hackishly fixed by inserting any regular script tag ( not type=module ) before your type=module entry point. Without it Parcel still generates these errors.

<script src="seemingly_anything.js"></script>
<script src="es6_entry_point.js" type="module"></script>

@einarpersson
Copy link

einarpersson commented Sep 26, 2020

I get this error whether I use type="module" or not. And the weird thing is that it only appears when I deploy it to vercel. But it works with npm start locally. And it only happens if index.js includes an import statement.

EDIT: more testing
It simply does not work with npm run build. But npm start works.

@TimDaub
Copy link

TimDaub commented Oct 30, 2020

For me, this error also happens when I put a defer tag on my <script>. I used to just add the var parcelRequire trick, but it seems not to work anymore. Does anyone have an idea how to reliably fix this?

Edit: Actually, the console says that the connection was lost. But on file changes, the page still appropriately updates...

@EmranMR
Copy link

EmranMR commented Nov 28, 2020

Ok so I am new to parcel. This is how I got into trouble like many of you.... it's quite an annoying bug!🤦‍♂️

  • I initiated the parcel on my html file with type="module" in my script tag, as you would do. Now that would mess everything up! do NOT do this. Once that happens you need to follow these steps to reverse:

do NOT do <script type="module" src="./main.js"></script>

How to Fix/Reverse?

  1. You need to stop parcel in your CLI
  2. Delete .parcel-cache folder in your directory which was created when you ran the parcel start| parcel serve...
    ☝️ - THIS IS VERY IMPORTANT OR DEFER AND ASYNC attributes won't WORK ☝️
  3. Delete type="module" from your index.html
  4. replace with either
  • <script defer src="./main.js"></script>
  • <script async src="./main.js"></script>
  • or just dump the tag old fashion way, to the bottom of your html
  1. run the parcel serve again and you are all good to go, auto refresh for everything back on! 👍

Since this is a bug that has been haunting people since 2018, and the index.html in the dist folder is dynamically produced, why dont we somehow make parcel to remove type="module" in the html file when it encounters. Also another bug is when it generates the script tag in the dynamically generated html file in dist folder, Parcel adds an empty string to the async or defer attribute.... img below👇

image🤷‍♂️🤷‍♂️🤷‍♂️🤷‍♂️🤷‍♂️🤷‍♂️🤷‍♂️🤷‍♂️🤷‍♂️

  • MacOS BigSur
  • Editor VSCode
  • Parcel v.2.0.0 beta1

@OxiBo
Copy link

OxiBo commented Nov 29, 2020

When I remove type="module", github pages does not show any styles on my page

@mellonis
Copy link

  1. Delete type="module" from your index.html

One does not simply delete type="module" from the code. Especially if you want to use native ES modules.

I have strong believe that defer and async attributes do not give us that — they do not provide module isolation, that's why it's impossible to use imports there.

When you delete type="module", you loose power of native ES modules.

I think that it's good if some web app can work in modern browsers "as is", without a preprocessing. When I use ES modules, modern browsers understand how to process them.

The problem is: when I add the parcel bundler, all goes wrong.

@mellonis
Copy link

I used this workaround.

@EmranMR
Copy link

EmranMR commented Nov 29, 2020

I used this workaround.

Thank you so much for pointing this out by @dfkaye from this thread. Much better and more elegant fix, without losing the power of type module!

If only this was magically fixed in V2..

@kungfooman
Copy link

Will Parcel ever support ES6? Issue open since 2018, check clock, it's three years by now

@talentlessguy
Copy link

@kungfooman parcel v2 supports type=module

@kungfooman
Copy link

@talentlessguy Did you try that yourself? I just installed parcel@next now with this command line:

parcel watch --public-url . ./src/examples_pc/hokusai.ts --no-hmr --dist-dir build --target es6

But it still produces same error as in this issue

@DeMoorJasper
Copy link
Member

@kungfooman there's an example in this thread on how to do this #1401 (comment)

joelewis added a commit to joelewis/peritext that referenced this issue Nov 27, 2021
Parcel has some [misunderstandings between script tags declared as es module](parcel-bundler/parcel#1401) and it's cascading into the build as console errors inkandswitch#22  inkandswitch#21 

Removing the attribute sorts this out. until they fix it in Parcel.
@doggy8088
Copy link

Add a <script>var parcelRequire;</script> to the <head> solve this issue for me. I have to use type="module" with Parcel because I'm using TypeScript.

@mukaofssn
Copy link

Add a <script>var parcelRequire;</script> to the <head> solve this issue for me. I have to use type="module" with Parcel because I'm using TypeScript.

@doggy8088 which version are you using this fix for?

@doggy8088
Copy link

@mukaofssn 1.12.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests