Movatterモバイル変換


[0]ホーム

URL:


Skip to content
Search Gists
Sign in Sign up

Instantly share code, notes, and snippets.

@sindresorhus
Last activeOctober 31, 2025 00:11
    Save sindresorhus/a39789f98801d908bbc7ff3ecc99d99c to your computer and use it in GitHub Desktop.
    Pure ESM package

    The package that linked you here is now pureESM. It cannot berequire()'d from CommonJS.

    This means you have the following choices:

    1. Use ESM yourself.(preferred)
      Useimport foo from 'foo' instead ofconst foo = require('foo') to import the package. You also need to put"type": "module" in your package.json and more. Follow the below guide.
    2. If the package is used in an async context, you could useawait import(…) from CommonJS instead ofrequire(…).
    3. Stay on the existing version of the package until you can move to ESM.
    4. SinceNode.js 22, you may be able torequire() ESM modules. However, Istrongly recommend moving to ESM instead.

    You also need to make sure you're on the latest minor version of Node.js. At minimum Node.js 16.

    I would strongly recommend moving to ESM. ESM can still import CommonJS packages, but CommonJS packages cannot import ESM packages synchronously.

    My repos are not the place to ask ESM/TypeScript/Webpack/Jest/ts-node/CRA support questions.

    FAQ

    How can I move my CommonJS project to ESM?

    • Add"type": "module" to your package.json.
    • Replace"main": "index.js" with"exports": "./index.js" in your package.json.
    • Update the"engines" field in package.json to Node.js 18:"node": ">=18".
    • Remove'use strict'; from all JavaScript files.
    • Replace allrequire()/module.export withimport/export.
    • Use only full relative file paths for imports:import x from '.';import x from './index.js';.
    • If you have a TypeScript type definition (for example,index.d.ts), update it to use ESM imports/exports.
    • Use thenode: protocol for Node.js built-in imports.

    Sidenote: If you're looking for guidance on how to add types to your JavaScript package,check out my guide.

    Can I import ESM packages in my TypeScript project?

    Yes, but you need to convert your project to output ESM. See below.

    How can I make my TypeScript project output ESM?

    Read the official ESM guide.

    Quick steps:

    • Make sure you are using TypeScript 4.7 or later.
    • Add"type": "module" to your package.json.
    • Replace"main": "index.js" with"exports": "./index.js" in your package.json.
    • Update the"engines" field in package.json to Node.js 18:"node": ">=18".
    • Add"module": "node16", "moduleResolution": "node16" to your tsconfig.json.(Example)
      • moduleResolution must be set tonode16 ornodenext, NOTnode!
    • Use only full relative file paths for imports:import x from '.';import x from './index.js';.
    • Removenamespace usage and useexport instead.
    • Use thenode: protocol for Node.js built-in imports.
    • You must use a.js extension in relative imports even though you're importing.ts files.

    If you usets-node, followthis guide.Example config.

    How can I import ESM in Electron?

    Electron supports ESM as of Electron 28.Please read this.

    I'm having problems with ESM and Webpack

    The problem is either Webpack or your Webpack configuration. First, ensure you are on the latest version of Webpack. Please don't open an issue on my repo. Try asking on Stack Overflow oropen an issue the Webpack repo.

    I'm having problems with ESM and Next.js

    Upgrade toNext.js 12 which has full ESM support.

    I'm having problems with ESM and Jest

    Read this.

    I'm having problems with ESM and TypeScript

    If you have decided to make your project ESM ("type": "module" in your package.json), make sure you have"module": "node16" in your tsconfig.json and that all your import statements to local files use the.js extension,not.ts or no extension.

    I'm having problems with ESM andts-node

    I would recommendtsx instead.

    Followthis guide and ensure you are on the latest version ofts-node.

    Example config.

    I'm having problems with ESM and Create React App

    Create React App doesn't yet fully support ESM. I would recommend opening an issue on their repo with the problem you have encountered. One known issue is#10933.

    How can I use TypeScript with AVA for an ESM project?

    Followthis guide.

    How can I make sure I don't accidentally use CommonJS-specific conventions?

    We got you covered with thisESLint rule. You should also usethis rule.

    What do I use instead of__dirname and__filename?

    Node.js 20.11+

    Useimport.meta.dirname andimport.meta.filename.

    Older Node.js versions

    import{fileURLToPath}from'node:url';importpathfrom'node:path';const__filename=fileURLToPath(import.meta.url);const__dirname=path.dirname(fileURLToPath(import.meta.url));

    However, in most cases, this is better:

    import{fileURLToPath}from'node:url';constfoo=fileURLToPath(newURL('foo.js',import.meta.url));

    And many Node.js APIs accept URL directly, so you can just do this:

    constfoo=newURL('foo.js',import.meta.url);

    How can I import a module and bypass the cache for testing?

    There's no good way to do this yet. Not until we getESM loader hooks. For now, this snippet can be useful:

    constimportFresh=asyncmodulePath=>import(`${modulePath}?x=${Date.now()}`);constchalk=(awaitimportFresh('chalk')).default;

    Note: This will cause memory leaks, so only use it for testing, not in production. Also, it will only reload the imported module, not its dependencies.

    How can I import JSON?

    Node.js 18.20+

    importpackageJsonfrom'./package.json'with{type:'json'};

    Older Node.js versions

    importfsfrom'node:fs/promises';constpackageJson=JSON.parse(awaitfs.readFile('package.json'));

    When should I use a default export or named exports?

    My general rule is that if something exports a single main thing, it should be a default export.

    Keep in mind that you can combine a default export with named exports when it makes sense:

    importreadJson,{JSONError}from'read-json';

    Here, we had exported the main thingreadJson, but we also exported an error as a named export.

    Asynchronous and synchronous API

    If your package has both an asynchronous and synchronous main API, I would recommend using named exports:

    import{readJson,readJsonSync}from'read-json';

    This makes it clear to the reader that the package exports multiple main APIs. We also follow the Node.js convention of suffixing the synchronous API withSync.

    Readable named exports

    I have noticed a bad pattern of packages using overly generic names for named exports:

    import{parse}from'parse-json';

    This forces the consumer to either accept the ambiguous name (which might cause naming conflicts) or rename it:

    import{parseasparseJson}from'parse-json';

    Instead, make it easy for the user:

    import{parseJson}from'parse-json';

    Examples

    With ESM, I now prefer descriptive named exports more often than a namespace default export:

    CommonJS (before):

    constisStream=require('is-stream');isStream.writable();

    ESM (now):

    import{isWritableStream}from'is-stream';isWritableStream();

    Comments are disabled for this gist.


    [8]ページ先頭

    ©2009-2025 Movatter.jp