Parcel: Convert `global` to window for browser targets.

Created on 17 Jul 2018  路  17Comments  路  Source: parcel-bundler/parcel

馃悰 bug report

I'm working on prototyping our build in parcel to measure performance. One of the things that I noticed different between webpack and parcel through my work is that webpack will wrap calls to global in a function that exposes the global variable as window. Parcel bundles just fail when run in the browser with global is undefined.

馃 Expected Behavior

In a compiled bundle targeting the browser, console.log(global); should behave the same as console.log(window);

馃槸 Current Behavior

console.log(global); throws with global is undefined

馃拋 Possible Solution

One solution is to follow webpack's solution. For any file that includes a reference to global wrap the contents of the file with:

(
  function (global) {
    // body of original module.
  }.call(this, require('parcels-global-shim')
)

馃敠 Context

馃捇 Examples

Bug Feature

Most helpful comment

I couldn't come up with a situation where it isn't replaced correctly with Parcel 2. If you do come across a case where it isn't, please open a new issue with a code sample.

All 17 comments

Closing this for now as I couldn't repro in a smaller repository. It may be something specific to our build. I'll reopen if I find more on this.

Re-opened as I was able to track this down to using type="module" in my script tags. We don't actually need this, so we can work around, but figured I'd leave this open for tracking purposes.

I can reproduce this in my react project when I add type="module"

related source code
https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/__forks__/setImmediate.js

parcel generated js

"..\\node_modules\\fbjs\\lib\\setImmediate.js":[function(require,module,exports) {
var global = arguments[3];
/**
 * Copyright (c) 2013-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */

'use strict';

// setimmediate adds setImmediate to the global. We want to make sure we export
// the actual function.

require('setimmediate');
module.exports = global.setImmediate;
},{"setimmediate":"..\\node_modules\\setimmediate\\setImmediate.js"}],

2833

I have the same problem with global by trying to build a website based on web components in which case type="module" is necessary.

Ideally, something babel based could polyfill globalThis. But strangely enough @babel/preset-env doesn't do this.

Hi! If Parcel is trying to be a bundler for _node_ modules, why is it not correctly providing all browser-compatible node globals, in this case, global?

With Parcel 2, console.log(global) is turned into

var $parcel$global =
    typeof globalThis !== "undefined"
        ? globalThis
        : typeof self !== "undefined"
        ? self
        : typeof window !== "undefined"
        ? window
        : typeof global !== "undefined"
        ? global
        : {};
console.log($parcel$global);

for both Node and Browser targets (though it's not really necessary for Node...)

@mischnic it's necessary for packages that support node/browser versions that predate globalThis. Sounds like this issue may be fixed in Parcel 2, then?

It's not fixed in parcel 2 as that is what I was using when I came across this issue

Could someone please give a code sample that doesn't work as expected?

I'll make it now 馃憤

I came across the issue by using @formatjs/intl-numberformat/polyfill package which depends upon the has-symbols which is what was throwing the error due to global not being defined.

I can no longer recreate this issue in parcel 2 馃槄 Here is my code sample which does now work -- https://codesandbox.io/s/quirky-microservice-0gnm9

I'm pretty sure I hit this issue only 3 days ago but I never committed that work to my repo because it wasn't working, instead I raised an issue on [has-symbols[(https://github.com/inspect-js/has-symbols/pull/18).

I guess I could have been using parcel 1 by mistake 馃 .

Is it possible that parcel build works but parcel build --no-scope-hoist (which is more similar to dev serve mode) doesn't?

Is it possible that parcel build works but parcel build --no-scope-hoist (which is more similar to dev serve mode) doesn't?

I guess it is possible but I only used parcel serve when I hit the issue

I couldn't come up with a situation where it isn't replaced correctly with Parcel 2. If you do come across a case where it isn't, please open a new issue with a code sample.

@mischnic I鈥檓 seeing this not work with has-symbols when coming in as a dependency of semantic-ui-react. Here鈥檚 a sample. It works okay in CodeSandbox but if you download it and npm install; npm start it should fail with:

Uncaught TypeError: Cannot read property 'Symbol' of undefined

The line in question looks like:

var origSymbol = global.Symbol;

There鈥檚 a related issue here (https://github.com/inspect-js/has-symbols/issues/4) but AFAICT parcel should be rewriting this?

On the project I鈥檓 working on (and probably the previous example) build does work and build --no-scope-hoist does not work.

A workaround for using serve is to remove the type=module attribute, and revert that before doing build.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mnn picture mnn  路  3Comments

jzimmek picture jzimmek  路  3Comments

466023746 picture 466023746  路  3Comments

termhn picture termhn  路  3Comments

philipodev picture philipodev  路  3Comments