How do I include a JavaScript file inside another JavaScript file, similar to @import in CSS?
How do I include a JavaScript file inside another JavaScript file, similar to @import in CSS?
The old versions of JavaScript had no import, include, or require, so many different approaches to this problem have been developed.
But since 2015 (ES6), JavaScript has had the ES6 modules standard to import modules in Node.js, which is also supported by most modern browsers.
For compatibility with older browsers, build tools like Webpack and Rollup and/or transpilation tools like Babel can be used.
ECMAScript (ES6) modules have been supported in Node.js since v8.5, with the --experimental-modules flag, and since at least Node.js v13.8.0 without the flag. To enable "ESM" (vs. Node.js's previous CommonJS-style module system ["CJS"]) you either use "type": "module" in package.json or give the files the extension .mjs. (Similarly, modules written with Node.js's previous CJS module can be named .cjs if your default is ESM.)
Using package.json:
{
"type": "module"
}
Then module.js:
export function hello() {
return "Hello";
}
Then main.js:
import { hello } from './module.js';
let val = hello(); // val is "Hello";
Using .mjs, you'd have module.mjs:
export function hello() {
return "Hello";
}
Then main.mjs:
import { hello } from './module.mjs';
let val = hello(); // val is "Hello";
Browsers have had support for loading ECMAScript modules directly (no tools like Webpack required) since Safari 10.1, Chrome 61, Firefox 60, and Edge 16. Check the current support at caniuse. There is no need to use Node.js' .mjs extension; browsers completely ignore file extensions on modules/scripts.
<script type="module">
import { hello } from './hello.mjs'; // Or the extension could be just `.js`
hello('world');
</script>
// hello.mjs -- or the extension could be just `.js`
export function hello(text) {
const div = document.createElement('div');
div.textContent = `Hello ${text}`;
document.body.appendChild(div);
}
Read more at https://jakearchibald.com/2017/es-modules-in-browsers/
Dynamic imports let the script load other scripts as needed:
<script type="module">
import('hello.mjs').then(module => {
module.hello('world');
});
</script>
Read more at https://developers.google.com/web/updates/2017/11/dynamic-import
The older CJS module style, still widely used in Node.js, is the module.exports/require system.
// mymodule.js
module.exports = {
hello: function() {
return "Hello";
}
}
// server.js
const myModule = require('./mymodule');
let val = myModule.hello(); // val is "Hello"
There are other ways for JavaScript to include external JavaScript contents in browsers that do not require preprocessing.
You could load an additional script with an AJAX call and then use eval to run it. This is the most straightforward way, but it is limited to your domain because of the JavaScript sandbox security model. Using eval also opens the door to bugs, hacks and security issues.
Like Dynamic Imports you can load one or many scripts with a fetch call using promises to control order of execution for script dependencies using the Fetch Inject library:
fetchInject([
'https://cdn.jsdelivr.net/momentjs/2.17.1/moment.min.js'
]).then(() => {
console.log(`Finish in less than ${moment().endOf('year').fromNow(true)}`)
})
The jQuery library provides loading functionality in one line:
$.getScript("my_lovely_script.js", function() {
alert("Script loaded but not necessarily executed.");
});
You could add a script tag with the script URL into the HTML. To avoid the overhead of jQuery, this is an ideal solution.
The script can even reside on a different server. Furthermore, the browser evaluates the code. The <script> tag can be injected into either the web page <head>, or inserted just before the closing </body> tag.
Here is an example of how this could work:
function dynamicallyLoadScript(url) {
var script = document.createElement("script"); // create a script DOM node
script.src = url; // set its src to the provided URL
document.head.appendChild(script); // add it to the end of the head section of the page (could change 'head' to 'body' to add it to the end of the body section instead)
}
This function will add a new <script> tag to the end of the head section of the page, where the src attribute is set to the URL which is given to the function as the first parameter.
Both of these solutions are discussed and illustrated in JavaScript Madness: Dynamic Script Loading.
Now, there is a big issue you must know about. Doing that implies that you remotely load the code. Modern web browsers will load the file and keep executing your current script because they load everything asynchronously to improve performance. (This applies to both the jQuery method and the manual dynamic script loading method.)
It means that if you use these tricks directly, you won't be able to use your newly loaded code the next line after you asked it to be loaded, because it will be still loading.
For example: my_lovely_script.js contains MySuperObject:
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
var s = new MySuperObject();
Error : MySuperObject is undefined
Then you reload the page hitting F5. And it works! Confusing...
So what to do about it ?
Well, you can use the hack the author suggests in the link I gave you. In summary, for people in a hurry, he uses an event to run a callback function when the script is loaded. So you can put all the code using the remote library in the callback function. For example:
function loadScript(url, callback)
{
// Adding the script tag to the head as suggested before
var head = document.head;
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// Then bind the event to the callback function.
// There are several events for cross browser compatibility.
script.onreadystatechange = callback;
script.onload = callback;
// Fire the loading
head.appendChild(script);
}
Then you write the code you want to use AFTER the script is loaded in a lambda function:
var myPrettyCode = function() {
// Here, do whatever you want
};
Then you run all that:
loadScript("my_lovely_script.js", myPrettyCode);
Note that the script may execute after the DOM has loaded, or before, depending on the browser and whether you included the line script.async = false;. There's a great article on Javascript loading in general which discusses this.
As mentioned at the top of this answer, many developers use build/transpilation tool(s) like Parcel, Webpack, or Babel in their projects, allowing them to use upcoming JavaScript syntax, provide backward compatibility for older browsers, combine files, minify, perform code splitting etc.
It is possible to dynamically generate a JavaScript tag and append it to HTML document from inside other JavaScript code. This will load targeted JavaScript file.
function includeJs(jsFilePath) {
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
}
includeJs("/path/to/some/file.js");
Maybe you can use this function that I found on this page How do I include a JavaScript file in a JavaScript file?:
function include(filename)
{
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.src = filename;
script.type = 'text/javascript';
head.appendChild(script)
}
I just wrote this JavaScript code (using Prototype for DOM manipulation):
var require = (function() {
var _required = {};
return (function(url, callback) {
if (typeof url == 'object') {
// We've (hopefully) got an array: time to chain!
if (url.length > 1) {
// Load the nth file as soon as everything up to the
// n-1th one is done.
require(url.slice(0, url.length - 1), function() {
require(url[url.length - 1], callback);
});
} else if (url.length == 1) {
require(url[0], callback);
}
return;
}
if (typeof _required[url] == 'undefined') {
// Haven't loaded this URL yet; gogogo!
_required[url] = [];
var script = new Element('script', {
src: url,
type: 'text/javascript'
});
script.observe('load', function() {
console.log("script " + url + " loaded.");
_required[url].each(function(cb) {
cb.call(); // TODO: does this execute in the right context?
});
_required[url] = true;
});
$$('head')[0].insert(script);
} else if (typeof _required[url] == 'boolean') {
// We already loaded the thing, so go ahead.
if (callback) {
callback.call();
}
return;
}
if (callback) {
_required[url].push(callback);
}
});
})();
Usage:
<script src="prototype.js"></script>
<script src="require.js"></script>
<script>
require(['foo.js','bar.js'], function () {
/* Use foo.js and bar.js here */
});
</script>
If you want it in pure JavaScript, you can use document.write.
document.write('<script src="myscript.js" type="text/javascript"></script>');
If you use the jQuery library, you can use the $.getScript method.
$.getScript("another_script.js");
You can also assemble your scripts using PHP:
File main.js.php:
<?php
header('Content-type:text/javascript; charset=utf-8');
include_once("foo.js.php");
include_once("bar.js.php");
?>
// Main JavaScript code goes here
Yes, use type="module" in a script tag (support):
<script type="module" src="script.js"></script>
And in a script.js file include another file like this:
import { hello } from './module.js';
...
// alert(hello());
In 'module.js' you must export the function/class that you will import:
export function hello() {
return "Hello World";
}
A working example is here.
There are several ways to implement modules in JavaScript. Here are the two most popular ones:
Browsers do not support this moduling system yet, so in order for you to use this syntax you must use a bundler like Webpack. Using a bundler is better anyway because this can combine all of your different files into a single (or a couple of related) files. This will serve the files from the server to the client faster because each HTTP request has some associated overhead accompanied with it. Thus by reducing the overall HTTP request we improve the performance. Here is an example of ES6 modules:
// main.js file
export function add (a, b) {
return a + b;
}
export default function multiply (a, b) {
return a * b;
}
// test.js file
import {add}, multiply from './main'; // For named exports between curly braces {export1, export2}
// For default exports without {}
console.log(multiply(2, 2)); // logs 4
console.log(add(1, 2)); // logs 3
This moduling system is used in Node.js. You basically add your exports to an object which is called module.exports. You then can access this object via a require('modulePath'). Important here is to realize that these modules are being cached, so if you require() a certain module twice it will return the already created module.
// main.js file
function add (a, b) {
return a + b;
}
module.exports = add; // Here we add our 'add' function to the exports object
// test.js file
const add = require('./main');
console.log(add(1,2)); // logs 3
Yes, there is...
Keep reading. In ES6, we can export and import part or whole JavaScript file into another one...
But wait, ES6 is not supported in all the browsers, so you need to transpile it using babel.js for example...
So you create a class like below:
class Person {
constructor(name) {
this.name = name;
}
build() {
return new Person(this);
}
}
module.exports = Person;
In another JavaScript file, do the import like:
import { Person } from 'Person';
You also can require the file like:
const Person = require('./Person');
If you are using an older JavaScript version you can use requirejs:
requirejs(["helper/util"], function(util) {
// This function is called when scripts/helper/util.js is loaded.
// If util.js calls define(), then this function is not fired until
// util's dependencies have loaded, and the util argument will hold
// the module value for "helper/util".
});
If you want to stick to older version of stuff, like jQuery, you can also use something like getScript:
jQuery.getScript('./another-script.js', function() {
// Call back after another-script loaded
});
Last, but not the least, don't forget you can do the traditional way of putting a script together using the <script> tag...
<script src="./first-script.js"></script>
<script src="./second-script.js"></script>
<script src="./third-script.js"></script>
There are also the async and defer attributes which I should mention here...
Note: There are several ways an external script can be executed:
- If async is present: The script is executed asynchronously with the rest of the page (the script will be executed while the page continues the parsing)
- If async is not present and defer is present: The script is executed when the page has finished parsing
- If neither async or defer is present: The script is fetched and executed immediately, before the browser continues parsing the page
There is also Head.js. It is very easy to deal with:
head.load("js/jquery.min.js",
"js/jquery.someplugin.js",
"js/jquery.someplugin.css", function() {
alert("Everything is ok!");
});
As you see, it's easier than Require.js and as convenient as jQuery's $.getScript method. It also has some advanced features, like conditional loading, feature detection and much more.
For Node.js only, this worked for me the best!
I've tried most solutions here, but none helped me about just being able to load another file without changing scope. Finally I used this. Which preserves the scope and everything. It is as good as your code is in that point.
const fs = require('fs');
eval(fs.readFileSync('file.js') + '');
Here is a Grunt plugin allowing you to use @import "path/to/file.js"; syntax in any file including JavaScript files. It can be paired with uglify or watch or any other plugin.
It can be installed with npm install: https://npmjs.org/package/grunt-import
In a past project I had quite a bit of success using ajile to do imports of reusable JavaScript files. I always wished there was a feature for this built into JavaScript itself.
In Node.js you can do that just like the following code shows!
sub.js
module.exports = {
log: function(string) {
if(console) console.log(string);
}
mylog: function(){
console.log('just for log test!');
}
}
main.js
const mylog = require('./sub');
mylog.log('Hurray, it works! :)');
mylog.mylog();
Name files with .mjs extension instead of .js
touch main.mjs lib.mjs
import { add } from './lib.mjs';
console.log(add(40, 2));
export let add = (x,y) => {
return x + y
}
node --experimental-modules main.js
I tried this problem with another approach,
Ordering of script importing, has no effect in here.
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Trials</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="main.js"></script>
<script src="scriptA.js"></script>
</head>
<body>
<h3>testing js in js (check console logs)</h3>
<button onclick="fnClick()">TEST</button>
</body>
</html>
main.js
function fnClick() {
console.log('From\tAAAAA');
var pro = myExpo.hello();
console.log(pro);
}
scriptA.js
myExpo = {
hello: function () {
console.log('From\tBBBBB');
return "Hello";
}
}
and the result is
From AAAAA
From BBBBB
Hello
The above function works fine if you are loading only one script or you don't care about the loading order of multiple scripts. If you have some scripts that depends on others, you need to use Promise to specify the order of loading. The reason behind this is Javascript loads resources like scripts and images asynchronously. The loading sequence does not depends on the sequence of asynchronous calls, meaning script1 will not be guaranteed to load before script2 even if you call dynamicallyLoadScript("scrip1") before calling dynamicallyLoadScript("scrip2")
So here's another version of dynamicallyLoadScript that guarantees loading order:
// Based on: https://javascript.info/promise-basics#example-loadscript
function dynamicallyLoadScript(url) {
return new Promise(function(resolve, reject) {
var script = document.createElement("script");
script.src = url;
script.onload = resolve;
script.onerror = () => reject(new Error(`Error when loading ${url}!`));
document.body.appendChild(script);
});
}
For more on Promises, see this excellent page.
The usage of this new dynamicallyLoadScript is very simple:
dynamicallyLoadScript("script1.js")
.then(() => dynamicallyLoadScript("script2.js"))
.then(() => dynamicallyLoadScript("script3.js"))
.then(() => dynamicallyLoadScript("script4.js"))
.then(() => dynamicallyLoadScript("script5.js"))
//...
Now the scripts are loaded in the order of script1.js, script2.js, script3.js, etc.
In addition, you can immediately run code that uses the scripts after they are loaded. Just add another .then after the loading the script:
dynamicallyLoadScript("script1.js")
.then(() => dynamicallyLoadScript("script2.js"))
.then(() => foo()) // foo can be a function defined in either script1, script2
.then(() => dynamicallyLoadScript("script3.js"))
.then(() => {
if (var1){ // var1 can be a global variable defined in either script1, script2, or script3
bar(var1); // bar can be a function defined in either script1, script2, or script3
} else {
foo(var1);
}
})
//more .then chains...
To display unhandled promise rejections (errors loading scripts, etc), put this unhandledrejection event listener at the top of your code:
// Based on: https://javascript.info/promise-error-handling#unhandled-rejections
window.addEventListener('unhandledrejection', function(event) {
// the event object has two special properties:
console.error(event.promise);// the promise that generated the error
console.error(event.reason); // the unhandled error object
});
Now you will be notified of any script loading errors.
If you are loading a lot of scripts without executing code immediately after loading, this shorthand function may come in handy:
function dynamicallyLoadScripts(urls) {
if (urls.length === 0)
return;
let promise = dynamicallyLoadScript(urls[0]);
urls.slice(1).forEach(url => {
promise = promise.then(() => dynamicallyLoadScript(url));
});
}
To use it, just pass in an array of script urls like this:
const scriptURLs = ["dist/script1.js", "dist/script2.js", "dist/script3.js"];
dynamicallyLoadScripts(scriptURLs);
The scripts will be loaded in the order they appear in the array.
Please note that we usually use static scripts. So we want to be taken from the cache as much as possible.
This saves network traffic and speeds up landing.
Usage
$.cachedScript( "ajax/test.js" ).done(function( script, textStatus ) {
console.log( textStatus );
});
The cache: true option has been added to the Ajax method.
If you find there are two or more scripts occupying the same function when they are called, and we cannot be include them at the same time, we need to do it dynamically by user selection.
Including another file in jQuery using $.getScript works since the script will not be cached by default. So we are safe to call other scripts. The calls can be arranged like this:
HTML
<select class="choice">
<option value="script1" selected>Script-1</option>
<option value="script2">Script-2</option>
</select>
JavaScript
$(".choice").change(on_change);
var url = "https://example.com";
$.url1 = url + "/script1.js";
$.url2 = url + "/script2.js";
function on_change() {
if ($(".choice").val()=="script1") {
script1();
} else {
script2();
}
}
// script1
function script1() {
$.getScript($.url1, function( data, textStatus, jqxhr ) {
// Execute here
});
}
// script2
function script2() {
$.getScript($.url2, function( data, textStatus, jqxhr ) {
// Execute here
});
}
A little extension to the library from Dan Dascalescu's answer taken from the Facebook idea.
(function() {
var __ = {};
this._ = function(name, callback) {
if(__[name]==undefined) {
__[name] = true;
var firstScript = document.getElementsByTagName('script')[0],
js = document.createElement('script');
js.src = name;
js.onload = callback;
firstScript.parentNode.insertBefore(js, firstScript);
}
}
})();
(new _('https://cdnjs.cloudflare.com/ajax/libs/Snowstorm/20131208/snowstorm-min.js', function() {
snowStorm.snowColor = '#99ccff';
}));
var xxx = require("../lib/your-library.js")
or
import xxx from "../lib/your-library.js" //get default export
import {specificPart} from '../lib/your-library.js' //get named export
import * as _name from '../lib/your-library.js' //get full export to alias _name
You can use my loadScript ES module for loading of the JavaScript files.
In your head tag, include the following code:
<script src="https://raw.githack.com/anhr/loadScriptNodeJS/master/build/loadScript.js"></script>
or
<script src="https://raw.githack.com/anhr/loadScriptNodeJS/master/build/loadScript.min.js"></script>
Now you can use window.loadScript for loading of your JavaScript files.
Asynchronous load JavaScript file.
src: URL of an external script file or array of the script file names.
options: the following options are available
onload: function () The onload event occurs when a script has been loaded. Default is undefined.
onerror: function ( str, e ) The onerror event occurs when an error has been occurred. The default is undefined.
str: error details
e: event
appendTo: The node to which the new script will be append. The default is the head node.
For example
loadScript.async( "JavaScript.js",
{
onload: function () {
var str = 'file has been loaded successfully';
console.log( str );
},
onerror: function ( str, e ) {
console.error( str );
},
} );
So this is a edge case. But if you need to load the JavaScript from a remote source, most modern browsers might block your cross-site requests due to CORS or something similar. So normal
<script src="https://another-domain.com/example.js"></script>
Won't work. And doing the document.createElement('script').src = '...' won't cut it either. Instead, what you could do is load the JavaScript code as a resource via standard GET request, and do this:
<script type="text/javascript">
var script = document.createElement('script');
script.type = 'text/javascript';
let xhr = new XMLHttpRequest();
xhr.open("GET", 'https://raw.githubusercontent.com/Torxed/slimWebSocket/master/slimWebSocket.js', true);
xhr.onreadystatechange = function() {
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
script.innerHTML = this.responseText; // <-- This one
document.head.appendChild(script);
}
}
xhr.send();
</script>
By grabbing the content yourself, the browser won't notice malicious intents and allow you go do the request. Then you add it in <script>'s innerHTML instead. This still causes the browser (at least tested in Chrome) to parse/execute the script.
Again, this is a edge case use case. And you'll have no backwards compatibility or browser compliance probably. But fun/useful thing to know about.
My general solution taken from the efekt.js.st library from EdgeS (which I authored).
shameless plug alert - I am on other stackexchange network sites. This is a relink of
https://codereview.stackexchange.com/questions/263764/dynamic-load-css-or-script.
What code or design would you use to support dynamic-loading of css and scripts?
Requirements
head, body, or current script-elementcss, js, mjs modules or other script-typesnonce, crossorigin, etcstatic loadScriptOrStyle(url, options) {
// provenance :<# **Smallscript EdgeS efekt** `efekt.js.st` github libraries #>
// returns :<Promise#onload;onerror>
// options :<# `fIgnoreCache`, `fAppendToHead`, `fUrlIsStyle`, `attrs:{}` #>
const head = document.head; let node = options?.fAppendToBody ? document.body : head;
const url_loader_cache = document.head.url_loader_cache
? head.url_loader_cache
: (head.url_loader_cache = {script:{},link:{}})
const kind = (options?.fUrlIsStyle || /\.css(?:(?:\?|#).*)?$/i.test(url))
? 'link' : 'script';
// check already-loaded cache
if(url_loader_cache[kind][url]) {
const el = url_loader_cache[kind][url];
// support `fIgnoreCache` reload-option; should not use on `head`
if(options?.fIgnoreCache)
el.remove();
else
return(new CustomEvent('cache',{detail:el}));
}
// (re)create and record it
const self = document.currentScript;
const el = url_loader_cache[kind][url] = document.createElement(kind);
const append = (!self || options?.fAppendToHead || options?.fAppendToBody)
? el => node.appendChild(el)
: el => self.parentNode.insertBefore(el, self);
const load = new Promise((resolve, reject) => {
el.onload = e => {e.detail = el;resolve(e)};
el.onerror = e => {e.detail = el;reject(e)};
// `onload` or `onerror` possibly alter `cache` value
// throw(new URIError(`The ${url} didn't load correctly.`))
});
// configure `module` attr, as appropriate
if(/\.mjs(?:(?:\?|#).*)?$/i.test(url))
el.type = 'module'
// configure other attrs as appropriate (referrer, nonce, etc)
for(const key in options?.attrs) {el[key] = attrs[key]}
// trigger it
if(kind === 'link') el.rel = 'stylesheet', el.href = url; else el.src = url;
append(el);
return(load);
}
So if you want it quick, and easy... Try this:
function include(filename)
{
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.src = filename;
script.type = 'text/javascript';
head.appendChild(script)
}
It’s this simple:
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
I did not see an answer whereby you create an object of all functions and variables in a file and then make that object an argument to refer to it in another file.
E.g., you have files called 'jsMod.js', 'jsView' and 'jsContr.js':
JSMODOBJ = {};
JSMODOBJ.valueAddition = function(/* element value 1 */ val1, /* element value 2 */ val2) {
return val1 + val2;
}
JSVIEWOBJ = {};
JSVIEWOBJ.elementColour = function(/* element id to change colour */ id, /* css colour classname */ col) {
document.getElementById(id).className = col;
}
JSCONTROBJ = {};
var jsMod = JSMODOBJ;
var jsView = JSVIEWOBJ;
JSCONTROBJ.changeColourByValue = function (val1, val2, id, clss) {
if (jsMod.valueAddition(val1,val2) !== 0) {
jsView.elementColour(id, clss);
}
}
Then you can set the .js files dynamically by echoeing the scripts into your .html or .php file:
<?php
echo "<script src = './js/dleafView.js'></script>
<script src = './js/dleafModule.js'></script>
<script src = './js/dleafContr.js'></script>";
?>
Then just call the control function within a <script type="text/javascript"></script> tag. Of course, this will take a lot of time in the beginning to set up, but it saves you time in the long run.
I use this in a slightly different way, but this way also works.
You can also use gulp, gulp-concat, gulp-typescript with /// <reference path= includes:
{
"scripts": {
"gulp": "gulp main"
},
"dependencies": {
"@types/gulp": "^4.0.6",
"@types/gulp-concat",
"@types/gulp-typescript",
"gulp": "^4.0.2",
"gulp-concat": "^2.6.1",
"gulp-resolve-dependencies": "^3.0.1",
"gulp-typescript": "^6.0.0-alpha.1",
"typescript": "^3.7.3"
}
}
class SomeClass {
delay: number;
}
/// <reference path="./someimport.ts" />
someclass = new SomeClass();
someclass.delay = 1;
This main Gulp.js task (on gulpfile.js) targets only the src/main.js file, resolving all its /// <reference path=... include references. These includes are know as Triple-Slash Directives, and they are used only for transpilers tools to combine files. In our case, they are used explicitly by .pipe(resolveDependencies({ and by TypeScript itself when checking the file for missing types, variables, etc.
Refer to gulp-typescript if you would like to customize the var tsProject = ts.createProject call and not use a tsconfig.json file or override its parameters.
var gulp = require("gulp");
var concat = require('gulp-concat');
var resolveDependencies = require('gulp-resolve-dependencies');
var ts = require("gulp-typescript");
var tsProject = ts.createProject("tsconfig.json");
gulp.task("main", function() {
return gulp
.src(["src/main.ts"])
.pipe(resolveDependencies({
pattern: /^\s*\/\/\/\s*<\s*reference\s*path\s*=\s*(?:"|')([^'"\n]+)/gm
}))
.on('error', function(err) {
console.log(err.message);
})
.pipe(tsProject())
.pipe(concat('main.js'))
.pipe(gulp.dest("build/"));
});
If you would like to target all your TypeScript project files instead of only src/main.ts, you can replace this:
return gulp
.src(["src/main.ts"])
.pipe(resolveDependencies({
...
// -->
return tsProject
.src()
.pipe(resolveDependencies({
...
If you do not want to use TypeScript, you can use this simplified gulpfile.js and remove all TypeScript includes from package.json:
var gulp = require("gulp");
var concat = require('gulp-concat');
var resolveDependencies = require('gulp-resolve-dependencies');
gulp.task("main", function() {
return gulp
.src(["src/main.js"])
.pipe(resolveDependencies({
pattern: /^\s*\/\/\/\s*<\s*reference\s*path\s*=\s*(?:"|')([^'"\n]+)/gm
}))
.on('error', function(err) {
console.log(err.message);
})
.pipe(concat('main.js'))
.pipe(gulp.dest("build/"));
});
{
"scripts": {
"gulp": "gulp main"
},
"dependencies": {
"gulp": "^4.0.2",
"gulp-concat": "^2.6.1",
"gulp-resolve-dependencies": "^3.0.1"
}
}
Then, after running the command npm run gulp, the file build/main.js is created with the following as its contents:
class SomeClass {
}
/// <reference path="./someimport.ts" />
someclass = new SomeClass();
someclass.delay = 1;
Which allows me to include it in the browser with the script tag, after serving the build directory files:
<html>
<head>
<script src="main.js"></script>
</head>
<body>
<script type="text/javascript">
console.log(someclass.delay);
</script>
</body>
</html>
Related questions:
On the back-end, you can use CommonJS modules. For example:
//a.js
function func () {
var result = "OK Bro";
return result;
}
module.exports = { func };
//b.js
var a = require('./a.js');
console.log(a.func);
You can just use the require(); tag.
For example, if I had a addition.js module that I wanted to add to math.js, I would do this:
//this is math.js
//vars
let a = 1;
let b = 3;
//start of code
const additionfile = require('addition.js');
window.alert("You added " + a + " and " + b + " together, to get " + additionfile.add(a,b) + "!");
if you wanted the addition.js file, it would look something like this
function add(a,b) {
const sum = a + b;
return sum;
}
This is the easiest solution. Use a bundler like Vite.js and then simply do:
import "./path/to/js/file";
That's it! The OP has asked for something like "@import in CSS" and this is exactly like that. It is also not as rocket science complex as some of the old methods. It is at least undoubtedly the most beginner-friendly method, but I'm sure non-beginners do like it as well.
To get started with Vite for a vanilla JavaScript project, just have Node.js and [NPM3 installed, and then do:
npm create vite@latest <your-vanilla-js-app-name> --template vanilla
E.g.:
npm create vite@latest my-js-app --template vanilla
Now add imports like mentioned at the beginning of this answer and call it a day.
Just as a side note: Also another thing that might pop into your mind is namespacing issues, e.g., what if a name you have used in a file you're including is similar to a name you already have in your current file? But that's the nature of JavaScript, right? It's not an issue specific to this method.
So you'll need to devise strategies for handling that separately. There's a comprehensive article on Addy Osmani's blog in case you want to learn more about that: Design Patterns for Handling the Global Namespace in JavaScript.