SteveO
SteveO

Reputation: 751

How to Include JQuery in a Svelte/Sapper Application?

There are many components that still require JQuery that I need to use (unfortunately).

What is the best way to do this in Svelte/Sapper? Should I use ES6 Imports, modify rollup, or what is the best approach?

For example, I need to include a pivot table, grid, scheduler, etc from DevExpress or Kendo UI.

I can pull in JQuery globally in the template.html file and get things to work, but I'm sure this is not the best way.

Upvotes: 2

Views: 3800

Answers (2)

milahu
milahu

Reputation: 3609

window.$ is reserved in svelte, so you must patch your library
to use jQuery in noconflict mode, like

sed -E 's/(\W?)\$(\W)/\1jQuery\2/g' library.js >library.noconflict.js

to replace $( with jQuery( and $. with jQuery.

(\W?) matches an optional non-word char (whitespace, parens),
to avoid replacing func_$( to func_jQuery(

\$(\W) matches $( or $. or or $) or $ or ....

in my case i had to patch goldenlayout.js version 1.5.9, like

sed -E 's/(\W?)\$(\W)/\1jQuery\2/g' \
node_modules/golden-layout/dist/goldenlayout.js \
>src/goldenlayout-1.5.9.noconflict.js

is also had to replace

(function($){
// ....
        define( [ 'jquery' ], function( jquery ) {
            $ = jquery;
            return lm.LayoutManager;
        } ); // jshint ignore:line
// ....
} );})(window.$);

with

(function(){
// ....
        define( [], function() {
            return lm.LayoutManager;
        } ); // jshint ignore:line
// ....
} );})();

before running sed to avoid variable shadowing
in this case local jQuery vs global window.jQuery

sed might replace too much (string contents)
so ideally do an AST transform like

// tools/patch-goldenlayout.js

// pnpm i -D acorn estree-walker magic-string

const input_file = "../node_modules/golden-layout/dist/goldenlayout.js";
const output_file = "../src/goldenlayout.noconflict.js";

const id_search = '$';
const id_replace = 'jQuery';

const acorn_parse = require("acorn").parse;
const estree_walk = require("estree-walker").walk;
const magicString = require("magic-string");
const fs = require("fs");

const code_old = fs.readFileSync(input_file, 'utf8');
let code = new magicString(code_old);

const ast = acorn_parse( code_old, {
    sourceType: 'module', ecmaVersion: 11 /* year 2020 */ });

estree_walk( ast, {
  enter: function ( node, parent, prop, index ) {
    if (node.type == 'Identifier' && node.name == id_search) {
      code.overwrite(node.start, node.end, id_replace);
    }
}});

fs.writeFileSync(output_file, code.toString());

Upvotes: 1

Rich Harris
Rich Harris

Reputation: 29615

Including it as a <script> in template.html is fine. Alternatively, do

import jQuery from 'jquery';

in any components or modules that use it.

Upvotes: 4

Related Questions