Skip to content

Instantly share code, notes, and snippets.

@rauschma
Last active October 18, 2019 08:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rauschma/dc9ab74495f521a479bb4fbe11623651 to your computer and use it in GitHub Desktop.
Save rauschma/dc9ab74495f521a479bb4fbe11623651 to your computer and use it in GitHub Desktop.

What will future hybrid npm packages look like?

Status quo

It’s great to see how many npm packages already come with ESM versions. Most common seems to be:

"main": "src/main.js",
"module": "dist/mypkg.esm.js",

import {x} from 'mypkg'; // bundler uses "module" entry
const {x} = require('mypkg');

Files in package:

mypkg/
  src/
    main.js  # CommonJS
    util.js  # CommonJS
  dist/
    mypkg.esm.js  # bundled

Future (once ESM is unflagged in Node.js)?

"main": "src/main.mjs",

import {x} from 'mypkg';
const {x} = require('mypkg/cjs');

Files in package:

mypkg/
  src/
    main.mjs
    util.mjs
  cjs/
    index.cjs  # main
    util.cjs

Edits

  • Rewrite, based on suggestions by @mgtitimoli
@mgtitimoli
Copy link

I believe it would better to have a cjs folder under the package with a package.json with the "type": "commonjs" since all the files under this folder are gonna be of this type.

So at the end the user would be able to require it like: const mypkg = require("mypkg/cjs");

@rauschma
Copy link
Author

rauschma commented Oct 18, 2019

@mgtitimoli True!

@mgtitimoli
Copy link

I don't know if they are gonna be bundled, but transpiled for sure...

CJS output would require more transformations as it would be targeted for older engines.

@mgtitimoli
Copy link

mgtitimoli commented Oct 18, 2019

Thanks @rauschma for including my suggestions, however there are still some things to clarify:

  1. All the files would have .js extensions (<- this is super important) and their types are gonna be controlled by the closer package.json
  2. The main package.json will have an entry "type": "module", so this way all files would be treated as modules by default
  3. There gonna be a cjs folder with an additional package.json but this time this one will have an entry with "type": "commonjs", so every file under this folder would be treated as a commonjs file.

@mgtitimoli
Copy link

mgtitimoli commented Oct 18, 2019

It's worth noticing that I came out with these suggestions after having read this some time ago.

@jampy
Copy link

jampy commented Oct 18, 2019

Probably unpopular idea: what about publishing multiple packages, each with different language versions?

mypkg-cjs
mypkg-es2016

Build tools could help with automated publishing and/or NPM could support this somehow.

This would avoid unused JS files in node_modules and would not require any specialized support by Node nor bundlers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment