metadevpro/ts-pegjs

`ts-pegjs` does not work when using `type: 'module'` in `package.json`

KrofDrakula opened this issue · 8 comments

Reproduction

Using version 3.x of peggy and 4.2.x of ts-pegjs.

Set the project type to "module" in package.json. Import peggy and ts-pegjs as usual:

import peggy from 'peggy';
import tsPegjs from 'ts-pegjs';

console.log(
  peggy.generate("start = ('a' / 'b')+", {
    output: 'source',
    format: 'es',
    plugins: [tsPegjs],
  })
);

A live reproduction is available on StackBlitz:

https://stackblitz.com/edit/vitejs-vite-asiiyk?file=scripts%2Fbuild.js&terminal=dev

Use command npm run peggy to run the script.

Expected result

Running this script should log out the generated parser source.

Actual result

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/home/projects/vitejs-vite-asiiyk/node_modules/prettier/parser-typescript' imported from /home/projects/vitejs-vite-asiiyk/node_modules/ts-pegjs/dist/tspegjs.mjs is generated.

Error log:
$ node scripts/build.js
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/home/projects/vitejs-vite-asiiyk/node_modules/prettier/parser-typescript' imported from /home/projects/vitejs-vite-asiiyk/node_modules/ts-pegjs/dist/tspegjs.mjs
Did you mean to import prettier/parser-typescript.js?
    at InternalError.get (https://vitejsviteasiiyk-ps20.w-credentialless.staticblitz.com/blitz.bf38680a.js:35:344855)
    at defaultResolve (https://vitejsviteasiiyk-ps20.w-credentialless.staticblitz.com/blitz.bf38680a.js:35:683858)
    at ESMLoader.resolve (https://vitejsviteasiiyk-ps20.w-credentialless.staticblitz.com/blitz.bf38680a.js:35:1314721)
    at ESMLoader.getModuleJob (https://vitejsviteasiiyk-ps20.w-credentialless.staticblitz.com/blitz.bf38680a.js:35:1312436)
    at https://vitejsviteasiiyk-ps20.w-credentialless.staticblitz.com/blitz.bf38680a.js:35:1076625
    at _0x8a4b23.link (https://vitejsviteasiiyk-ps20.w-credentialless.staticblitz.com/blitz.bf38680a.js:44:315602)
    at https://vitejsviteasiiyk-ps20.w-credentialless.staticblitz.com/blitz.bf38680a.js:35:1076586 {
  code: 'ERR_MODULE_NOT_FOUND'
}

I also confirm this

I'm also seeing this. Is there a workaround?

I fixed it by creating a .cjs file instead of using the CLI interface in a {type:'module'} package. That way, node build.cjs will work even in an ES module package, and you can compile the parser into an ES module file and work without having to switch to a CommonJS package type or use the .cjs extension.

I fixed it by creating a .cjs file instead of using the CLI interface in a {type:'module'} package. That way, node build.cjs will work even in an ES module package, and you can compile the parser into an ES module file and work without having to switch to a CommonJS package type or use the .cjs extension.

Sure, but my build scripts was written in TypeScript and some of the modules won't even work in CommonJS mode. It's easier to just not upgrade yet.

You can force TypeScript into CommonJS mode using .cts too if you're using ts-node (or ts-node-esm) to run them. If you can separate and invoke the build step separately and simply expect the rest of the scripts to assume the built file exists when importing it, it should work. That way you can segregate the parts that have to work in CJS mode (just the parser build step) and have everything else live in ES land.

This is the solution I came up with:

https://github.com/KrofDrakula/mathpls

Note the .gitignore on the built parser file which is imported elsewhere in the TypeScript codebase.

My hacky workaround for this was to change the following in node_modules/ts-pegjs/dist/tspegjs.mjs.

from

import * from  prettierPluginTypescript from "prettierparser-typescript";
import prettier from "prettier/standalone";

to

import prettierPluginTypescript from "prettier/esm/parser-typescript.mjs";
import prettier from "prettier/esm/standalone.mjs";