How do I include or import a JavaScript file into another JavaScript file, similar to how @import works in CSS?
JavaScript can import files using several approaches depending on your environment and project requirements. The most modern method is ES6 modules with import/export statements, while Node.js traditionally uses CommonJS with require() and module.exports. For browser compatibility, module bundlers like webpack can transpile different module systems into browser-compatible code.
Contents
- ES6 Modules: The Modern Standard
- CommonJS: Traditional Node.js Approach
- Module Bundlers: webpack, esbuild, and Rollup
- Browser Compatibility and Setup
- Dynamic Imports and Loading
- Choosing the Right Module System
ES6 Modules: The Modern Standard
ES6 modules represent the official JavaScript standard for modular programming, providing a clean syntax for importing and exporting functionality between files. This approach is similar in concept to CSS @import but with much more powerful capabilities.
Basic Syntax
ES6 modules use import statements to bring in functionality from other modules:
// Import named exports
import { functionName, variableName } from './module.js';
// Import default export
import defaultExport from './module.js';
// Import both named and default exports
import defaultExport, { namedExport1, namedExport2 } from './module.js';
// Import all exports as an object
import * as ModuleName from './module.js';
Export Syntax
To make functions, variables, or classes available for import, you use export statements:
// Named exports
export const myVariable = 'value';
export function myFunction() { /* ... */ }
export class MyClass { /* ... */ }
// Default export (one per module)
export default function() { /* ... */ }
Key Features
- Static analysis: ES6 modules are analyzed before execution, enabling better optimization
- Live bindings: Imported variables remain connected to their original module
- Asynchronous loading: Modules can load asynchronously in browsers
- Tree shaking: Unused exports can be eliminated during bundling
The Mozilla Developer Network provides comprehensive documentation on ES6 module syntax and best practices.
CommonJS: Traditional Node.js Approach
CommonJS has been the standard module system in Node.js since its inception and remains the default in most Node.js environments. It uses a synchronous approach to module loading.
Basic Syntax
CommonJS uses the require() function to import modules:
// Import a module
const myModule = require('./module.js');
// Import specific exports
const { functionName, variableName } = require('./module.js');
Export Syntax
To export functionality, CommonJS uses module.exports or exports:
// Single export
module.exports = function() { /* ... */ };
// Multiple exports
module.exports.functionName = function() { /* ... */ };
module.exports.variableName = 'value';
// Alternative syntax
exports.functionName = function() { /* ... */ };
Key Features
- Synchronous loading: Modules are loaded synchronously, which works well in server environments
- Dynamic require:
require()can be called anywhere in the code, including conditionally - Immediate execution: Code runs immediately when required
- Widely adopted: Most npm packages use CommonJS by default
According to the research findings, CommonJS uses require('./file.js') syntax for importing other modules and module.exports for exporting functionality [source: Adam Coster’s blog].
Module Bundlers: webpack, esbuild, and Rollup
Module bundlers are tools that take your modular JavaScript code and bundle it into one or more files that can be loaded in browsers. They support multiple module systems and provide additional optimization features.
webpack
webpack is a powerful module bundler that can handle ES6 modules, CommonJS, and AMD:
// webpack configuration example
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
}
};
esbuild
esbuild is a fast JavaScript bundler that focuses on performance:
# Bundle CommonJS or ES6 modules
esbuild src/index.js --bundle --outfile=dist/bundle.js
Key Benefits of Bundlers
- Browser compatibility: Transpile modern JavaScript to older browsers
- Code splitting: Split bundles for better performance
- Minification: Reduce file size automatically
- Hot module replacement: Development-time updates without full refresh
The research confirms that “webpack is a module bundler” whose main purpose is to bundle JavaScript files for browser usage [source: webpack documentation].
Browser Compatibility and Setup
Native ES6 Module Support
Modern browsers support ES6 modules natively. To use them, you need to add type="module" to your script tags:
<script type="module" src="main.js"></script>
Key Browser Considerations
- Chrome: Full support since version 61
- Firefox: Full support since version 60
- Safari: Full support since version 11
- Edge: Full support since version 16
Fallback for Older Browsers
For browsers that don’t support ES6 modules, you can provide a fallback:
<script type="module" src="main.js"></script>
<script nomodule src="main-legacy.js"></script>
Transpilation with Babel
For broader browser support, use Babel to transpile ES6 modules to older JavaScript versions:
// .babelrc configuration
{
"presets": ["@babel/preset-env"]
}
Dynamic Imports and Loading
ES6 modules support dynamic imports using the import() function, which returns a promise:
// Dynamic import
import('./module.js')
.then(module => {
// Use the imported module
module.functionName();
})
.catch(error => {
console.error('Error loading module:', error);
});
// Using async/await
async function loadModule() {
try {
const module = await import('./module.js');
module.functionName();
} catch (error) {
console.error('Error loading module:', error);
}
}
Common Use Cases for Dynamic Imports
- Code splitting: Load modules only when needed
- Conditional loading: Import based on user actions or conditions
- Large libraries: Load heavy libraries on demand
The research shows that “to import ESM into CommonJS you’ll use the asynchronous import() function” [source: Adam Coster’s blog].
Choosing the Right Module System
When to Use ES6 Modules
- New projects: Start with ES6 modules for future compatibility
- Browser applications: Native support in modern browsers
- TypeScript projects: Built-in support and better tooling
- Static analysis needs: Better optimization and tree shaking
When to Use CommonJS
- Node.js projects: Especially if using older Node.js versions
- Existing codebases: When maintaining legacy projects
- npm packages: Most existing packages use CommonJS
- Synchronous requirements: When you need immediate module execution
Migration Considerations
- Node.js version: ES6 modules require Node.js 12.0.0 or later
- package.json: Add
"type": "module"to enable ES6 modules - File extensions: Use
.mjsfor ES6 modules or configure.jsfiles - Testing: Ensure all functionality works after migration
The research indicates that “ESModules and CommonJS are mutually exclusive” in many contexts, so careful planning is needed when choosing between systems [source: Stack Overflow].
Conclusion
JavaScript file imports can be accomplished through several approaches, each with its own advantages:
- ES6 modules provide the modern standard with clean syntax and better optimization, perfect for new projects and browser applications
- CommonJS remains essential for Node.js development and legacy codebases, offering synchronous loading and wide npm compatibility
- Module bundlers like webpack and esbridge provide solutions for complex projects requiring optimization and browser compatibility
For most new projects, starting with ES6 modules is recommended due to their future-proof nature and browser support. When working specifically with Node.js, consider the environment’s default module system and your project’s compatibility requirements. The choice ultimately depends on your specific needs, target environment, and existing codebase structure.
Sources
- JavaScript modules - JavaScript | MDN
- CommonJS (cjs) and Modules (esm): Import compatibility - Adam Coster
- Module Methods | webpack
- How to use an ES6 import in Node.js? - Tutorialspoint
- ES6 imports vs CommonJS imports in Javascript | Medium
- Modules: ECMAScript modules | Node.js Documentation
- CommonJS vs. ES modules in Node.js - LogRocket Blog
- How to use ES6 modules in CommonJS? - Stack Overflow