tsdx icon indicating copy to clipboard operation
tsdx copied to clipboard

Add modern format

Open hardfist opened this issue 6 years ago • 8 comments

Current Behavior

https://github.com/developit/microbundle#new-modern-js like microbundle supports

Desired Behavior

Suggested Solution

Who does this impact? Who is this for?

Describe alternatives you've considered

Additional context

hardfist avatar Nov 03 '19 14:11 hardfist

low effort issue

swyxio avatar Nov 04 '19 00:11 swyxio

We should add this. Is there a new package.json entry key for this?

jaredpalmer avatar Dec 19 '19 15:12 jaredpalmer

no idea. probably what parcel does we should also do https://github.com/parcel-bundler/parcel/#targets since i dont see anyone else trying to standardize package.json

swyxio avatar Dec 19 '19 17:12 swyxio

even though entry key is not standardized, since uses can customize webpack's mainfield

module.exports = {
  //...
  resolve: {
    mainFields: ['browserModern', 'browser', 'module', 'main'] // load modern first
  }
};

It stills make sense if tsdx add an entry to point modern format

hardfist avatar Dec 20 '19 03:12 hardfist

Just wanted to re-up this to put it back on your radar @jaredpalmer.

There's now a good bit of steam around the "exports" field implying modern JavaScript. The TLDR is that, since "exports" only started being supported very recently (Node 12.9, Webpack 5, @rollup/plugin-node-resolve@16), it is unsafe to assume files pointed to by this field are ES5.

Here's a quick video explanation: https://youtu.be/cLxNdLK--yI?t=537

For TSDX, I'd recommend jumping on this in order to provide better output for the majority case:

Modern + ESM + UMDModern + ESM + CJS + UMD
{
  "main": "./dist/es5.umd.js",
  "module": "./dist/es5.module.js",
  "exports": {
    "import": "./dist/es2017.module.js",
    "default": "./dist/es5.umd.js"
  }
}
{
  "main": "./dist/es5.cjs.js",
  "unpkg": "./dist/es5.umd.js",
  "umd:main": "./dist/es5.umd.js",
  "module": "./dist/es5.module.js",
  "exports": {
    "import": "./dist/es2017.module.js",
    "default": "./dist/es5.cjs.js"
  }
}

One huge perk of doing in this in TSDX specifically is that TypeScript's "2017" target was specifically designed for this exact usage. It aligns directly with the set of JS features that shipped in all browsers that support <script type=module>, which is the cutoff most configurations are using to denote "modern" JS. This makes it possible to bundle in development and even production without having to transpile modern packages.

developit avatar Feb 26 '21 17:02 developit

@developit what if the library node && library support have different implementation, then which module should points to? node implementation or browser implementation?

hardfist avatar Feb 28 '21 15:02 hardfist

@hardfist there is a "node" exports object key that you can use to provide a different set of exports for Node, with the other keys assumed to be browser:

{
  // these are for Node:
  "node": {
    "import": "./dist/modern-node.js",
    "default": "./dist/modern-node.cjs"
  },
  // these are for browser builds:
  "import": "./dist/modern-browser.js",
  "default": "./dist/modern-browser.cjs"
}

developit avatar Feb 28 '21 15:02 developit

how does bundler know about that? by main fields?

hardfist avatar Feb 28 '21 22:02 hardfist