支持 ES5 模块中的 ES6 导入

Len*_*ijn 8 javascript ecmascript-6 es6-modules

对于我的一年级学生,我提供了一个使用 Revealing Module Pattern 编写的基于 ES5 的简单库。这是“主”模块/命名空间的一个片段,它将容纳其他扩展:

window.Library = (function ($) {
    if (!$) {
        alert("The Library is dependent on jQuery, which is not loaded!");
    }

    return {};
})(window.jQuery);
Run Code Online (Sandbox Code Playgroud)

这适用于几乎 99.9% 的 Web 开发新手,并且没有将 ES6 等花哨的东西与 Webpack 或 Babel 结合使用。

0.1% 现在要求我提供基于 ES6 的版本,可以正确导入。我很乐意提供这个,但我有点坚持如何最好地解决这个问题。

我显然想保持 ES5 的方式,所以我的学生可以使用脚本标签包含文件并Library.SomeExtension.aFunction();在任何他们喜欢的地方输入。最重要的是,一些扩展依赖于 jQuery,它以与上面的代码片段类似的方式注入。

我现在正在寻找一些可维护的方法来获得两全其美的方法,使用一个代码库,将 jQuery 作为依赖项。我想给 99.9% a window.Library,而我想给 0.1% 一种使用import Library from 'library'.

我可以用一个 JS 文件来完成这两个任务吗?或者我需要一个特殊的 ES6 版本(不是问题)?最重要的是:我将如何以可以支持两种情况的方式重新调整我的代码(都类似于上面的代码段)?

任何和所有指针将不胜感激!

编辑:正如一个方面说明,我已经有一个gulpfile.js在其中贯穿这个库的地方Babelminifiers和其他的东西。所以必须扩展它来解决上述问题不是问题!

Len*_*ijn 5

经过几个晚上的移动代码并安装了如此多的 gulp 软件包,我什至不记得我尝试过的所有软件包,我最终确定了一些我不太满意的东西。

首先,回答我自己的问题,@Bergi 在评论中也支持这个问题:

简短回答:不,您不能以任何方式(现在)将 ES6 语法与 ES5(模块)混合在一个文件中,因为浏览器会在使用export.

长答案:从技术上讲,您可以将脚本元素类型设置为“模块”,这将使浏览器接受export关键字。但是,您的代码只会运行两次(一次在加载时,一次在导入后)。如果你能忍受这一点,那么“否”就变成了“是”,有点。

那么我最终做了什么?让我先说一下,我真的很想在输出 ES5 文件中保留我(现在)拥有的 IIFE 模块设置。我将我的代码库更新为纯 ES6,并尝试了各种插件组合(包括 @David Bradshaw 提到的 Rollup.js)。但是我根本无法让它们工作,或者它们会以浏览器无法再加载模块或放弃源映射支持的方式完全破坏输出。随着学生们正在进行的项目即将结束,我已经为 0.1% 的学生浪费了足够的业余时间。所以明年运气更好,以获得“更好”的解决方案。

  1. 我基于 jQuery 的 UMD 模式(如@Sly_cardinal 所述)并将该代码放入Library.umd.js. 对于 ES6 部分,我制作了一个Library.es6.js只有 aexport default Library的。

  2. 在这两个文件中,我放置了一个多行注释/*[Library.js]*/,我想在其中注入连接的未缩小的 Library.js。

  3. 我修改了我现有的 Gulp 任务,只构建Library.jswithconcat并将Babel其存储在一个临时位置。我选择在这个过程中牺牲源映射支持,因为连接的代码在输出中是完全可读的。从技术上讲,源映射支持“有效”,但它仍然会过多地抛弃调试器。

  4. 我添加了一个额外的 Gulp 任务来读取 temp 的内容Library.js,然后对于步骤 1 中的每个文件,我会找到并用内容替换多行注释。保存生成的文件,然后将它们通过最终concat(例如与 jQuery 捆绑)terser和 sourcemap 生成。

最终结果是两个文件:

  • 一种支持 UMD/ES5 浏览器
  • 一种支持 ES6

虽然我对结果很满意,但我不喜欢 Gulp 任务链和流程前半部分失去 sourcemap 支持。如前所述,我尝试了许多 gulp 插件来实现相同的效果(例如gulp-inject),但它们要么无法正常工作,要么对源映射做了奇怪的事情(即使他们声称支持它)。

在接下来的努力中,我可能会研究与 Gulp 不同的东西,或者制作我自己的插件来完成上述工作,但正确:P