jaredpalmer / tsdx

Zero-config CLI for TypeScript package development
https://tsdx.io
MIT License
11.28k stars 507 forks source link

Add modern format #298

Open hardfist opened 5 years ago

hardfist commented 5 years ago

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

swyxio commented 5 years ago

low effort issue

jaredpalmer commented 4 years ago

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

swyxio commented 4 years ago

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

hardfist commented 4 years ago

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

developit commented 3 years ago

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
```jsonc { "main": "./dist/es5.umd.js", "module": "./dist/es5.module.js", "exports": { "import": "./dist/es2017.module.js", "default": "./dist/es5.umd.js" } } ``` ```jsonc { "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.

hardfist commented 3 years ago

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

developit commented 3 years ago

@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"
}
hardfist commented 3 years ago

how does bundler know about that? by main fields?