Skip to content

Transforms Node.js files from ES module to CommonJS, or vice versa.

License

Notifications You must be signed in to change notification settings

knightedcodemonkey/module

Repository files navigation

CI codecov NPM version

Node.js utility for transforming a JavaScript or TypeScript file from an ES module to CommonJS, or vice versa.

  • ES module ➡️ CommonJS
  • CommonJS ➡️ ES module

By default @knighted/module transforms the one-to-one differences between ES modules and CommonJS, but it also accepts options that allow:

  • Converting import/export to require/exports
  • Extensions to be updated in relative specifiers
  • Write transformed source code to a filename

Requirements

  • Node >= 20.11.0

Example

Given an ES module

file.js

import { argv } from 'node:process'
import { pathToFileURL } from 'node:url'
import { realpath } from 'node:fs/promises'

const detectCalledFromCli = async path => {
  const realPath = await realpath(path)

  if (import.meta.url === pathToFileURL(realPath).href) {
    console.log('invoked directly by node')
  }
}

detectCalledFromCli(argv[1])

You can transform it to the equivalent CommonJS module

import { transform } from '@knighted/module'

await transform('./file.js', {
  type: 'commonjs'
  moduleLoading: true,
  out: './file.cjs'
})

Which produces

file.cjs

const { argv } = require('node:process')
const { pathToFileURL } = require('node:url')
const { realpath } = require('node:fs/promises')

const detectCalledFromCli = async path => {
  const realPath = await realpath(path)

  if (require('node:url').pathToFileURL(__filename).toString() === pathToFileURL(realPath).href) {
    console.log('invoked directly by node')
  }
}

detectCalledFromCli(argv[1])

When executed from the CLI

use@computer: $ node file.cjs
invoked directly by node

Options

type ModuleOptions = {
  /* What module system to convert to. */
  type?: 'module' | 'commonjs'
  /* Whether import/export and require/exports should be transformed. */
  modules?: boolean
  /* Whether to change specifier extensions to the assigned value. If omitted they are left alone. */
  specifier?: '.js' | '.mjs' | '.cjs' | '.ts' | '.mts' | '.cts'
  /* What filepath to write the transformed source to. */
  out?: string
}

Roadmap

  • Support option modules.
  • Remove @knighted/specifier and avoid double parsing.

About

Transforms Node.js files from ES module to CommonJS, or vice versa.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published