executablebooks / markdown-it-plugin-template

A template for creating a markdown-it plugin.
https://executablebooks.github.io/markdown-it-plugin-template/
MIT License
6 stars 3 forks source link

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

Open chrisjsewell opened 3 years ago

chrisjsewell commented 3 years ago

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: https://github.com/executablebooks/markdown-it-plugin-template/blob/d6cd3eab97ae6e484f76291b87c9de8b4d4931b6/package.json#L13-L24

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: https://github.com/executablebooks/markdown-it-plugin-template/blob/88078b13da5c8b9b8f496cb1393c82a4b9f292d3/tsconfig.json#L7-L8

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): https://github.com/executablebooks/markdown-it-plugin-template/blob/88078b13da5c8b9b8f496cb1393c82a4b9f292d3/rollup.config.js#L14

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: https://github.com/mjackson/unpkg/issues/34

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

chrisjsewell commented 3 years ago

@rowanc1 interested to get your opinion?

chrisjsewell commented 3 years ago

See also https://github.com/markdown-it/markdown-it/pull/613#issuecomment-610691453 and https://github.com/nodeca/js-yaml/commit/1b5fea8526fea734041334db3687ae5a919a0dfc, i.e. I think markdown-it will also soon move to this duel umd + esm deployment strategy

chrisjsewell commented 3 years ago

Also, a related question, is how/should type files (.d.ts) be "rolled up" into a single file, see e.g. rollup-plugin-dts and Rollup your types

(plus I realised after 86e9fb3292b4222ef584e31b16acb8a3865af488, I now have types in both dist/cjs and dist/mjs and so "types": "dist/index.d.ts" in package.json is wrong)

rowanc1 commented 3 years ago

I have had the most experience with webpack and creating targets for consumption in browser. For most of these plugins do you see the consumption happening in the browser (through a script tag) or through node and then re-bundling at the downstream application? I suppose both might happen, but I would certainly think that most of these would be consumed through node imports? For strict node packages I have just used tsc with some basic/default configuration (I suppose this is still cjs?).

One other target I have found handy in the package.json is unpkg: pointing to the minified bundle that can be used directly in the browser.

chrisjsewell commented 3 years ago

cheers for the feedback

Think I have it mainly sorted now though, with: https://executablebooks.github.io/markdown-it-plugin-template/ 😄

Note, Rollup now builds umd (instead of cjs) + esm (both minified), and unpkg already loads from the main entry point in package.json, so I think unpkg is not necessary.