Skip to content

What distribution(s) to target (CJS, ESM, ...)? #1

@chrisjsewell

Description

@chrisjsewell

Certainly compared to Python (one distribution works for all v3.x), JS/TS is a bit of a mess when it comes to packaging libraries: not only do you need to think about the version/format of javascript (and compatibility with third-party modules), but also node vs browser compatibility.

Essentially CommonJS modules are a legacy format, that many third party packages still use, whereas ES modules are now the ~official standard and "future" of javascript (and are now basically supported in all browsers: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules, see also https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/).
Again comparing to Python, it feels like JS/TS is in a similar situation to when python packages were transitioning from v2 to v3 (and so support was necessary for both).

Using rollup you can actually target multiple build formats:

Currently, I have it set to do a "hybrid" build with: https://github.com/executablebooks/markdown-it-plugin-template/blob/master/rollup.config.js, and in package.json pointing to either with:

"main": "dist/cjs/index.js",
"module": "dist/mjs/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"exports": {
".": {
"import": "./dist/mjs/index.js",
"require": "./dist/cjs/index.js"
}
},

This is essentially what is recommended here, but then here it mentions a danger in "double transpiling".

Additionally confusing, is what to target in the tsconfig:

"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */
"module": "es2015", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */

and also how babel fits in with rollup, and if @rollup/plugin-babel is actually needed (if you remove this plugin, it still builds fine at present):

babel({ babelHelpers: "bundled" }), // transpile ES6/7 code

It is of note that markdown-it itself uses the umd format (amd, cjs and iife), in its rollup config: https://github.com/markdown-it/markdown-it/blob/064d602c6890715277978af810a903ab014efc73/support/rollup.config.js#L13

Also a consideration of what is required for unpkg: unpkg/unpkg#34

Here is also a bunch of links about CommonJS vs ES Modules and building hybrid packages:

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions