【问题标题】:Importing predefined functions into an ES6 module将预定义函数导入 ES6 模块
【发布时间】:2019-01-10 23:05:28
【问题描述】:

第 1 部分: 在我的主 .js 文件中,我设置了几个快捷功能:

// 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 );

第 2 部分:

我正在使用 ES6 模块将我的网站的代码拆分为符合逻辑的、可管理的块。目前我的本地构建设置使用Parcel,我相信它使用 Babel 来转译模块。

这些被导入到定义选择器函数的同一个主 .js 文件中:

// 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 );
    } );
} );

这些在主 .js 文件中工作得很好,但在模块文件中不起作用 - 任何尝试使用它们都会在控制台中触发错误,例如Uncaught ReferenceError: $ is not defined

是否可以在模块文件中访问这些函数,而无需在每个模块的顶部重写它们?

干杯????

【问题讨论】:

  • 勾选将 ES6 模块导入全局范围 - stackoverflow.com/questions/35600751/…
  • 如何导出选择器函数?
  • @Troopers 对不起,我才意识到我写的问题不是特别好。我已经更新它以清除它。但基本上,选择器函数是在我的主 JS 文件的顶部定义的;在文件的更下方,我将模块导入该文件。

标签: javascript ecmascript-6 es6-modules parceljs


【解决方案1】:

是否可以在模块文件中访问这些功能?

没有。它们在主模块的范围内。您可以导出它们并在其他模块中导入它们,但这是不可取的 - 它会在您的入口点创建循环依赖。

没有在每个模块的顶部重写它们?

只需将它们放在自己的模块中,然后将其导入到任何地方。

// 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) {
     …
}

【讨论】:

  • 谢谢!这很有意义。我不确定 StackOverflow 的礼仪,但可以问一个后续问题吗?我只是想知道使用您的语法 import {init as initBGVideo} from ... 与我使用的语法 import BGVideo from ... 相比有什么优势?
  • @jono_hayward 我已将其更改为 init 函数,因为构造函数不应该产生副作用——您只是创建了一个实例(使用 new),但随后什么也没做。避免这种情况。关于命名函数的导出与默认导出,这仅取决于您的模块是否提供其他任何东西。我想默认导出也一样好。 (也许我想演示为命名导入使用别名?我忘了)。已编辑。
猜你喜欢
  • 2017-11-19
  • 2018-03-18
  • 2018-09-28
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 2017-01-04
  • 1970-01-01
相关资源
最近更新 更多