ES6: import module from URL
Asked Answered
R

6

108

Is it possible to import javascript module from external url in ES6?

I tried (using babel-node):

import mymodule from 'http://...mysite.../myscript.js';
// Error: Cannot find module 'http://...mysite.../myscript.js'
Rhapsody answered 5/1, 2016 at 8:33 Comment(0)
G
53

2018 Update: The module loader spec is now a part of the ES Spec - what you are describing is allowed and possible with <script type="module"> in browsers and with a custom --loader with Node.js as well as with Deno if you're into that.


The module loader spec and the import/export syntax are separate. So this is a property of the module loader (not a part of the ES spec). If you use a module loader that supports plugins like SystemJS.

Grigri answered 5/1, 2016 at 8:43 Comment(6)
Browserify plugin: browserify-cdnjsJuridical
Wait, isn't the import syntax the native module loader in ES6?Jopa
@Jopa specifying the syntax for loading modules (i.e. import and export syntax) and specifying how to load it are two separate tasks - the browser and node.js would use different mechanisms for it for instance - so it can't be a part of the language. In general - interacting with the environment is not a task the spec is interested in.Grigri
Correct, the underlying mechanism may be different, but the import syntax is supposed to import the module right? Obviously we have no current examples of the syntax working natively but presumably at some point in the future browsers will support it.Jopa
@Jopa At some point browsers will have a native module loader, but there is no specification as to how that will load. Maybe it will load external URLs, maybe it won't. No telling until someone writes oneJuridical
@Jopa Chrome and Firefox support it under a flag. The spec is polyfilled by github.com/ModuleLoader/es6-module-loader (a subset of systemjs). Files that call System.register would likely work - other files will likely not at the moment. There is also script type='module' for writing module code inside the browser. This is all mostly guessing.Grigri
B
31

Update in 2022, it seems it works at least in latest Chrome, Firefox and Safari as of now, as long as the server provides a response header of content-type: application/javascript; charset=utf-8 for the js file.

Try these two files with a vanilla web server:

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>

hello.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);

This is a HUGE deal! Because we can say bye to Webpack now. I am a little too excited now!

Bound answered 18/1, 2022 at 3:38 Comment(2)
This is exciting. Note as of Jan 2022 it doesn't work in a Stackblitz project stackblitz.com/edit/js-y9xn5f or on Codesandbox - but works OK in my local dev environment.Jocasta
That’s blocked by webpack. Webpack thought it’s a dynamic import and it wants to bundle the js at compile time. The reason why I thought it’s huge and exciting is because with this feature, we will have significant less dependence on webpack.Bound
A
11

You could also use scriptjs which in my case requires less configs.

var scriptjs = require('scriptjs');

scriptjs('https://api.mapbox.com/mapbox.js/v3.0.1/mapbox.standalone.js', function() {
    L.mapbox.accessToken = 'MyToken';
});
Apparel answered 6/1, 2017 at 11:45 Comment(0)
H
5

TL;DR:

For now, no.

Long answer:

There are two different specs: the ES6 defines the syntax to exporting/importing. And there is the Loader Spec that actually defines how this modules will load.

Spec-speak aside, the important part for us developers is:

The JavaScript Loader allows host environments, like Node.js and browsers, to fetch and load modules on demand. It provides a hookable pipeline, to allow front-end packaging solutions like Browserify, WebPack and jspm to hook into the loading process.

This division provides a single format that developers can use in all JavaScript environments, and a separate loading mechanism for each environment. For example, a Node Loader would load its modules from the file system, using its own module lookup algorithm, while a Browser Loader would fetch modules and use browser-supplied packaging formats.

(...)

The primary goal is to make as much of this process as possible consistent between Node and Browser environments. For example, if a JavaScript program wants to translate .coffee files to JavaScript on the fly, the Loader defines a "translate" hook that can be used. This allows programs to participate in the loading process, even though some details (specifically, the process of getting a particular module from its host-defined storage) will be different between environments.

So we depend on the host environment (node, browser, babel, etc) to resolve/load the modules for us and provide hooks to the process.

Hayseed answered 23/3, 2016 at 12:45 Comment(1)
This answer: "no" is invalid as in 2018/2019Opah
H
3

The specification describes how exactly a module specifier in import is resolved:

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

It says URLs are allowed, both absolute and relative ones (starting with /, ./, ../), and it does not differentiate between static and dynamic imports. Further in the text, there's an "Example" box showing examples of valid specifiers:

  • 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
Humpage answered 2/9, 2021 at 22:32 Comment(0)
D
-1

example in pure javascript how to import google code and replace element on any page to google translate button (can be run from browser debug console for any site you want)

importScriptURI("https://translate.google.com/translate_a/element.js"); 
document.getElementsByTagName("h1")[0].innerHTML='<div id="google_translate_element"></div>';
setTimeout(()=>{ new google.translate.TranslateElement({pageLanguage: 'en'},'google_translate_element');},1000);
Drucilladrucy answered 22/1, 2023 at 19:55 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Laraelaraine

© 2022 - 2024 — McMap. All rights reserved.