點燈坊

失くすものさえない今が強くなるチャンスよ

Node 使用 ES Module

Sam Xiao's Avatar 2021-10-24

ES Module 是 ECMAScript 2015 最重要發明,而從 Node 12 開始也正式支援 ES Module,甚至還可將 Import 語法用在原本 CommonJS Module。

Version

Node 14.18.1

Using .js

Node 12 允許我們一樣使用 .js,但必須搭配 package.json

helloWorld.js

export let helloWorld = _ => 'Hello World'

hello-world.js 使用 ES6 的 exporthelloWorld 匯出。

index.js

import { helloWorld } from "./helloWorld.js"

console.log (helloWorld())

index.js 使用 ES6 的 importhelloWorld 匯入。

package.json

{
  "type": "module",
  "name": "esm-import",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
}

若要 file extension 仍使用 .js,則要在 pckage.json 加入 "type": "module",如此 Node 將視 .js 為 ES module。

Using .mjs

若不想使用 package.json"type": "module",也可將 file extension 改成 .mjs

helloWorld.mjs

export let helloWorld = _ => 'Hello World'

helloWorld.js 改成 helloWorld.mjs

index.mjs

import { helloWorld } from "./helloWorld.mjs"

console.log (helloWorld ())

import 要改成 helloWorld.mjsindex.js 也要改成 index.mjs

也就是若不使用 package.json,則所有檔案都要改成 .mjs

Importing CommonJS Module

Node 12 之後也可使用 import 載入 CommonJS module。

helloWorld.txt

Hello World

希望使用 Node 的 fs.readFile 讀取 helloWorld.txt

require

index.js

let { readFile } = require("fs")

readFile ("hello-world.txt", (err, data) => {
  if (err) throw err
  console.log (data.toString ())
})

Node 12 之前會使用 require 載入 CommonJS module,可直接搭配 destructuring。

import

index.js

import { readFile } from 'fs'

readFile ("hello-world.txt", (err, data) => {
  if (err) throw err
  console.log (data.toString ())
})

從 Node 12 開始也可使用 import 載入 CommonJS module,也可直接在 import 使用 Object Destructuring。

package.json

{
  "type": "module",
  "name": "esm-import",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT"
}

因為 file extension 為 .js,所以依然要使用 package.json"type": "module"

Conclusion

  • 隨著 Node 支援 ES6+ 越來越完整,可漸漸不必使用 Babel 轉譯,直接使用原生 Node 即可
  • 由於 import 可支援 ES module 與 CommonJS module,因此 Node 可全面使用 import 語法;但若是開發 package,為了最大相容性仍建議使用 CommonJS module,若想使用 export 語法,可使用 Node + Babel 開發環境,由 Babel 轉成 CommonJS module

Reference

Valeri Karpov, What’s New in Node.js 12: ESM Imports
Node.js, ECMAScript Modules