【问题标题】:ES6: import module from URLES6:从 URL 导入模块
【发布时间】:2016-04-09 00:23:13
【问题描述】:

是否可以在 ES6 中从外部 url 导入 javascript 模块?

我试过(使用 babel-node):

import mymodule from 'http://...mysite.../myscript.js';
// Error: Cannot find module 'http://...mysite.../myscript.js'

【问题讨论】:

    标签: javascript ecmascript-6 es6-modules es6-module-loader


    【解决方案1】:

    2018 更新:模块加载器规范现在是 ES 规范的一部分 - 您所描述的内容在浏览器中使用 <script type="module"> 和使用 Node.js 以及 Deno if 的自定义 --loader 是允许和可能的你很喜欢。


    模块加载器规范和导入/导出语法是分开的。所以这是模块加载器的一个属性(不是 ES 规范的一部分)。如果您使用支持 SystemJS 等插件的模块加载器。

    【讨论】:

    • 浏览器插件:browserify-cdnjs
    • 等等,import 语法不是 ES6 中的原生模块加载器吗?
    • @slebetman 指定加载模块的语法(即importexport 语法)并指定如何 加载它是两个独立的任务——浏览器和节点。例如,Node.js 会使用不同的机制——所以它不能成为语言的一部分。一般来说 - 与环境交互不是规范感兴趣的任务。
    • 正确,底层机制可能不同,但是导入语法应该是导入模块吧?显然,我们目前没有本机工作的语法示例,但大概在未来的某个时候浏览器会支持它。
    • @slebetman Chrome 和 Firefox 在标志下支持它。该规范由github.com/ModuleLoader/es6-module-loader(systemjs 的一个子集)填充。调用 System.register 的文件可能会工作 - 其他文件目前可能不会。还有script type='module' 用于在浏览器中编写模块代码。这都是猜测。
    【解决方案2】:

    您也可以使用scriptjs,在我的情况下需要更少的配置。

    var scriptjs = require('scriptjs');
    
    scriptjs('https://api.mapbox.com/mapbox.js/v3.0.1/mapbox.standalone.js', function() {
        L.mapbox.accessToken = 'MyToken';
    });
    

    【讨论】:

      【解决方案3】:

      TL;DR:

      目前,没有

      长答案:

      有两种不同的规范:ES6 定义了导出/导入的语法。 还有 Loader Spec 实际定义了如何这个模块将被加载。

      抛开规范不谈,对我们开发者来说重要的部分是:

      JavaScript 加载器允许 Node.js 和浏览器等宿主环境按需获取和加载模块。它提供了一个可挂钩的管道,允许 Browserify、WebPack 和 jspm 等前端打包解决方案挂钩到加载过程中。

      该部分提供了一种开发人员可以在所有 JavaScript 环境中使用的单一格式,并为每个环境提供了单独的加载机制。例如,Node Loader 会使用自己的模块查找算法从文件系统加载其模块,而 Browser Loader 会获取模块并使用浏览器提供的打包格式。

      (...)

      主要目标是让这个过程在 Node 和 Browser 环境之间尽可能地保持一致。例如,如果一个 JavaScript 程序想要即时将.coffee 文件翻译成 JavaScript,加载器定义了一个可以使用的“翻译”钩子。这允许程序参与加载过程,即使某些细节(特别是从主机定义的存储中获取特定模块的过程)在环境之间会有所不同。

      所以我们依赖宿主环境(节点、浏览器、babel 等)为我们解析/加载模块并为进程提供挂钩。

      【讨论】:

      • 这个答案:“否”在 2018/2019 年无效
      【解决方案4】:

      2022 年更新,目前看来至少在最新的 Chrome、Firefox 和 Safari 中有效,只要服务器为 js 文件提供了content-type: application/javascript; charset=utf-8 的响应头。

      用普通网络服务器试试这两个文件:

      index.html

      <!DOCTYPE html>
      <html lang="en-US">
      <head>
         <meta charset="utf-8">
         <title>Hello World</title>
         <script type="module" src="./hello.js"></script>
      </head>
      <body>
      </body>
      </html>
      

      你好.js

      import ip6 from 'https://cdn.jsdelivr.net/gh/elgs/ip6/ip6.js';
      
      const el = document.createElement('h1');
      const words = "::1";
      const text = document.createTextNode(ip6.normalize(words));
      el.appendChild(text);
      
      document.body.appendChild(el);
      

      这是一笔大买卖!因为我们现在可以和 Webpack 说再见了。我现在有点太兴奋了!

      【讨论】:

      • 这很令人兴奋。请注意,截至 2022 年 1 月,它在 Stackblitz 项目 stackblitz.com/edit/js-y9xn5f 或 Codesandbox 中不起作用 - 但在我的本地开发环境中可以正常工作。
      • 这被 webpack 阻止了。 Webpack 认为这是一个动态导入,它想在编译时打包 js。我之所以认为它巨大而令人兴奋是因为有了这个功能,我们对 webpack 的依赖将大大减少。
      【解决方案5】:

      规范描述了import 中的模块说明符 是如何被解析的:

      https://html.spec.whatwg.org/multipage/webappapis.html#resolve-a-module-specifier

      上面写着 URL 是允许的,绝对和相对的(以 /./../ 开头),它确实区分静态和动态导入。在正文中,还有一个“示例”框显示了有效说明符的示例:

      • https://example.com/apples.mjs
      • http:example.com\pears.js (becomes http://example.com/pears.js as step 1 parses with no base URL)
      • //example.com/bananas
      • ./strawberries.mjs.cgi
      • ../lychees
      • /limes.jsx
      • data:text/javascript,export default 'grapes';
      • blob:https://whatwg.org/d0360e2f-caee-469f-9a2f-87d5b0456f6f

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-04
        • 1970-01-01
        • 1970-01-01
        • 2018-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多