Gathering detailed insights and metrics for @putout/printer
Gathering detailed insights and metrics for @putout/printer
Gathering detailed insights and metrics for @putout/printer
Gathering detailed insights and metrics for @putout/printer
@putout/minify
🐊Putout-based minifier
@putout/recast
JavaScript syntax tree transformer, nondestructive pretty-printer, and automatic source map generator
@putout/plugin-printer
🐊Putout plugin adds support of transformations for @putout/printer
@putout/bundle
🐊Putout bundle suitable for Deno or Browsers
npm install @putout/printer
Typescript
Module System
Min. Node Version
Node Version
NPM Version
84.8
Supply Chain
100
Quality
95.2
Maintenance
100
Vulnerability
100
License
JavaScript (96.06%)
TypeScript (3.94%)
Love this project? Help keep it running — sponsor us today! 🚀
Total Downloads
602,786
Last Day
1,597
Last Week
9,560
Last Month
40,744
Last Year
355,174
MIT License
16 Stars
1,735 Commits
2 Forks
1 Watchers
1 Branches
1 Contributors
Updated on Feb 09, 2025
Minified
Minified + Gzipped
Latest Version
12.31.0
Package Id
@putout/printer@12.31.0
Unpacked Size
254.97 kB
Size
55.57 kB
File Count
153
NPM Version
10.9.0
Node Version
22.13.1
Published on
Feb 09, 2025
Cumulative downloads
Total Downloads
Last Day
-24.2%
1,597
Compared to previous day
Last Week
12.6%
9,560
Compared to previous week
Last Month
52.7%
40,744
Compared to previous month
Last Year
43.4%
355,174
Compared to previous year
8
25
Prints Babel AST to readable JavaScript. Use 🐊Putout to parse your code.
You may also use Babel 8 with estree-to-babel
for ESTree and Babel AST to put .extra.raw
to .raw
(which is simpler for transforms, no need to use Optional Chaining and add extra values every time).
Supports:
npm i @putout/printer
Printer has first class support from 🐊Putout with help of @putout/plugin-printer
. So install:
1npm i @putout/plugin-printer -aD
And update .putout.json
:
1{ 2 "printer": "putout", 3 "plugins": ["printer"] 4}
To benefit from it.
1const {print} = require('@putout/printer'); 2const {parse} = require('putout'); 3const ast = parse('const a = (b, c) => {const d = 5; return a;}'); 4 5print(ast); 6// returns 7` 8const a = (b, c) => { 9 const d = 5; 10 return a; 11}; 12`;
When you need to extend syntax of @putout/printer
just pass a function which receives:
path
, Babel Pathprint
, a function to output result of printing into token array;When path
contains to dashes __
and name, it is the same as: write(path.get('right'))
, and this is
actually traverse(path.get('right'))
shortened to simplify read and process.
Here is how you can override AssignmentPattern
:
1const ast = parse('const {a = 5} = b'); 2 3print(ast, { 4 format: { 5 indent: ' ', 6 newline: '\n', 7 space: ' ', 8 splitter: '\n', 9 quote: `'`, 10 endOfFile: '\n', 11 }, 12 semantics: { 13 comments: true, 14 maxSpecifiersInOneLine: 2, 15 maxElementsInOneLine: 3, 16 maxLogicalsInOneLine: 3, 17 maxVariablesInOneLine: 4, 18 maxTypesInOneLine: 3, 19 maxPropertiesInOneLine: 2, 20 maxPropertiesLengthInOneLine: 15, 21 trailingComma: true, 22 encodeSingleQuote: true, 23 encodeDoubleQuote: false, 24 roundBraces: { 25 arrow: true, 26 sequence: true, 27 assign: false, 28 new: true, 29 }, 30 }, 31 visitors: { 32 AssignmentPattern(path, {print}) { 33 print('/* [hello world] */= '); 34 print('__right'); 35 }, 36 }, 37}); 38 39// returns 40'const {a/* [hello world] */= 5} = b;\n';
format
Options related to visuals and not related to logic of output can be changed with help of format
,
you can override next options:
1const overrides = { 2 format: { 3 indent: ' ', 4 newline: '\n', 5 space: ' ', 6 splitter: '\n', 7 endOfFile: '\n', 8 }, 9};
indent
- use two spaces, tabs, or anything you want;newline
- symbol used for line separation;space
- default symbol used for space character;splitter
- mandatory symbol that used inside of statements like this:Default options produce:
1if (a > 3) 2 console.log('ok'); 3else 4 console.log('not ok');
But you can override them with:
1const overrides = { 2 format: { 3 indent: '', 4 newline: '', 5 space: '', 6 splitter: ' ', 7 }, 8};
And have minified code:
if(a>3)console.log('ok');else console.log('not ok');
Options used to configure logic of output, similar to ESLint rules:
maxElementsInOneLine
- count of ArrayExpression
and ArrayPattern
elements placed in one line.maxLogicalsInOneLine
- count of LogicalExpression
elements placed in one line.maxVariablesInOneLine
- count of VariableDeclarators
in one line.maxPropertiesInOneLine
- count of ObjectProperties
in one line.maxPropertiesLengthInOneLine
- maximum length of Object Property
, when violated splits event if maxPropertiesInOneLine
satisfies;roundBraces
to output braces or not
arrow
: In a single argument arrow function expressions enabled: (a) => {}
, disabled: a => {}
;sequence
: In sequence expressions: enabled: for(let e of l) (a(), b())
, disabled: for(let e of l) a(), b()
;assign
: In assignment expressions: enabled: (e.o=w(e.o)
, disabled: e.o=w(e.o)
;new
: In new expressions: enabled: new Date()
, disabled: new Date
;When you want to improve support of existing visitor or extend Printer with a new ones, you need next base operations:
When you need to override behavior of existing visitor use:
1import { 2 print, 3 visitors as v, 4} from '@putout/printer'; 5 6print(ast, { 7 visitors: { 8 CallExpression(path, printer, semantics) { 9 const {print} = printer; 10 11 if (!path.node.goldstein) 12 return v.CallExpression(path, printer, semantics); 13 14 print('__goldstein'); 15 }, 16 }, 17});
print
Used in previous example print
can be used for a couple purposes:
string
;node
when object
passed;node
when string
started with __
;1print(ast, { 2 visitors: { 3 AssignmentPattern(path, {print, maybe}) { 4 maybe.write.newline(path.parentPath.isCallExpression()); 5 print('/* [hello world] */= '); 6 print('__right'); 7 }, 8 }, 9});
maybe
When you need some condition use maybe
. For example, to add newline only when parent node is CallExpression
you
can use maybe.write.newline(condition)
:
1print(ast, { 2 visitors: { 3 AssignmentPattern(path, {write, maybe}) { 4 maybe.write.newline(path.parentPath.isCallExpression()); 5 write(' /* [hello world] */= '); 6 write('__right'); 7 }, 8 }, 9});
write
When you going to output string you can use low-level function write
:
1print(ast, { 2 visitors: { 3 BlockStatement(path, {write}) { 4 write('hello'); 5 }, 6 }, 7});
indent
When you need to add indentation use indent
, for example when you output body,
you need to increment indentation, and then decrement it back:
1print(ast, { 2 visitors: { 3 BlockStatement(path, {write, indent}) { 4 write('{'); 5 indent.inc(); 6 indent(); 7 write('some;'); 8 indent.dec(); 9 write('{'); 10 }, 11 }, 12});
traverse
When you need to traverse node path, you can use traverse
:
1print(ast, { 2 visitors: { 3 AssignmentExpression(path, {traverse}) { 4 traverse(path.get('left')); 5 }, 6 }, 7});
This is the same as print('__left')
but more low-level, and supports only objects.
About speed, for file speed.js
:
1const {readFileSync} = require('node:fs'); 2 3const putout = require('putout'); 4const parser = require('@babel/parser'); 5 6const code = readFileSync('./lib/tokenize/tokenize.js', 'utf8'); 7const ast = parser.parse(code); 8 9speed('recast'); 10speed('putout'); 11 12function speed(printer) { 13 console.time(printer); 14 15 for (let i = 0; i < 1000; i++) { 16 putout(code, { 17 printer, 18 plugins: ['remove-unused-variables'], 19 }); 20 } 21 22 console.timeEnd(printer); 23}
With contents of tokenize.js
, we have:
MIT
No vulnerabilities found.
No security vulnerabilities found.