Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Add formatting options to util.inspect() #47744

Closed
NullDev opened this issue Apr 27, 2023 · 13 comments
Closed

Feature Request: Add formatting options to util.inspect() #47744

NullDev opened this issue Apr 27, 2023 · 13 comments
Labels
feature request Issues that request new features to be added to Node.js. util Issues and PRs related to the built-in util module.

Comments

@NullDev
Copy link

NullDev commented Apr 27, 2023

Rel: #14638

I wanted to propose a feature request regarding util.inspect():
Add options to control

  • Indentation (amount of spaces), maybe tabs too?
  • Single / Double Quotes
  • Trailing comma?
  • Perhaps linebreaks as well, see example below

Currently:

const obj = {
    x: {
        y: "",
    },
    foo: {
        bar: "abc",
        baz: true,
    },
    stuff: {
        a: "",
        b: "",
        c: "",
    },
};

console.log(
    util.inspect(obj)
);

Results in:

{
  x: { y: '' },
  foo: { bar: 'abc', baz: true },
  stuff: { a: '', b: '', c: '' }
}

Proposal:

const obj = {
    x: {
        y: "",
    },
    foo: {
        bar: "abc",
        baz: true,
    },
    stuff: {
        a: "",
        b: "",
        c: "",
    },
};

console.log(
    util.inspect(obj, {
        indentation: 4,
        quotes: "double",
        breakAfterProperties: true,
    })
);

Which would result in:

{
    x: {
        y: ""
    },
    foo: {
        bar: "abc",
        baz: true
    },
    stuff: {
        a: "",
        b: "",
        c: ""
    }
}

Which almost resembles the original.

If this isn't in the scope for util.inspect() maybe a different formatting helper function?


Addendum: Rationalé / Use Cases (from #47744 (comment))

My current use case would be automatically writing an object to a new JS file without breaking our linting. This use case is rather specific but those options for "consistent code style" probably find other applications (such as generating documentations) as well. I also do see potential for use cases such as tooling / logging. For instance printing objects in some "smart warnings" while adhering to previous logging styles.

I understand that the method is meant for debugging, but in practice developers do use the output of util.inspect. For instance as a starting point for creating code snippets or configuration files or as part of code generation tools or scaffolding utilities. It might be helpful for test cases as well and it could also generally improve readability and DX. As suggested by HinataKah0, we already have compact: true/false. Other options wouldn't hurt in my opinion.

@HinataKah0
Copy link
Contributor

HinataKah0 commented Apr 27, 2023

I think you can set opt compact: false, see the available options.

util.inspect(obj, {
  compact: false,
});

I tried it and it showed something like this:

{
  x: {
    y: ''
  },
  foo: {
    bar: 'abc',
    baz: true
  },
  stuff: {
    a: '',
    b: '',
    c: ''
  }
}

@NullDev
Copy link
Author

NullDev commented Apr 27, 2023

@HinataKah0 Ah wasn't aware of that, thanks! That solves one of the suggestions 😄

@HinataKah0
Copy link
Contributor

HinataKah0 commented Apr 27, 2023

I think it's possible to have an opt for modifying indentation

In lib/internal/util/inspect.js, formatValue relies on ctx.indentationLvl. However... the increment & decrement is hardcoded everywhere 😅 we can simply store the indentationDiff in ctx and apply it

But let's see the collaborators' thoughts if we want to have it or not 😄
If we are going to make it a feature request, finally, I'll have new things to be done

@NullDev
Copy link
Author

NullDev commented Apr 27, 2023

Thank's awesome! Thanks for already looking into it 😃

@VoltrexKeyva VoltrexKeyva added util Issues and PRs related to the built-in util module. feature request Issues that request new features to be added to Node.js. labels Apr 27, 2023
@tniessen
Copy link
Member

As the documentation says, util.inspect() is meant as a debugging aid:

The util.inspect() method returns a string representation of object that is intended for debugging. The output of util.inspect may change at any time and should not be depended upon programmatically.

Sure, we could add more and more options to allow fine-grained control over the output format, but why? Why should we encourage very specific format options (such as trailing commas) for a function whose output format developers were never supposed to rely on?

@NullDev
Copy link
Author

NullDev commented Apr 27, 2023

@tniessen Well, unfortunately there aren't many other options to get a cleanly formatted string representation without using e.g. JSON.stringify(), that, as the name suggests outputs JSON and not an actual string representation of the Object, or to iterate over every property separately.

So why not improve the only built-in method we currently have for that? Or, as mentioned in my suggestion above, implement a helper method for such formatting if it's not in the scope of util.inspect()?

@tniessen
Copy link
Member

Could you clarify your use case? What do you want to use the output for? Why do you need trailing commas, for example?

@NullDev
Copy link
Author

NullDev commented Apr 27, 2023

@tniessen My current use case would be automatically writing an object to a new JS file without breaking our linting. This use case is rather specific but those options for "consistent code style" probably find other applications (such as generating documentations) as well. I also do see potential for use cases such as tooling / logging. For instance printing objects in some "smart warnings" while adhering to previous logging styles.

I understand that the method is meant for debugging, but in practice developers do use the output of util.inspect. For instance as a starting point for creating code snippets or configuration files or as part of code generation tools or scaffolding utilities. It might be helpful for test cases as well and it could also generally improve readability and DX. As suggested by HinataKah0, we already have compact: true/false. Other options wouldn't hurt in my opinion

(Added this reasoning to the original issue)

@tniessen
Copy link
Member

My current use case would be automatically writing an object to a new JS file without breaking our linting

This implies that the formatting function's options must be powerful enough to adhere to whatever linting you apply, which implies a high level of complexity.

Also, the output of util.inspect() is usually not syntactically valid JS, even though it might coincidentally be for the values that you are passing to it (which, as the docs say, is not guaranteed and might break at any point).

@NullDev
Copy link
Author

NullDev commented Apr 27, 2023

That's true. As I said my personal use case is rather specific. The objects in question aren't deeply nested / complex. But I do see some other use cases that mainly involve printing and not using it as-is in code. And of course adding options to cover all linting cases is completely overkill, which is why I only proposed indentation and quotes. Trailing comma is not necessary and line breaks are already covered

@Nickwiz
Copy link

Nickwiz commented Apr 28, 2023

Miss at least indentation option. console.dir() uses util.inspect and it is easy enough to do a quick hack like:

console.log(
	util.inspect(obj, {colors: 1}).replace(
		/^ +/gm, a => '\t'.repeat(a.length / 2)
	)
);

to get tab indentation. (Find two space indentation way to heavy/straining to read in the long run, and very hard to see on bigger objects).

@aduh95
Copy link
Contributor

aduh95 commented May 3, 2023

You should really use JSON.stringify and your linter auto-fix – and if that doesn’t work for you, disable the linter for the file(s) you are generating. You’ll run into edge cases with util.inspect because it’s NOT meant to generate valid JS, on the other hand JSON.stringify is guaranteed per spec to produce valid JS.

@bnoordhuis
Copy link
Member

I believe the consensus here is "no" (and I agree for the reasons Tobias outlined) so I'll go ahead and close this out.

@bnoordhuis bnoordhuis closed this as not planned Won't fix, can't repro, duplicate, stale May 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Issues that request new features to be added to Node.js. util Issues and PRs related to the built-in util module.
Projects
None yet
Development

No branches or pull requests

7 participants