Skip to content

feat: emit ESM syntax in standalone mode via ajv.code.esm - #872

Open
jaideeppyne wants to merge 1 commit into
fastify:mainfrom
jaideeppyne:feat/standalone-esm
Open

feat: emit ESM syntax in standalone mode via ajv.code.esm#872
jaideeppyne wants to merge 1 commit into
fastify:mainfrom
jaideeppyne:feat/standalone-esm

Conversation

@jaideeppyne

Copy link
Copy Markdown

Summary

Closes #679.

Standalone mode currently hardcodes CommonJS (require / module.exports), so ESM and TypeScript consumers have to wrap the generated serializer in an interop layer. This mirrors Ajv's standalone code.esm option: when the serializer is built with

fastJson(schema, { mode: 'standalone', ajv: { code: { esm: true } } })

the generated code uses import / export default instead of require / module.exports.

Details

  • Reads options.ajv.code.esm (already threaded through to the validator) so the standalone serializer output matches the validator's module format — the same flag @fastify/ajv-compiler's StandaloneValidator already honors.
  • Emits import Serializer from 'fast-json-stringify/lib/serializer.js' / import Validator from '.../validator.js' and export default (...)(validator, serializer). Two ESM-specific details are handled:
    • explicit .js extensions, which ESM resolution requires (CJS require does not);
    • the IIFE is wrapped in parentheses, because export default function () {}(...) parses as a function declaration and would drop the invocation.
  • CommonJS output is byte-for-byte unchanged — the ESM path is only taken when ajv.code.esm === true.

Testing

  • Added two tests to test/standalone-mode.test.js that generate ESM output, write it to a .mjs file, dynamically import() it, and assert it serializes correctly — both without a validator and with an if/then/else schema that pulls in the Ajv validator dependency.
  • Full suite green (497 tests); standalone.js at 100% coverage; eslint clean.
  • Documented the option in the Standalone Mode section of the README.

Standalone mode hardcoded CommonJS require/module.exports, forcing ESM/TypeScript
consumers to add interop shims. Mirror Ajv's standalone code.esm option: when
`{ mode: 'standalone', ajv: { code: { esm: true } } }` is set, emit
import/export default (with explicit .js extensions that ESM resolution requires)
instead of require/module.exports. CommonJS output is unchanged by default.

Closes fastify#679

Signed-off-by: Jaideep Pyne <jaideeppyne1997@gmail.com>
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.

emit CJS/ESM syntax in standalone mode based on AJV code options

1 participant