Himenon/openapi-typescript-code-generator

Bug: Incorrectly publishing for ESM

Closed this issue · 4 comments

Steps To Reproduce

enviroment

% node --version                     
v20.11.0
  • package.json
{
  "name": "openapi-esm",
  "type": "module",
  "scripts": {
    "generate": "node index.js"
  },
  "devDependencies": {
    "@himenon/openapi-typescript-code-generator": "^0.27.4"
  }
}
  • index.js
import * as fs from "fs";

import { CodeGenerator } from "@himenon/openapi-typescript-code-generator";

const main = () => {
  const codeGenerator = new CodeGenerator("spec/openapi.yml");
  const code = codeGenerator.generateTypeDefinition();
  fs.writeFileSync("client.ts", code, { encoding: "utf-8" });
};

main();

The current behavior

% node index.js                      
file:///path/to/repo/index.js:3
import { CodeGenerator } from "@himenon/openapi-typescript-code-generator";
         ^^^^^^^^^^^^^
SyntaxError: Named export 'CodeGenerator' not found. The requested module '@himenon/openapi-typescript-code-generator' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '@himenon/openapi-typescript-code-generator';
const { CodeGenerator } = pkg;

    at ModuleJob._instantiate (node:internal/modules/esm/module_job:132:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:214:5)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at async loadESM (node:internal/process/esm_loader:28:7)
    at async handleMainPromise (node:internal/modules/run_main:113:12)

The expected behavior

To success generate files.

my opinion

This project is made from CommonJS currently.
And Node.js ESM needs whether package.json's "type": "module" or .mjs file extension.

Thus, entry package.json file should be below.

{
  "name": "@himenon/openapi-typescript-code-generator",
  ...
  "module": "$esm/index.mjs",
  "browser": "$esm/index.mjs",
  ...
  "exports": {
    ...
    ".": {
      "import": "./$esm/index.mjs",
      "node": "./$cjs/index.js",
      "browser": "./$esm/index.mjs",
      "default": "./$cjs/index.js",
      "types": "./$types/index.js"
    },
    ...
  }
}

The build .mjs files needs to be strict modulespecifier for import declaration.

// ❌
import * as Api from "./api";
// ✅
import * as Api from "./api.mjs";

Thanks for the bug report ! @Hajime-san

I have been waiting for such a report. This is an opportunity for this library to support ES Modules.

I can definitely solve this problem as I reproduced the problem with the sample code provided.

Please give me some time.

Thank you!
It seems to be working well👍

And, it also works fine on Deno with this ESM migration🦕

deno run --allow-read --allow-write index.ts

import { CodeGenerator } from "npm:@himenon/openapi-typescript-code-generator";

const main = async () => {
  const codeGenerator = new CodeGenerator("spec/openapi.yml");
  const code = codeGenerator.generateTypeDefinition();
  const encoder = new TextEncoder();
  await Deno.writeFile("client.ts", encoder.encode(code));
};

await main();

Oh, it worked on the Deno, too. Thanks for checking!