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

Imports transformations can break code, including 3rd-party #7125

Closed
emirotin opened this issue Oct 18, 2021 · 1 comment
Closed

Imports transformations can break code, including 3rd-party #7125

emirotin opened this issue Oct 18, 2021 · 1 comment

Comments

@emirotin
Copy link

🐛 bug report

The way Parcel bundles the imported modules can break the code, including 3rd-party.

Short explanation: this happens because all imported methods are called with the module object as their context.

Example: this input

import {raf} from './raf';
raf(() => {});

Gets transformed into

var _raf = require("./raf");
_raf.raf(()=>{
    document.write("It doesn't");
});

Detailed explanation: see below for both real-world and minimal contrived repros.

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

No config, default Parcel 2.0 installation, using parcel serve as an example.

🤔 Expected Behavior

The code that works without bundling should work after bundling. The code that works as a single module should keep working after splitting it into two or more modules.

😯 Current Behavior

All imported functions are called with the module object as their context. This can break certain methods, requestAnimationFrame is a notable real-world example.

💁 Possible Solution

Unscoped calls should remain the same.

🔦 Context

I tried porting a project from gulp+babel to parcel 2. The calls to requestAnimationFrame (issued by the tiny-slider library) got broken.

💻 Code Sample

Real-World example

Let's look at this code first https://github.com/emirotin/parcel-issue/tree/main/real-world.

It's a simplified port of the first example from http://ganlanyuan.github.io/tiny-slider/demo/, the official demo of the tiny-slider library, quite popular front-end lib (4.2K GitHub stars).

This library exports detached requestAnimationFrame from a utility module. Because parcel makes the call to raf into something like _raf.raf, now requestAnimationFrame is called with _raf as its context. In Firefox, this generates an error like

Uncaught TypeError: 'requestAnimationFrame' called on an object that does not implement interface Window.

The same code would work with other bundlers, specifically, I have this error in the real project which worked with gulp+babel.

Contrived example

Check this working code https://github.com/emirotin/parcel-issue/tree/main/contrived-working
It proves that detaching requestAnimationFrame is not a problem per se.

Now let's transform it by moving raf to a module of its own: https://github.com/emirotin/parcel-issue/tree/main/contrived-broken
And now it fails!

Some arguments

One can say that the problem is with the code and not the tool.

But the example above proves that the code does nothing illegal. Yes, the problem can be fixed with the code (by doing something along the lines of raf = window.requestAnimationFrame.bind(window);). But the code is valid (see the contrived-working example, it's OK to call detached raf, but it's not OK to call it with non-Window context), and the bundler should not break the legal code.

tiny-slider is a very popular library, widely tested with different bundlers.

Another argument is that the code like this works when in a single module, and splitting the working code into multiple modules should not break it. And a similar argument is that this code would work without bundling, so it should keep working after being bundled.

🌍 Your Environment

Software Version(s)
Parcel 2.0
Node v14.17.2
npm/Yarn 6.14.13
Operating System Ubuntu
@mischnic
Copy link
Member

mischnic commented Jan 3, 2023

If I understand the problem correctly, this should be solved with #7956

@mischnic mischnic closed this as completed Jan 3, 2023
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

2 participants