Siirtyminen CommonJS:stä natiiveihin ES-moduuleihin
Muunna require/module.exports import/export-muotoon ja käsittele dual package- ja yhteentoimivuusongelmat.
Siirtyminen CommonJS:stä natiiveihin ES-moduuleihin on ilmainen Node.js-taustakehityksen bootcamp-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Node.js-taustakehityksen bootcamp-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Node.js-taustakehityksen bootcamp-kurssilla on yhteensä 4 oppituntia.
Kaksi moduulijärjestelmää, yksi suoritusympäristö
Node.js käytti perinteisesti CommonJS:ää (CJS): koodi ladataan komennolla require() ja asetetaan muiden käytettäväksi komennolla module.exports. Nykyaikaisessa JavaScriptissä on sisäänrakennettu standardi, ES Modules (ESM), jossa käytetään komentoja import ja export.
- CommonJS lataa moduulit ajonaikaisesti synkronisesti.
- ESM analysoidaan staattisesti, ladataan asynkronisesti ja se on virallinen ECMAScript-standardi.
Node tukee nykyään molempia, mutta niiden yhdistämiseen liittyy sääntöjä. Tässä oppitunnissa siirrätte taustapalveluprojektin CJS:stä siististi natiiviin ESM:ään.
// CommonJS (old)
const fs = require('fs');
module.exports = { readConfig };
// ES Modules (new)
import fs from 'fs';
export { readConfig };Kertokaa Nodelle, että tarkoitatte ESM:ää
Node päättää tiedostotunnisteen ja lähimmän package.json-tiedoston perusteella, miten tiedostoa käsitellään:
"type": "module"tiedostossapackage.json→.js-tiedostoja käsitellään ESM-tiedostoina.- Ei
type-kenttää (tai arvo"commonjs") →.js-tiedostot ovat CommonJS-tiedostoja. .mjson aina ESM ja.cjsaina CommonJStype-kentän arvosta riippumatta.
Siistein siirtovaihe on lisätä "type": "module" kerran ja korjata sitten tiedostot, joissa se aiheuttaa virheitä.
{
"name": "my-api",
"version": "1.0.0",
"type": "module",
"main": "src/server.js",
"scripts": {
"start": "node src/server.js"
}
}Vientien muuntaminen
Korvatkaa module.exports ja exports.foo export-lauseilla.
module.exports = X(yksi arvo) →export default X.exports.foo = ...(useita nimettyjä vientiarvoja) →export const foo = ...tai ryhmiteltyexport { foo, bar }.
Suosikaa apuohjelmissa nimettyjä vientiarvoja, jotta käyttäjät saavat automaattisen täydennyksen ja selkeämmät tuonnit.
// Before (CJS)
// module.exports.add = (a, b) => a + b;
// module.exports.PI = 3.14159;
// After (ESM)
export const add = (a, b) => a + b;
export const PI = 3.14159;
console.log(add(2, 3)); // 5
console.log(PI); // 3.14159Tuontien muuntaminen
Korvatkaa require() komennolla import. Vastatkaa vientityyliä:
- Nimetty:
const { add } = require('./math')→import { add } from './math.js'. - Oletusvienti:
const express = require('express')→import express from 'express'.
Tärkeä sääntö: ESM:ssä omien tiedostojen suhteellisiin tuonteihin on sisällytettävä tiedostotunniste (.js). Node ei päättele sitä puolestanne kuten CommonJS teki.
// Before (CJS)
// const { add } = require('./math');
// After (ESM) — note the explicit .js extension
import { add } from './math.js';
console.log(add(10, 5)); // 15Ei enää tunnisteita __dirname tai __filename
ESM ei tarjoa CommonJS:n yleisiä tunnisteita __dirname ja __filename. Jos taustapalvelunne muodostaa tiedostopolkuja (määritykset, lataukset, mallineet), ne on luotava uudelleen import.meta.url-arvon avulla.
Nykyaikainen Node (20.11+) tarjoaa myös tunnisteet import.meta.dirname ja import.meta.filename suoraan, mikä on jatkossa yksinkertaisin vaihtoehto.
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
// Classic portable approach
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const configPath = join(__dirname, 'config.json');
console.log(configPath);
// Node 20.11+ shortcut:
// const dir = import.meta.dirname;JSON-tiedostojen ja sisäänrakennettujen moduulien tuonti
Taustapalveluprojekteihin vaikuttaa vielä kaksi muutosta:
- JSON:
require('./data.json')ei enää toimi suoraan. Käyttäkää tuontiattribuuttia:import data from './data.json' with { type: 'json' }. - Ydinmoduulit: suosikaa
node:-etuliitettä (esimerkiksiimport { readFile } from 'node:fs/promises'). Se poistaa tulkinnanvaraisuuden ja kestää tulevat muutokset.
Jos kohdistatte koodin vanhempaan Node-versioon, JSON-tiedoston lukeminen fs-moduulin avulla välttää attribuuttisyntaksin yhteensopivuusongelmat kokonaan.
import { readFile } from 'node:fs/promises';
// Robust, version-agnostic way to load JSON in ESM
const raw = await readFile(new URL('./pkg.json', import.meta.url));
const pkg = JSON.parse(raw);
console.log(pkg.name);Tason ylimmän tason await on supervoima
Yksi aito ESM:n taustakoodille tuoma parannus on ylimmän tason await. CommonJS:ssä asynkroninen käynnistys piti kääriä IIFE-funktioon. ESM-moduulissa voitte käyttää await-komentoa suoraan ylimmällä tasolla.
Tämä tekee tietokantayhteyksistä, määritysten hakemisesta ja alustustoiminnoista huomattavasti selkeämpiä palvelimen käynnistystiedostoissa.
// ESM entry file
async function connectDb() {
await new Promise((r) => setTimeout(r, 50));
return { status: 'connected' };
}
const db = await connectDb(); // top-level await — no IIFE needed
console.log('DB:', db.status);Yhteentoimivuus: ESM tuo CommonJS:n
Tulette edelleen riippumaan vain CJS:ää tukevista npm-paketeista. Hyvä uutinen on, että ESM voi tuoda CommonJS:n. Node käärii paketin module.exports-arvon oletusvientiarvoksi.
- Käyttäkää
import pkg from 'cjs-lib'saadaksennemodule.exports-arvon. - Node yrittää tunnistaa myös nimetyt viennit, mutta monimutkainen CJS voi aiheuttaa tässä virheen — purkakaa arvot sen sijaan oletusviennistä.
// 'lodash' is CommonJS; the whole export object is the default
import _ from 'lodash';
const { chunk } = _; // safe: destructure from default
console.log(chunk([1, 2, 3, 4], 2)); // [[1,2],[3,4]]Yhteentoimivuus: CommonJS lataa ESM:n
Toinen suunta on vaikeampi. CommonJS-tiedosto ei voi ladata ESM-moduulia synkronisesti komennolla require() (vanhemmat Node-versiot aiheuttavat virheen ERR_REQUIRE_ESM). Vaihtoehdot:
- Käyttäkää dynaamista
import()-tuontia, joka palauttaa Promisen — se toimii CJS:n asynkronisten funktioiden sisällä. - Node 22+ lisäsi kokeellisen mahdollisuuden ladata ESM synkronisesti komennolla
require(), mutta älkää luottako siihen siirrettävässä koodissa.
Tämä epäsymmetria on tärkein syy siihen, että tiimit siirtävät koko koodikannan ESM:ään sen sijaan, että yhdistäisivät molempia.
// Inside a CommonJS file:
async function run() {
// dynamic import works even from CJS
const { add } = await import('./math.mjs');
console.log(add(4, 6)); // 10
}
run();Kaksoispakettien julkaiseminen
Jos julkaisette kirjaston, osa käyttäjistä käyttää ESM:ää ja osa CJS:ää. Nykyaikainen ratkaisu on exports-kenttä ja ehdolliset viennit, joiden avulla toimitetaan molemmat koontiversiot.
import-ehto → ESM-aloituskohta.require-ehto → CJS-aloituskohta.
Varokaa kaksoispakettivaaraa: jos molemmat koontiversiot ladataan, moduulin tilasta syntyy kaksi kopiota (esimerkiksi kaksi erillistä singleton-oliota). Pitäkää tilallinen logiikka yhdessä sisäisessä moduulissa, jonka molemmat koontiversiot tuovat.
{
"name": "my-lib",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.cjs",
"types": "./dist/index.d.ts"
}
}
}Käytännöllinen siirtotarkistuslista
Luotettava toimintajärjestys olemassa olevalle taustapalvelulle:
- Lisätkää
"type": "module"tiedostoonpackage.json. - Nimetkää kaikki CommonJS:ksi jäävät tiedostot uudelleen muotoon
.cjs. - Muuntaa
require/module.exportsmuotoonimport/export. - Lisätkää
.js-tunnisteet kaikkiin suhteellisiin tuonteihin. - Korvatkaa
__dirname/__filenameimport.meta-apuominaisuuksilla. - Korjatkaa JSON-tuonnit ja CJS-oletusviennin yhteentoimivuus.
- Suorittakaa testit; antakaa virheiden osoittaa jäljellä olevat
require-kutsut.
Työkalut, kuten cjstoesm tai codemodit, voivat automatisoida suurimman osan muokkauksista, mutta tarkistakaa muutokset aina.
Pikatarkistus
Muunneratte taustapalvelutiedoston ESM:ään ja lisäätte "type": "module"-asetuksen. Yhtäkkiä oman apuohjelman tuonti aiheuttaa virheen ERR_MODULE_NOT_FOUND. Mikä on todennäköisin korjaus?
Kertaus
Siirsitte Node.js-taustapalvelun CommonJS:stä natiiveihin ES-moduuleihin. Tärkeimmät asiat:
- Ottakaa ESM käyttöön asetuksella
"type": "module"; käyttäkää.cjs/.mjs-tunnisteita tiedostokohtaiseen ohitukseen. - Vaihtakaa
require/module.exportsmuotoonimport/exportja sisällyttäkää aina.js-tunniste suhteellisiin tuonteihin. - Luokaa
__dirnameuudelleenimport.meta.url-arvon avulla (tai käyttäkääimport.meta.dirname-tunnistetta). - ESM voi tuoda CJS:n oletusvientinä; CJS:n on käytettävä dynaamista
import()-tuontia ESM:ää varten. - Ylimmän tason
awaityksinkertaistaa asynkronista käynnistystä. - Käyttäkää kirjastoissa ehdollista
exports-määritystä ja varokaa kaksoispakettivaaraa.
Näiden sääntöjen avulla voitte nykyaikaistaa minkä tahansa Node-palvelun luottavaisesti standardin mukaisiksi ES-moduuleiksi.
Opi JavaScript tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 22
- Oppitunnit
- 92
Usein kysytyt kysymykset
Onko oppitunti ”Siirtyminen CommonJS:stä natiiveihin ES-moduuleihin” ilmainen?
Kyllä – oppitunnin ”Siirtyminen CommonJS:stä natiiveihin ES-moduuleihin” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Node.js-taustakehityksen bootcamp-kurssin, päivitä CoddyKit PROhon. Node.js-taustakehityksen bootcamp-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Siirtyminen CommonJS:stä natiiveihin ES-moduuleihin”?
Muunna require/module.exports import/export-muotoon ja käsittele dual package- ja yhteentoimivuusongelmat. Harjoittelet Node.js-taustakehityksen bootcamp-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Node.js-taustakehityksen bootcamp-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Node.js-taustakehityksen bootcamp-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.
Kuinka kauan ”Siirtyminen CommonJS:stä natiiveihin ES-moduuleihin”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Node.js-taustakehityksen bootcamp-oppitunnilla?
Kyllä. Jokainen Node.js-taustakehityksen bootcamp-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Siirtyminen CommonJS:stä natiiveihin ES-moduuleihin
- tsconfigin määrittäminen Node-taustaprojekteille
- Tyyppiturvallinen ympäristökonfiguraatio ja ajonaikainen validointi
- Nopea iterointi tsx:llä, hot reloadilla ja source map -tiedostoilla