Node.js & npm.

ESM modules

Agenda

  • ESM модули
  • CJS
  • CJS vs ESM

CJS

// a.js

class Parrot {
  say(){
    console.log('Im parrot!')
  }
}

module.exports = { Parrot: Parrot }

// index.js

const { Parrot } = require('./a.js')

const myParrot = new Parrot()
myParrot.say() // Im parrot!

CJS. взгяд node.js

(function(exports, require, module, __filename, __dirname) {
  class Parrot { }
  /** rest code */
}); 

CJS. import/export

  • Является обектом
  • "возвращает объект"

Осторожно, TS!

CJS невомвестим с ESM!

но при сборке можно конвертировать

CJS

ESM

Что такое

ESM модули

Модули ECMAScript — это официальный стандартный формат упаковки кода JavaScript для повторного использования. Модули определяются с использованием различных операторов import и export.

Что умеет ESM

  • динамическая загрузка других модулей(включая удаленные ресурсы)
  • понимает CJS
  • экспортировать переменные и функции
  • доступ к мета информации

Пример

// addTwo.mjs
function addTwo(num) {
  return num + 2;
}

export { addTwo };

// index.(mjs|js)
import {addTwo} from './addTwo.mjs'

addTwo(3) // 5

Как включить esm

добавить type:module в package.json

// package.json
{
  "name": "myPackage",
  "version": "1.0.0",
  "type": "module",
  "dependencies": {},
  "scripts": {}
  // rest
}

Динамический import

  • позволяет импортировать модули по условию
  • возвращают промис
// twoSum.mjs
export function twoSum(a){
  return a + 2
}

// index.mjs
async function main(){
  if(someCond){
    const module = await import('./twoSum.mjs')
    const res = module.twoSum(3) // 5
  }
}

import/export default

// car.mjs
class Car {}

export default Car;

// index.mjs
import Car from './car.mjs'
const honda = new Car()

Удаленные ресурсы

import 'data:text/javascript,console.log("hello!");';
import './02-fn.mjs?query=1#hash=123';
import 'file://full/real/path/to/your/file.mjs'

Мета информация

  • import.meta.dirname
    
  • import.meta.filename
  • import.meta.url
  • import.meta.resolve(<path>)

Доступно через import.meta

ESM <3 CJS

// car.cjs
class Car {}

module.exports = {Car}

// index.mjs
import carCJSModule from './car.cjs'

const audi = new carCJSModule.Car()

Ограниения при работе с cjs

  • Нельзя использовать глобальные объекты CommonJS, такие как __filename, __dirname (хотя их можно воссоздать с помощью import.meta.url).
  • Нельзя использовать require() для импорта модулей в ESM.

esm vs cjs

ESM CJS
синтаксис import/export require/exports
динамический + (возвращает промис) +- (уже является функцией)
default + +
стандартизирован да нет
совместим да нет, esm не поддерживается

References

09. ESM modules

By vitalic gorodkov

09. ESM modules

  • 114