Overview
As the amount of JavaScript code increases, it becomes standard practice to separate and manage it as external files (.js) rather than writing it inside the HTML. This article explains how to load external files using the src attribute of the <script> tag and covers various path specification patterns. We will focus on splitting files to improve maintainability and using the defer attribute to guarantee the correct execution order.
Specifications (Input/Output)
- Input: The browser parses the HTML and loads the .js files from the specified paths.
- Output:
- Scripts execute in the specified order.
- The execution order is printed to the console log.
- DOM manipulations from each file are reflected on the page.
Basic Usage
To load an external file, use the src attribute in a <script> tag to point to the file’s location. By adding the defer attribute, you can prevent the script from blocking HTML parsing while ensuring that scripts run in the order they are written in the code.
The following example shows a practical setup that combines local files, files on a server, and files from an external CDN.
Full Code (HTML / JavaScript)
HTML (index.html)
This file demonstrates three patterns: relative paths, root-relative paths, and absolute paths (URLs). Note that root-relative paths (starting with /) require a web server to function correctly.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>External Script Loading Demo</title>
<script src="./js/utils.js" defer></script>
<script src="/assets/js/core-config.js" defer></script>
<script src="https://api.example.com/sdk/v2/analytics.js" defer></script>
<script src="./js/main.js" defer></script>
</head>
<body>
<div id="app">
<h1>Please check the console</h1>
<p>The script loading status will be displayed here.</p>
</div>
</body>
</html>
JavaScript (./js/utils.js)
This is an example of a utility module loaded first to provide functions for subsequent scripts.
/**
* General Utility Module
* Loaded first to provide functions for later scripts.
*/
console.log('[1] utils.js: Load complete');
/**
* Function to format messages
* @param {string} msg - The message to display
* @returns {string} - Message with a timestamp
*/
const formatMessage = (msg) => {
const time = new Date().toLocaleTimeString();
return `[${time}] ${msg}`;
};
JavaScript (./js/main.js)
This is the main application logic loaded last to control the application.
/**
* Main Application Logic
* Uses functions defined in the previously loaded scripts.
*/
console.log('[4] main.js: Load complete');
// Use the function defined in utils.js
const welcomeMessage = formatMessage('Application started.');
console.log(welcomeMessage);
// DOM Manipulation
document.querySelector('#app p').textContent = welcomeMessage;
Customization Points
- Path Types:
./script.js: A file in the same directory as the HTML.../script.js: A file in the parent directory (one level up)./js/script.js: A file inside a “js” folder located at the site’s root.
- Execution Order: When using the
deferattribute, scripts run in the order they appear in the HTML (from top to bottom). If there is a dependency (e.g., jQuery library → jQuery plugin), always list the dependency first.
Important Points
- 404 Not Found Errors: If the file path is incorrect, the script will not load. Check the browser console for errors like
GET ... net::ERR_FILE_NOT_FOUND. Pay close attention to directory levels (e.g., the number of../). - Cross-Origin Resource Sharing (CORS): When loading scripts from another site using an absolute path, the request might be blocked depending on that server’s security settings.
- Caching Issues: Browsers cache JS files to improve performance. If changes you made do not appear, disable the cache in your developer tools or add a parameter to the filename (like
script.js?v=2) to force a reload.
Advanced Usage
Implementing Cache Busting
This technique ensures that users’ browsers load the latest version of a file after you update it.
<script src="./js/app.js?v=20260122" defer></script>
By writing the path this way, the browser recognizes it as a different resource from the previous version and requests the new file from the server instead of using the cache.
Summary
Moving JavaScript to external files improves code reusability and makes HTML easier to read. Understanding how to use different path types (relative, root, and absolute) and controlling the execution order with the defer attribute is the foundation of building stable web applications.
