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.
In a compiled bundle targeting the browser, console.log(global); should behave the same as console.log(window);
console.log(global); throws with global is undefined
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')
)
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"}],
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 buildworks butparcel 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.
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.