Roaders / ts-command-line-args

A typescript wrapper for command-line-args that allow you to generate config from existing TS interfaces
26 stars 11 forks source link

Write Markdown not working with ES2020 #32

Closed mt-krainski closed 2 years ago

mt-krainski commented 2 years ago

My Typescript is not very good so I'm not sure I'm doing this right. I have a test.ts file like

import { parse } from "ts-command-line-args";

interface MyInterface {
    first: string;
    second: string;
    help?: boolean;
}

export const args = parse<MyInterface>(
    {
        first: { type: String },
        second: { type: String },
        help: { type: Boolean, optional: true, alias: "h", description: "Prints this usage guide" },
    },
    {
        helpArg: "help",
        headerContentSections: [
            {
                header: "Something here",
                content: "Something else here.",
            },
        ],
        footerContentSections: [{ content: "Copyright: Company Inc." }],
    }
);

console.log(args.first);
console.log(args.second);

and a tsconfig.json file containing compilerOptions.target: "ES2020". If I tsc-compile the file and run it via node, e.g. with --help, it works as expected

> node build/test.js --help

Something here

  Something else here. 

Options

  --first string                            
  --second string                           
  -h, --help        Prints this usage guide 

  Copyright: Company Inc. 

but if I try to run write-markdown, that option doesn't work.

> write-markdown -m README.md -j build/test.js
Loading existing file from '<project path>/README.md'
<node modules path>/node_modules/ts-command-line-args/dist/helpers/markdown.helper.js:131
    var jsExports = require(jsPath);
                    ^

Error [ERR_REQUIRE_ESM]: require() of ES Module <project path>/build/test.js from <node modules path>/node_modules/ts-command-line-args/dist/helpers/markdown.helper.js not supported.
Instead change the require of test.js in <node modules path>/node_modules/ts-command-line-args/dist/helpers/markdown.helper.js to a dynamic import() which is available in all CommonJS modules.
    at loadArgConfig (<node modules path>/node_modules/ts-command-line-args/dist/helpers/markdown.helper.js:131:21)
    at <node modules path>/node_modules/ts-command-line-args/dist/helpers/markdown.helper.js:122:16
    at Array.map (<anonymous>)
    at Object.generateUsageGuides (<node modules path>/node_modules/ts-command-line-args/dist/helpers/markdown.helper.js:120:10)
    at <node modules path>/node_modules/ts-command-line-args/dist/write-markdown.js:60:45
    at step (<node modules path>/node_modules/ts-command-line-args/dist/write-markdown.js:34:23)
    at Object.next (<node modules path>/node_modules/ts-command-line-args/dist/write-markdown.js:15:53)
    at <node modules path>/node_modules/ts-command-line-args/dist/write-markdown.js:9:71
    at new Promise (<anonymous>)
    at __awaiter (<node modules path>/node_modules/ts-command-line-args/dist/write-markdown.js:5:12)
    at writeMarkdown (<node modules path>/node_modules/ts-command-line-args/dist/write-markdown.js:51:12)
    at Object.<anonymous> (<node modules path>/node_modules/ts-command-line-args/dist/write-markdown.js:96:1) {
  code: 'ERR_REQUIRE_ESM'
}

Node.js v17.4.0

Would you have any advise? The hint there says to change the code in markdown.helper.js which is a part of your package.

Roaders commented 2 years ago

I think you're probably going to have to compile test.js in another module format. I am not sure how I would support requiring both sorts of module - it's probably possible but I'd have to research it. You could have a tsconfig file that is used specifically to compile test.js and another tsconfig file that compiles the rest of your project.

mt-krainski commented 2 years ago

Thanks for answering! I'm quite new to TypeScript and I'm not sure what do you mean by module format? What'd be a proper module format to use for this to work?

Roaders commented 2 years ago

ES2020 is a module format. It's a proper module format but new, newer than that module format used by write-markdown. write-markdown uses commonjs. GIve that a try. As I said you could use a separate tsconfig file for generating the imports for write-markdown and for building your app.

mt-krainski commented 2 years ago

I see, thanks. So I changed the module to commonjs in tsconfig.json. I got this

write-markdown -m README.md -j build/test.js
Loading existing file from '<project path>/README.md'
<node modules path>/node_modules/ts-command-line-args/dist/helpers/markdown.helper.js:131
    var jsExports = require(jsPath);
                    ^

Error [ERR_REQUIRE_ESM]: require() of ES Module <project path>/build/test.js from <node modules path>/node_modules/ts-command-line-args/dist/helpers/markdown.helper.js not supported.
test.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules.
Instead rename test.js to end in .cjs, change the requiring code to use dynamic import() which is available in all CommonJS modules, or change "type": "module" to "type": "commonjs" in <project path>/package.json to treat all .js files as CommonJS (using .mjs for all ES modules instead).

    at loadArgConfig (<node modules path>/node_modules/ts-command-line-args/dist/helpers/markdown.helper.js:131:21)
    at <node modules path>/node_modules/ts-command-line-args/dist/helpers/markdown.helper.js:122:16
    at Array.map (<anonymous>)
    at Object.generateUsageGuides (<node modules path>/node_modules/ts-command-line-args/dist/helpers/markdown.helper.js:120:10)
    at <node modules path>/node_modules/ts-command-line-args/dist/write-markdown.js:60:45
    at step (<node modules path>/node_modules/ts-command-line-args/dist/write-markdown.js:34:23)
    at Object.next (<node modules path>/node_modules/ts-command-line-args/dist/write-markdown.js:15:53)
    at <node modules path>/node_modules/ts-command-line-args/dist/write-markdown.js:9:71
    at new Promise (<anonymous>)
    at __awaiter (<node modules path>/node_modules/ts-command-line-args/dist/write-markdown.js:5:12)
    at writeMarkdown (<node modules path>/node_modules/ts-command-line-args/dist/write-markdown.js:51:12)
    at Object.<anonymous> (<node modules path>/node_modules/ts-command-line-args/dist/write-markdown.js:96:1) {
  code: 'ERR_REQUIRE_ESM'
}

Node.js v17.4.0

I did as suggested (changed type to commonjs in package.json) and now I'm getting:

write-markdown -m README.md -j build/test.js
Loading existing file from '<project path>/README.md'
<node modules path>/node_modules/command-line-args/dist/index.js:1374
        const err = new Error(`Unknown option: ${arg}`);
                    ^

UNKNOWN_OPTION: Unknown option: -m
    at Object.commandLineArgs [as default] (<node modules path>/node_modules/command-line-args/dist/index.js:1374:21)
    at parse (<node modules path>/node_modules/ts-command-line-args/dist/parse.js:60:49)
    at Object.<anonymous> (<node modules path>/packages/cuberover-bridge/build/test.js:5:49)
    at Module._compile (node:internal/modules/cjs/loader:1097:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1149:10)
    at Module.load (node:internal/modules/cjs/loader:975:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:999:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at loadArgConfig (<node modules path>/node_modules/ts-command-line-args/dist/helpers/markdown.helper.js:131:21) {
  optionName: '-m'
}

Node.js v17.4.0

I also tried it with a more practical example and got an error related to importing a local package.

Maybe at this point this will still be helpful for someone else. On my side, for reasons unrelated to this issue - write-markdown, however useful was not the main functionality we were looking for - we decided to go with a different package for argument parsing. So I'm closing this as not relevant anymore. Thanks for your help nonetheless!

Roaders commented 2 years ago

I'd like to get it working if I could. If you could share a repo for me to look at that demonstrates the issue I'll take a look.