This article will detail the various methods for including a JavaScript file in another JavaScript file – providing several methods for use in the browser, and when working in Node.js.
One of the cornerstones of programming is reusable code. This concept is encapsulated in the DRY (Don’t Repeat Yourself) principle – that if you need to do something multiple times, you write the code for it once, and re-use it where it is required, rather than having multiple copies of the same code in your code base.
Functions are the most common way of separating repeating code out so that it can be re-used. Re-usable code can be wrapped in a function, and then called later in a file when it is required.
If you have a lot of code, however, this gets unruly. You may require tens or even hundreds of functions, and defining them all at the top of you JavaScript file will make it difficult to manage and debug.
JavaScript (and most other modern programming languages) allows you to separate these functions into separate files, and import them when they are needed, making managing your code base easier. Functions can be categorized by their purpose and kept in different files, only being imported when and where they are needed, keeping your code clean and efficient.
Here’s how to do it.
Including JavaScript in the Browser
There are several ways to include a JavaScript file when working in the web browser depending on where the file is located, the kind of file it is, and what you are trying to achieve.
Directly including a file in a web page
If you are looking to include a standard JavaScript file or load a JavaScript library from a CDN (for example, jQuery), and the library supports it, it may be easiest to just load it directly in your HTML:
<script src="path/to/script.js"></script>
JavaScript files loaded in this manner are executed as soon as they have been downloaded. Any functions or variables set in the file will be available globally within the browser window. You can load as many JavaScript files in a HTML document as you require.
Deferring Script Loading
To execute a script only AFTER the page has fully loaded, user the defer attribute:
<script src="path/to/script.js" defer></script>
This is useful if you are importing a library that relies on another library to be loaded first. For example, if you are loading a library that relies jQuery and are receiving errors as the jQuery library has not yet loaded, add the defer attribute to your script tag to make sure the script is executed after the page has been parsed.
Note that the defer attribute only works with external scripts, not inline scripts.
Defining ECMA/ES6 JavaScript Modules
JavaScript (officially known as ECMAScript) recently adopted a standardized system for importing JavaScript code as modules. This was introduced with the ECMAScript 2015, also known as the ES6 release. This system lets you split your code into multiple files containing modules that can then be imported into other JavaScript files (or other modules, if you want to break things up further).
Several of the below methods use ES6 Modules. We’ve already got an article covering how to create and use JavaScript modules – check it out here.
Example ES6 JavaScript Module
The below examples will refer to the following example module which we’ll store in a file called exampleLogger.js:
function logIt(logMe){ console.log(logMe) } // Export the above function for use in other scripts export { logIt };
This is a very simple module with a single function called logIt that will log anything passed to it to the console.
ES6 Module Import in the Browser
ES6 module importing works in all modern web browsers. Below, the example module defined above is imported using a HTML script tag:
<script type="module" src="./exampleLogger.js"></script> <script> logIt('Hello LinuxScrew!'); </script>
The exported functions and variables from the module are made available to the scripts running within the web page.
Individual functions can also be imported from a module if you don’t need to use all of it:
<script type="module"> import { logMe } from './exampleLogger.js'; logIt('Hello LinuxScrew!'); </script>
The logMe function is imported from the exampleLogger.js module, and then executed.
Note the use of the type attribute with the value module – this tells the browser that a module is loaded in that particular script.
ES6 Dynamic Import In the Browser
Modules can also be imported dynamically:
<script type="module"> import('exampleLogger.js').then(module => { module.logIt('Hello LinuxScrew!'); }); </script>
This lets you call functions from a module only after it has loaded, as an alternative to using the defer attribute.
Using Require.js
Require.js is a library for loading external JavaScript files designed for use in the browser. It’s well documented, and setup is simple. Once Require.js is loaded you can use it to load modules. This is useful when working with browsers that may not natively support ES6 modules.
requirejs(["./exampleLogger.js"], function(module) { //This function is called when the JavaScript file has loaded module.logIt('Hello LinuxScrew!'); });
Loading External JavaScript with jQuery
If you are using jQuery you can use the jQuery.getScript() method to load and execute a JavaScript file via HTTP:
$.getScript("path/to/script.js", function() { alert("Script loaded!"); });
Note that this method is not intended for use with ES6 modules but is for loading and running standard scripts.
Using fetch to download and execute scripts
Vanilla JavaScript can also download and execute scripts using the Fetch API:
This is perfect for loading JSON files:
fetch('.path/to/data.json') .then((response) => response.json()) .then((data) => console.log(data));
While this method can also be used to load scripts by fetching the script, loading the text and running it using eval(), it’s a really, really bad idea, so I’m not including an example of how to do it so you can’t copy and paste it and deploy it to your users. eval() is outright dangerous and should never be used.
Fetch Inject
The Fetch Inject library can be used to load JavaScript files asynchronously. This is an NPM package that must be installed using the NPM package manager.
This is particularly useful if you want to load scripts when a user performs an action, rather than loading all scripts on page load:
var myButton = document.getElementById('myButton'); myButton.onclick = (event) => { event.preventDefault(); fetchInject([ './path/to/script.js' ]); }
Using ES6 Modules Node.js
ES6 Modules can be created and included in Node.js as per our article here.
Node.js Require
The Node.js require() function is not part of standard JavaScript (so it’s not available in the browser), and is part of the Node.js runtime that allows you to run JavaScript outside of the browser.
The require() function loads a local JavaScript file (usually an ES6 module) and executes it in Node.js.
The result of require() can be assigned to a variable, so that the imported script is executed and the exported values are assigned to the variable as an object.
var example = require('./example.js')
require() can also be used without assigning the result to a variable to simply execute a script from within another.
Find out more about how the require() function can be used within Node.js here.
Checking that the import was successful
Here are some ways to check whether a script has imported successfully:
- Include a call to
console.log()
in the external script, so that you can check the console to see if it has loaded - If using a third party library, try making a call to one of the included functions
- Use a bundler like Webpack to bundle all of your scripts and dependencies into a single file so that you can be sure it has all loaded before it is executed
Trust No One
Don’t just go including code from anywhere. Loading external code from untrusted websites may work now, but the site owner could easily replace the code you are importing with something malicious. Many web browsers will even try to prevent you from importing or executing code through some of the above means if they risk making your users vulnerable.
Only import code you have written, or use trusted, vetted libraries with a good reputation. Just because a library is available on NPM or is hosted on popular CDNs doesn’t mean that it’s trustworthy!