This tutorial is a part of the Learn everything about Javascript in one course.
Why do we package and reuse code?
Anything you build, will depend on someone else's code. Why? Because it's fast, saves time, money. When joining a team, working on a project, you will build upon your team's code. Your teammate will also use your code for their work. That's why we need to know how to package and reuse code.
Reusable code is written in a file called module
with additional (simple) export syntax. When we reuse this code, we import the module with its name
and file path
. There are currently 2 ways that you can package and reuse code:
CommonJS | ES Modules | |
---|---|---|
Availability | Before ES6 | Since ES6 (2015) |
Node.js support | All versions | Node 13 and up (to use this feature, you need to add "type": "module" to your package.json file) |
Export syntax | module.exports = exportObject |
export exportObject1 export default exportObject2 |
Import syntax | const importedObj = require('/path/to/file.js) |
import importedObj from '/path/to/file' |
CommonJS and ES Modules import/export
should not be mixed.
Package (export) your code with CommonJS syntax
You can write your code as normal then export them by then end of the file using syntax: module.exports = exportObject
// Package (export) your code with CommonJS syntax
const getUser = async () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ name: 'Superman', superpower: 'fly'})
}, 1000);
})
}
module.exports = { // export syntax
API_KEY: '123-456',
getUser
}
Reuse (import) your code with CommonJS syntax
You can import your code (on the top of the file) with CommonJS syntax: const importedObj = require('/path/to/file.js)
// Reuse (import) your code with CommonJS syntax
const { API_KEY, getUser } = require('./export') // destructure while importing a module
const wholeModule = require('./export.js') // import whole module, ".js" part is optional
;(async () => { // a self-invoking async function
const user1 = await getUser()
const user2 = await wholeModule.getUser()
console.log('user1:', user1)
console.log('user2:', user2)
})()
console.log('API_KEY:', API_KEY)
console.log('API_KEY:', wholeModule.API_KEY)
// API_KEY: 123-456
// API_KEY: 123-456
// user1: { name: 'Superman', superpower: 'fly' }
// user2: { name: 'Superman', superpower: 'fly' }
Package (export) your code with ES Module syntax
You can write your code as normal then export them by then end of the file using syntax:
export default exportObject2
, the default object recieved when import.export exportObject1
, import needs to destructure to get thisexportObject1
.
// Package (export) your code with ES Module syntax
const getUser = async () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ name: 'Superman', superpower: 'fly'})
}, 1000);
})
}
export const API_KEY = '123-456' // import needs to destructure to get this constant
export default getUser // default object recieved when import
For Node version 13 & 14, "type": "module"
in package.json
file is required to be able to use ES Module export/import syntax.
{
"type": "module"
}
Reuse (import) your code with ES Module syntax
You can import your code (on the top of the file) with CommonJS syntax:
import importedObj from '/path/to/file'
for default exported object.import { objectName } from '/path/to/file'
for non-default exported object.import * as wholeObject from '/path/to/file'
for everything and renamed aswholeObject
.- We can use
as
to rename imported object.
// Reuse (import) your code with ES Module syntax
// ".js" is required for Node ES Module
import { API_KEY } from './export.js' // destructured import for non-default exported object
import { API_KEY as key } from './export.js' // destructured import and rename
import getUser from './export.js' // import default exported object
import * as wholeModule from './export.js' // import everything and rename as "wholeModule"
;(async () => {
const user1 = await getUser()
const user2 = await wholeModule.default()
console.log('user1:', user1)
console.log('user2:', user2)
console.log('wholeModule:', wholeModule)
})()
console.log('API_KEY:', API_KEY)
console.log('key:', key)
// API_KEY: 123-456
// key: 123-456
// user1: { name: 'Superman', superpower: 'fly' }
// user2: { name: 'Superman', superpower: 'fly' }
// wholeModule: [Module] { API_KEY: '123-456', default: [AsyncFunction: getUser] }
Summary
- Code packaging and reusing is a very important concept (but it's very simple to learn). You will see this in almost every project you work on.
- There are 2 ways to do code packaging and reusing:
CommonJS
andES Module
. - CommonJS and ES Modules
import/export
should not be mixed.