Scenario
As part of my prototyping process I wanted to bring in tween.js which I can do using a <script> tag on the html portion but I'd like to import this vanilla es5 file directly to my es6 files for various reasons.
What I'd like to do is something like
import * as TWEEN from 'import * as TWEEN from 'https://cdnjs.cloudflare.com/ajax/libs/tween.js/16.7.0/Tween.min.js'
While that seems to load the remote file I don't seem to get methods like TWEEN.Tween etc etc. I suspect all the es5 is disposed of in some sort of closure vacuum > garbage collection.
Question
I realize I can clone this file locally but I'm hoping to streamline my one-off style prototyping by importing cdn files that aren't always es6 friendly. Is this feasible ?
If you would like to inject Tween.min.js which is hosted on CDN via script tag, it will be UMD module, which is not compatible with ESM modules.
But, instead of importing it like you describe above, you can use/call it via window object:
window.TWEEN inside your esm modules.
When Tween.min.js will be loaded and executed it will be attached to window object.
Just to make sure that you are load that script first separately on HTML side, before your esm scripts/apps, otherwise window.TWEEN might be undefined.
Related
Can't understand the difference between the two examples that I just read at the end of the Deno manual section on the deno bundle command:
Bundles can also be loaded in the web browser. The bundle is a
self-contained ES module, and so the attribute of type must be set to
"module". For example:
<script type="module" src="website.bundle.js"></script>
Or you could import it into another ES module to consume:
<script type="module">
import * as website from "website.bundle.js";
</script>
I was under the impression that both forms achieve the same effect (i.e., "fetched and executed immediately, before the browser continues to parse the page"), and the latter is used when a script follows or one wants to narrow down what is imported (e.g., as seen in this answer).
Section 16.6.1.2 Modules of the Exploring ES6 book appears to agree with this assessment.
Reddit thread Difference Es6 import module vs script src="" also seems to confirm this: "Instead of dumping an entire library into your global scope you an instead only include what you need and actually use."
This may be considered a duplicate of other questions (see bottom for the list) but those answers didn't help me much, and the ancillary sources also didn't seem to reveal if my assumption is correct. (On the other hand, it is more than possible that I overlooked something obvious and would have to work on my reading comprehension skills...)
Load javascript as an ES6 module OR via a script tag in the page (tangentially related)
What is the difference between a script tag with src and a script tag that requires a module? (looked promising but not about ES6 modules...)
Classic scripts v/s module scripts in Javascript
WHATWG: Adding JavaScript modules to the web platform
Import js from script tag in HTML file. Possible?
What is the difference between importing js library or reference it in html <script> tag (not about ES6 modules)
Should I reference files in a `script` tag when using ES6 modules in a browser
ES6 import vs <script src> in html
I was under the impression that both forms achieve the same effect
Yes, both of these will have the same effect
(i.e., "fetched and executed immediately, before the browser continues
to parse the page"),
No, that any <script with type="module" will defer by default, so the loading will not block parsing. All deferred scripts are then executed in the order they appear, after parsing and before DOMContentLoaded fires.
and the latter is used when a script follows or
one wants to narrow down what is imported (e.g., as seen in this
answer).
Which one you want to use also depends on what work is done in the bundle. If the bundle only contains libraries, and doesn't create any side effects (ie, interacting with the page, rendering, etc) then you will probably want to import it so that you can use the functions.
If it does have side-effects (ie. a react app that renders to the DOM), and is self-contained, then just including the tag will be enough to get it started
This is vague - I apologize in advance, I am trying to be as succinct as I can with my limited understanding, while exposing my potentially incorrect assumptions.
I have a website that's literally one huge HTML file. It runs scripts defined in-line in a <scripts> tag.
My goal is to move all the scripts into individual .js files and pull them into index.html (or into one another where required). I am familiar with the usage of Node's require and I am familiar with import, as used in Angular. I stress usage because I don't really know how they work.
Assumption 1: I cannot use require - it is purely for Node.js. The reason I bring it up is that I am pretty sure I have seen require in AngularJS 1.5 code, so assuming makes me uncomfortable. I am guessing this was stitched together by WebPack, Gulp, or similar.
Assumption 2: I should use import, but import only works with a URL address, if I have my .js hosted on a server or CDN, it will be be pulled. BUT, I cannot give local pathing (on the server) here - index.html will NOT automatically pull in the dependencies while being served. I need npm/Webpack/other to pre-compile my index.html if I want the deps pulled in on the server.
Assumption 3: Pre-compiling into a single, ready-to-go, html file is the desired way to build things, because the file can be served quickly (assuming it's ready to go). I make the assumption with the recent trend of serving Markdown from CDNs, the appearance of the JAMstack, and the number of sites using Jekyll and such (though admittedly for traditional Jekyll sites).
Assumption 4: I also want to go to Typescript eventually, but I assume that changes nothing, since I will just pull in TS to compile it down to .js and then use whatever solution I used above
Question: If it's clear what I am trying to do and what confuses me, is a decent solution to look into npm/Webpack to stich together my .js files? What would prepare them for being stiched together, using import/export? If so, is there an example of how this is usually done?
As you mentioned, require cannot be used for your purposes, since it is a part of CommonJS and NodeJS's module system. More info on require can be found here: What is this Javascript "require"?
Import is a ES2015 standard JS syntax. But ES2015 standard and everything above it has very limited browser support. You can read more about it here: Import Reference
However, you can still code in the latest standard (thereby enabling the use of import/export etc.,) and then transpile the code to be able to run on the browser. Inorder to do this, you require a transpiler. You can refer Babel which is one of the most popular transpilers : https://babeljs.io/
For your exact purpose, you need to use a module bundler. Webpack/Rollup etc., are some popular module bundlers. They can automatically identify all the JS files referenced through import, combine them and then transpile code to be able to run on the browser (they also use a transpiler) and produce a single JS file (or multiple, based on your configurations).
You can refer the getting started guides of Webpack: https://webpack.js.org/guides/getting-started/
or RollupJS: https://rollupjs.org/guide/en#quick-start
I am learning javascript. I read about how to import and export things between javascript modules. I am making a javascript game which consists of several files. Each defines a class and its methods.
I have two questions:
Only one of the files actually contains code that interacts with the DOM, so in the HTML do i need to include <script src="..."></script> for every js file? or only the one that deals with the DOM?
I first tried only referencing the one js file in the index.html and exporting the classes defined in the other js files and importing them in the js files where those classes are used. But no browser seemed to understand the import/export statements? Isn't that done on client side javascript?
You need referencing all js file in the index.html, because your game will use other file as the module for entry file. And the module file need to be referenced before the entry file.
Yes, export/import can not be used on client side directly, its used in nodejs platform mostly with supporting by some tools like typescript or babel. But you can use them with some tools as told before.
so, i think you can use babel to transform your code to es5 target firstly, then that you can reference them in browser.
If you mean ES6 imports, the import Whatever from “some-resource”; statement requires the “some-statement” to be a URL.
Additionally, the “entry point” script should be <script type=“module” src=“some-url”></script>. The “module” is what tells the user agent that it is loading a JavaScript module and that import statements should be resolved.
You only need to include one <script> tag if that one script correctly imports the rest of your dependency chain.
Browser support for this is still somewhat limited which is why using webpack or some other build step is still recommended until the feature is fully fleshed out.
currently import / export syntax is supported by approximatively 75% of all users browser (caniuse.com).
The very first thing is to put type="module" as an attribute of a <script tag> (Eg. <script type="module">)
Then you can import/export in your modules. And YES modules need to export a value (variable, function...) to be able to use it in another script, but this is optionnal since you can just execute script without the need to export something.
Documentation:
import
export
Very good article on how to use module in browsers
Keep in mind that is not yet a supported feature and you will need a polyfill if you mind about browser compatibility
Since mostly we're using modules and import statement transpiling them with tools like Babel, I'm intrigued about how native Web browser's implementations will load external files with the so-called import statement.
Will modules be loaded using XmlHttpRequest/XmlHttpRequest2 under the hoods?
AFAIK, the whole standard defines a programmatic API as System global variable where there're methods like System.define to evaluate a JavaScript source code and register it as a named module.
Does this mean that actual module system implementation won't cover external file module loading (meaning that a library/framework or your own vanilla JavaScript code should get the source code using an XmlHttpRequest?)
There is a loader standard being actively developed by the WHATWG that will handle the loading in the browser: http://whatwg.github.io/loader/
As this is still a work in progress, things might still change. As far as I can see, the exact way that the browser loads the files is not specified, but it is probable that it will use the Fetch API (the Promise-based replacement for XmlHttpRequest2).
In the end, you should be able to use the module syntax with script tags and the browser (or whatever your JS environment is) will handle the loading:
<script type="module">
import x from 'y';
import a from 'b';
...
</script>
or
<script type="module" src="y.js"></script>
Currently, browsers are at different points of implementation:
IE/Edge: Under Consideration
Firefox: In progress
Chrome: In progress
Webkit: Meta Bug
Please feel free to correct me or extend this answer.
Why not use it as a general component pattern for Javascript, including browser-executed Javascript?
At a glance, it seems to be a good way to modularize the project I'm currently working on, which consists of a large Javascript code-base, with lots of components, some of which interact with eachother.
CommonJS is definitely suitable for the browser, with some caveats. The CommonJS module pattern is quite nice (in my biased opinion), and is also a good stepping stone to the module system proposed for ECMAScript Harmony (the planned next release of the JavaScript language). Specifically, Harmony modules won't have access to the global ("window") object.
The reason that some people claim CommonJS modules are not suitable for the browser is that they can't be loaded via a <script> tag without some server-side assistance. For example, imagine you have a markdown library that exports a "convertToHTML" function. You could then make a module that looks like this:
var convertToHTML = require("markdown").convertToHTML;
exports.mangleSomeText = function() {
// do something then call convertToHTML
}
This doesn't work via a script tag for a few reasons (the scope isn't wrapped, so convertToHTML would get attached to window, require wouldn't typically be defined and exports needs to be created separately for each module).
A client side library with a tiny bit of server side help could allow this to load via script tags easily. Or, a client side library that loads the script via XMLHttpRequest and does an eval() would also work, though the debugging experience is often not as good.
A fairly reasonable solution right now, though one that is also the subject of contentious debate among CommonJS members, is RequireJS. Using RequireJS, you can write your module like this:
define(function(require, exports, module) {
var convertToHTML = require("markdown").convertToHTML;
exports.mangleSomeText = function() {
// do something then call convertToHTML
}
});
All we did was add that define() bit around the module. (You could likely make a server do that pretty easily as well, so that you don't even need to manually type the define part).
I've personally used RequireJS on a couple of projects now and find it an easy way to make use of CommonJS modules without a server-side bit. There are many other solutions and if you aren't reliant on running static JS files, standard CommonJS modules are a great way to go.
(ObDisclaimer: I started the CommonJS project, so I am clearly biased.)