0

Part 1: In my master .js file, I have a couple of shortcut functions set up:

// Selector shortcuts - mimic jQuery style selectors but using more modern, standard code
const $  = ( selector, scope = document ) => scope.querySelector( selector );
const $$ = ( selector, scope = document ) => scope.querySelectorAll( selector );
const on = ( el, type, listener ) => el.addEventListener( type, listener );

Part 2:

I'm using ES6 modules to split up the code for my site into logical, manageable chunks. Currently my local build set up is using Parcel, which I believe uses Babel to transpile the modules.

These are imported into the same master .js file in which the selector functions are defined:

// Selector shortcuts - mimic jQuery style selectors but using more modern, standard code
const $  = ( selector, scope = document ) => scope.querySelector( selector );
const $$ = ( selector, scope = document ) => scope.querySelectorAll( selector );
const on = ( el, type, listener ) => el.addEventListener( type, listener );

// Load components
import BGVideo    from './BGVideo';
import FieldLabel from './FieldLabel';

// Invoke components
on( document, 'DOMContentLoaded', ( e ) => {

    $$( '[data-background-video]' ).forEach( ( el ) => {
        new BGVideo( el );
    } );

    $$( '.c-form__item' ).forEach( ( el ) => {
        new FieldLabel( el );
    } );
} );

These work great within the master .js file, but not within the module files - any attempt to use them triggers an error in the console e.g. Uncaught ReferenceError: $ is not defined

Is it possible access to these functions within the module files, without rewriting them at the top of every module?

Cheers

jono_hayward
  • 183
  • 1
  • 2
  • 10
  • check Import ES6 module into global scope - https://stackoverflow.com/questions/35600751/import-es6-module-into-global-scope – Akrion Aug 03 '18 at 06:33
  • 1
    How do you export the selector functions? – Troopers Aug 03 '18 at 07:08
  • @Troopers Sorry, I just realised that I didn't write the question particularly well. I've updated it to clear it up a bit. But basically, the selector functions are defined at the top of my main JS file; further down in the file I am importing the modules into that file. – jono_hayward Aug 04 '18 at 10:51

1 Answers1

1

Is it possible access to these functions within the module files?

No. They are in the scope of the master module. You could export them and import them in the other modules, but that's not advisable - it would create a circular dependency on your entry point.

without rewriting them at the top of every module?

Just put them in their own module, and import that everywhere.

// dom_helpers.js
/* Selector shortcuts - mimic jQuery style selectors but using more modern, standard code */
export const $  = (selector, scope = document) => scope.querySelector(selector);
export const $$ = (selector, scope = document) => scope.querySelectorAll(selector);
export const on = (el, type, listener) => el.addEventListener(type, listener);

// master.js
// Load components
import initBGVideo from './BGVideo';
import initFieldLabel from './FieldLabel';
import {$$, on} from './dom_helpers';

// Invoke components
on(document, 'DOMContentLoaded', e => {
    for (const el of $$('[data-background-video]')) {
        initBGVideo(el);
    }
    for (const el of $$('.c-form__item')) {
        initFieldLabel(el);
    }
});

// BGVideo.js
import {$, $$, on} from './dom_helpers';

export default function init(el) {
     …
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thank you! That makes perfect sense. I'm not sure on the StackOverflow etiquette, but is it ok to ask a followup question? I'm just wondering what the advantage is of using your syntax `import {init as initBGVideo} from ... ` vs the one I've used, `import BGVideo from ...` ? – jono_hayward Aug 05 '18 at 23:16
  • @jono_hayward I've changed it to an init function because constructors should not do side effects - you were just creating an instance (with `new`) but then didn't do anything with it. Avoid that. Regarding the export of a named function vs a default export, that just depends on whether your module is providing anything else. I guess a default export is just as fine. (Maybe I wanted to demonstrate using aliases for named imports? I forgot). Edited. – Bergi Aug 06 '18 at 14:08