Skip to content

feat: Update the library to export ESM and CJS at the same time #47

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Pouja
Copy link

@Pouja Pouja commented Apr 21, 2025

It required some hoops to make it work with mocha/chai due to chai only working with ESM. But I could not set the package type to module, due to still requiring tsc to output cjs. The only way was to use .mts file extension and have 2 separate tsconfig files.

To test this, I created three files:

// bundle-me.ts
import { IsEmail } from "class-validator";
import { transformAndValidate } from "class-transformer-validator";

// declare the class using class-validator decorators
class User {
  @IsEmail()
  public email: string;

  public hello(): string {
    return "World!";
  }
}

// then load the JSON string from any part of your app
const userJson: string = JSON.stringify({email: 'me@hello.com'});

// transform the JSON to class instance and validate it correctness
transformAndValidate(User, userJson)
  .then((userObject: User) => {
    // now you can access all your class prototype method
    console.log(`Hello ${userObject.hello()}`); // prints "Hello World!" on console
  })
  .catch(err => {
    // here you can handle error on transformation (invalid JSON)
    // or validation error (e.g. invalid email property)
    console.error(err);
  });
// esbuild.config.cjs.js
import { build } from "esbuild";
import { writeFileSync } from 'node:fs';

try {
    const { metafile } = await build({
        bundle: true,
        entryPoints: ['bundle-me.ts'],
        mainFields: ["main"],
        platform: "node",
        format: "cjs",
        metafile: true,
        outdir: "dist",
        color: true,
        logLevel: 'info',
        tsconfig: 'tsconfig.json'
    });
    writeFileSync('./dist/metafile.json', JSON.stringify(metafile, null, 2), 'utf-8');
} catch (e) {
    console.error(e);
    process.exit(1);
}
// esbuild.config.esm.js
import { build } from "esbuild";
import { writeFileSync } from 'node:fs';

try {
    const { metafile } = await build({
        bundle: true,
        entryPoints: ['bundle-me.ts'],
        mainFields: ["module", "main"],
        platform: "node",
        format: "esm",
        metafile: true,
        outdir: "dist",
        color: true,
        logLevel: 'info',
        tsconfig: 'tsconfig.json'
    });
    writeFileSync('./dist/metafile.json', JSON.stringify(metafile, null, 2), 'utf-8');
} catch (e) {
    console.error(e);
    process.exit(1);
}

Then you can bundle and see the result between ESM and CJS:

~/d/n/bundle-class-transformer-validator ❯❯❯ node esbuild.config.cjs.js

  dist/bundle-me.js  944.6kb

⚡ Done in 61ms
~/d/n/bundle-class-transformer-validator ❯❯❯ node esbuild.config.esm.js

  dist/bundle-me.js  88.9kb

⚡ Done in 48ms

It did require some manual copying to verify this.

This should resolve #30

It required some hoops to make it work with mocha/chai due to chai only working with ESM. But I could not set the package type to module, due to still requiring tsc to output cjs. The only way was to use .mts file extension and have 2 separate tsconfig files.
@Pouja
Copy link
Author

Pouja commented Apr 21, 2025

This should not break for anyone already using CJS. The output is exactly the same.

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.

Support tree shaking (google-libphonenumber is huge)
1 participant