Skip to content
Educora
Advanced16 min14 / 27

Modules and modern tooling

Split code into files with `import` and `export`, add packages with npm and meet the tools professionals use: Vite, ESLint, Prettier.

Check yourself
In this lesson you will learn
  • Write and import named and default exports
  • Explain what <script type="module"> gives you in the browser
  • Understand the role of npm, package.json and packages
  • Know what a bundler, a linter and a formatter are for

A real app has tens of thousands of lines of code. If you put it all in one file, finding anything, working as a team and fixing bugs becomes a nightmare. That is why code is split into small, logical pieces — modules — and ready-made solutions are added as packages. This is the last step from learning JavaScript to working with it professionally.

Modules: export and import

Definition
Module

A separate file with its own scope. Its variables and functions are invisible from outside — only what it explicitly shares with export can be taken into other files with import.

There are two kinds of exports. Named exports (export const, export function) can be as many as you like in a file and are imported in curly braces under the same name. A default export (export default) is only one per file and is imported without braces, under any name.

JavaScript
// math.js
export const PI = 3.14159;

export function circleArea(radius) {
  return PI * radius * radius;
}

export default function greet(name) {
  return `Hello, ${name}!`;
}
The file math.js shares two named exports and one default export.
JavaScript
// app.js
import greet, { circleArea, PI } from './math.js';
import * as math from './math.js';

console.log(greet('Aysel'));
console.log(circleArea(2).toFixed(2));
console.log(PI === math.PI);
Expected output
Hello, Aysel!
12.57
true
app.js takes what it needs. import * as math collects all named exports into one object.
ExportImportNote
export function circleAreaimport { circleArea } from './math.js'the name must match
export const PIimport { PI as pi } from './math.js'as renames it
export default function greetimport hello from './math.js'no braces, any name

Modules in the browser

We tell the browser that a file is a module with the type="module" attribute. In such a script import/export work, variables don't “pollute” the global scope, the code runs in strict mode and it starts after the page has been fully read. What's more, in a module you can write await outside any function, at the top level of the file:

HTML
<p id="status">Loading the menu...</p>

<script type="module">
  const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

  await wait(1500);

  const menu = ['plov', 'dolma', 'pakhlava'];
  document.querySelector('#status').textContent = `Menu: ${menu.join(', ')}`;
</script>
Preview
In a normal <script>, top-level await would be a syntax error — in a module it works.

npm and packages

Formatting dates, drawing charts, writing tests — for all of this there are ready-made packages written by other developers. npm (Node Package Manager) is the package manager installed together with Node.js. Information about the project, its dependencies and commands is kept in the package.json file, and downloaded packages go into the node_modules folder.

JSON
{
  "name": "weather-app",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "lint": "eslint ."
  },
  "dependencies": {
    "dayjs": "^1.11.10"
  },
  "devDependencies": {
    "vite": "^5.0.0",
    "eslint": "^9.0.0"
  }
}
dependencies are the packages the app needs to run, devDependencies are tools used only during development, and scripts are commands like npm run dev.
  1. 1
    Create a project

    In a terminal, type npm create vite@latest my-app and choose Vanilla and JavaScript as the template.

  2. 2
    Install the dependencies

    Go into the folder with cd my-app and run npm install.

  3. 3
    Add a package

    Type npm install dayjs, then use it in your code with import dayjs from 'dayjs';.

  4. 4
    Start the dev server

    Type npm run dev and open the address shown in the terminal (usually http://localhost:5173). The page updates itself as soon as you save a file.

Modern tools

Kind of toolWhat it doesExamples
Package managerdownloads and updates packagesnpm, pnpm, Yarn
Bundler and dev servercombines and compresses modules for the websiteVite, webpack, esbuild
Linterfinds bugs and bad habits without running the codeESLint
Formatterlays out code automatically in one consistent stylePrettier
Test runnerchecks automatically that the code works correctlyVitest, Jest
Exercise

The text of a package.json file is given as a string. Read it with JSON.parse and print: 1) name@version (weather-app@1.4.2), 2) each dependency on its own line as name version, 3) Dev tools: N — the number of packages in devDependencies.

Exercise · JavaScript
const text = '{"name": "weather-app", "version": "1.4.2", "dependencies": {"dayjs": "^1.11.10", "lodash": "^4.17.21"}, "devDependencies": {"vite": "^5.0.0", "eslint": "^9.0.0"}}';

// 1) parse the text and print name@version
// 2) print every dependency as: name version
// 3) print Dev tools: N
▸ Expected output
weather-app@1.4.2
dayjs ^1.11.10
lodash ^4.17.21
Dev tools: 2

Key points

  • A module is a file with its own scope; export shares things and import takes them.
  • Named exports are imported in { } with the same name; export default without braces, under any name.
  • <script type="module"> gives you import/export, its own scope, strict mode and top-level await.
  • npm installs packages; a project's dependencies and commands live in package.json.
  • Vite runs and builds the project, ESLint finds mistakes, Prettier formats the code.

Check yourself

10 questions. Every correct answer earns XP.

1 / 10
How do you share a function so that another file can use it?