Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ESNext by default, full ESM-CJS interop, max minification #1059

Merged
merged 17 commits into from
Feb 28, 2022

Conversation

ctjlewis
Copy link
Contributor

@ctjlewis ctjlewis commented Jul 9, 2021

Changes

  • Full ESM-CJS interop: .cjs/.mjs extensions, "module"/"main" fields, "exports" field. Ex:

    "main": "./dist/index.cjs",
    "module": "./dist/index.mjs",
    "exports": {
      "./package.json": "./package.json",
      ".": {
        "import": "./dist/index.mjs",
        "require": "./dist/index.cjs"
      }
    },
    
  • Emits ES2020, Terser minification for ESM by default

  • ES5 output now deprecated behind build --legacy flag

  • Pass --passWithNoTests to Jest by default with tsdx test

  • Package upgrades

Reasoning

  • Smallest possible bundle sizes due to minimal transpilation

  • Maximum ESM/CJS interop for Node 14+

  • ESNext output and ESM/CJS interop changes leave all transpilation to lower featuresets up to library consumers downstream in order to minimize problems at compile-time, and prevent TSDX from enforcing a maximum featureset on consumers (previously, this was ES5).

    Inspired by module resolution issues with React Native's Metro importing TSDX modules. Also results in much smaller bundles, especially now that ESM is Terser'd by default.

@vercel
Copy link

vercel bot commented Jul 9, 2021

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/formium/tsdx/DXDgToBbfGTFxbr7udnDDoQNXziL
✅ Preview: https://tsdx-git-fork-ctjlewis-no-dist-formium.vercel.app

opts.env,
shouldMinify ? 'min' : '',
'js',
fileExtension,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Encode ESM/CJS module status as *.mjs and *.cjs instead of *.esm.js etc.

@@ -38,7 +38,7 @@
"templates"
],
"engines": {
"node": ">=10"
"node": ">=14"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logic assumes Node >14.

"rollup-plugin-postcss": "^2.5.0",
"styled-components": "^5.0.1",
"tiny-invariant": "^1.1.0",
"tiny-warning": "^1.0.3",
"yarn-deduplicate": "^2.1.1"
"yarn-deduplicate": "^3.1.0"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Package updates, do not cause test failures.

Comment on lines +36 to +39
const isEsm = opts.format.includes('es') || opts.format.includes('esm');

const shouldMinify =
opts.minify !== undefined ? opts.minify : opts.env === 'production';
opts.minify !== undefined ? opts.minify : opts.env === 'production' || isEsm;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minify ESM output also.

require: './dist/index.cjs',
},
},
// module: `dist/${safeName}.mjs`,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CJS/ESM interop logic.

@@ -19,7 +19,7 @@ const reactTemplate: Template = {
},
scripts: {
...basicTemplate.packageJson.scripts,
test: 'tsdx test --passWithNoTests',
test: 'tsdx test',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tsdx test now passes --passWithNoTests by default.

@@ -3,5 +3,5 @@ import { PackageJson } from 'type-fest';
interface Template {
dependencies: string[];
name: string;
packageJson: PackageJson;
packageJson: PackageJson & { husky: any; prettier: any; };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prevent TypeError.

Comment on lines +17 to +21
path: `dist/${name}.production.min.cjs`,
limit: '10 KB',
},
{
path: `dist/${name}.esm.js`,
path: `dist/${name}.min.mjs`,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update emitted filepaths.

@@ -41,6 +41,8 @@ export interface TsdxOptions extends SharedOpts {
env: 'development' | 'production';
// Module format
format: ModuleFormat;
/** If `true`, Babel transpile and emit ES5. */
legacy: boolean;
// Is minifying?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ES5 now behind build --legacy flag.

Comment on lines +1 to +3
// import * as module from 'your-package-name';
import * as module from '../dist/index.mjs';
console.log(module);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test ESM import. If we generated this dynamically, the first line would work because of the package.json "exports" field: import * as module from 'my-package-name'

@@ -1,4 +1,4 @@
import { sum } from '../src';
const sum = (a: number, b: number) => a + b;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guaranteed to pass.

@@ -0,0 +1 @@
console.log(require('..'))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test CJS require.

@@ -1,4 +1,4 @@
// regression test for generators
export function* testGenerator() {
return yield true;
yield true;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prevent TypeError.

Copy link
Contributor Author

@ctjlewis ctjlewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes to test files largely involve refactoring for --legacy flag and new emitted filepaths.

@jaredpalmer jaredpalmer merged commit 2d7981b into jaredpalmer:master Feb 28, 2022
@ctjlewis
Copy link
Contributor Author

ctjlewis commented Feb 28, 2022

Ha, totally forgot I sent this in! @jaredpalmer I ended up forking this and doing a lot more, see:

https://github.com/tszip/tszip

I also ended up starting fresh again, building on work done by Luke Edwards (what I currently use, basically state of the art):

https://github.com/tsmodule/tsmodule

Would draw special attention to the "Next.js component library" section of that README. The config mentioned there is now generated automatically by tsmodule create --react [project-name], just need to update docs.

We should talk sometime if you have a minute.

@cdauth
Copy link

cdauth commented Apr 4, 2022

Is there any rough idea when this will be released?

@ctjlewis
Copy link
Contributor Author

@cdauth I'm trying to see what can be done but this repo is mostly not maintained as many people have moved onto other work. I would use tsmodule above even though it's basically experimental, feel free to open an issue if you have any problems.

See also: #1134, #1129.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants