parcel: Some dependencies that rely on window don't work

BUG: An older website that imports jQuery and Bootstrap from locally downloaded files don’t have their dependencies properly running; Bootstrap complains that jQuery and $ are not found. It seems that either the order from the HTML is not respected, or that JS that installs to the root window are not working correctly.

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

        <script src="LIBS/jquery.min.js"></script>
        <script src="LIBS/bootstrap.min.js"></script>

$> parcel index.html

🤔 Expected Behavior

Imported scripts run correctly

😯 Current Behavior

Bootstrap complains about not finding jquery. Not sure if import order or window problem

🔦 Context

Can’t use Parcel if this doesn’t work for older / retrofit websites.

🌍 Your Environment

Software Version(s)
Parcel 1.2.0
Node v8.9.1
npm/Yarn npm v5.5.1
Operating System Windows 10

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 27
  • Comments: 29 (6 by maintainers)

Commits related to this issue

Most upvoted comments

The workaround from @sundayz

import jQuery from "jquery";
window.$ = window.jQuery = jQuery;
import "lib-that-depends-on-jQuery";

didn’t work for me, since the library that depends on jQuery does so in a sync way, and because parcel ends up generating

"use strict";
var _ = _interopRequireDefault(require("jquery"));
require("lib-that-depends-on-jQuery");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
window.$ = window.jQuery = _.default;

assigning jQuery on window happens too late.

Combining the workaround with the hint from @devongovett does the trick for me:

const jQuery = require("jquery")
window.$ = window.jQuery = jQuery;
require("lib-that-depends-on-jQuery")

since parcel generates in that case

var jQuery = require("jquery");
window.$ = window.jQuery = jQuery;
require("lib-that-depends-on-jQuery");

2 and a half years and nobody posted at least a workaround?

This worked for me in a project that uses bootstrap and jquery. In my app.js (entry point for parcel):

import jQuery from "jquery";
window.$ = window.jQuery = jQuery; // workaround for https://github.com/parcel-bundler/parcel/issues/333
import 'bootstrap/dist/js/bootstrap.bundle';

Import order matters. Couldn’t get it to work with the normal bootstrap js include because it couldn’t resolve the dependency for Popper, even though I’m not using tooltips or popper anywhere.

Sometimes corporate policy requires self hosting all dependencies

unfortunately, const $ = require('jQuery'); doesn’t work for me. At least, I can’t do that at the top level and have it work everywhere (like I could with webpack, which we’re moving from). I think it works if I do that in every single file that uses jquery.

This is because jQuery disables setting itself on the window global in a CommonJS environment (which Parcel is). See https://github.com/jquery/jquery/blob/master/src/wrapper.js#L29 and https://github.com/jquery/jquery/blob/2d4f53416e5f74fa98e0c1d66b6f3c285a12f0ce/src/exports/global.js#L30-L32.

If you need it to be accessible on window, you could do something like window.$ = require('jquery'). Does that work?

This seems like a valid use case for a parcelignore. They’re being included in the correct order, but I’m guessing the closure scope is preventing them from mounting to the window correctly.

I’m not sure what we should do about this. The cause of this issue is that jQuery relies on this being the global object, but in a CommonJS environment (which Parcel emulates) this refers to the module object.

Perhaps we could make it so that if you imported a script from HTML, it would retain this in the entry module, but as soon as you require it would turn into the module object since it is in a common js context. Then you could have <script type="commonjs"> and <script type="module"> for commonjs and ES6 module environments. Obviously this is a breaking change from the current default, but with Parcel 2 on the horizon I’d like to revisit this issue and get some options that make sense. Thoughts?