import { createRequire } from 'node:module'; import url from 'node:url'; import { defineConfig } from 'tsdown'; // css-tree uses createRequire() to load .json data files, which breaks at // runtime in ESM bundles. We bundle it in (noExternal) so we can intercept // those require() calls via this plugin and inline the JSON content at build // time. See https://github.com/resend/react-email/pull/2425. const hoistCreateRequireImports = { name: 'hoist-create-require-imports', async transform(code: string, id: string, meta: Record) { if (id.includes('css-tree')) { const localizedRequire = createRequire(url.pathToFileURL(id)); return { code: code .replaceAll("import { createRequire } from 'module';", '') .replaceAll( /(const|var|let)\s+require\s*=\s*createRequire\s*\([^)]*\)\s*;?/g, '', ) .replaceAll( /require\s*\(\s*(['"])([^)]+?\.json)\1\s*\)/gm, (_match: string, _quote: string, jsonSpecifier: string) => { return JSON.stringify( localizedRequire(localizedRequire.resolve(jsonSpecifier)), null, 2, ); }, ), ...meta, }; } }, }; export default defineConfig([ { dts: false, entry: ['./src/cli/index.ts'], format: ['esm'], outDir: 'dist/cli', }, { dts: true, entry: ['./src/index.ts'], format: ['esm', 'cjs'], outDir: 'dist', deps: { alwaysBundle: ['css-tree'], neverBundle: [/^react($|\/)/, /^react-dom($|\/)/], }, plugins: [hoistCreateRequireImports], }, ]);