An AST-based JavaScript refactoring tool. The guiding philosophy behind jsmod is that traversing and manipulating an abstract syntax tree should be as familiar as traversing and manipulating the DOM tree. Heavily influenced by jQuery and jscodeshift, JSMod features a powerful CSS-like selector engine alongside a chainable API for traversal and manipulation.
TODO
Update all object literals to use the shorthand notation.
({foo: foo, bar: bar, baz: baz})
({foo, bar, baz})
└── ObjectExpression,
└── properties
├── Property
│ ├── shorthand: false
│ ├── key
│ │ └── Identifier
│ │ └── name: "foo"
│ └── value
│ └── Identifier
│ └── name: "foo"
├── Property
│ ├── shorthand: false
│ ├── key
│ │ └── Identifier
│ │ └── name: "bar"
│ └── value
│ └── Identifier
│ └── name: "bar"
└── Property
├── shorthand: false
├── key
│ └── Identifier
│ └── name: "baz"
└── value
└── Identifier
└── name: "baz"
// Parse code into an AST.
const program = recast.parse(input).program;
// Helper functions
const isLongHand = el => el.attr(['shorthand']) === false;
const hasIdenticalKeyValue = el => el.attr(['key', 'name']) === el.attr(['value', 'name']);
// Apply transformation
const newProgram = jsmod(program)
.find('ObjectExpression > Property')
.filter(isLongHand)
.filter(hasIdenticalKeyValue)
.attr('shorthand', true);
const code = recast.print(newProgram.getAst()).code;
// TODO: Save to disk.
- selectors
- element e.g.
Identifier
- combinators
- descendant combinator e.g.
ArrayExpression Identifier
- child combinator e.g.
ArrayExpression > Identifier
- adjacent sibling combinator e.g.
Identifier + Literal
- general sibling combinator e.g.
Identifier ~ Literal
- descendant combinator e.g.
- attribute descent e.g.
ClassDeclaration.id > Identifier
- attribute selectors
- has attribute - e.g.
[name]
- exact match - e.g.
[attribute="value"]
- fuzzy match - e.g.
[attribute~="value"]
- begins with - e.g.
[attribute^="value"]
- ends with - e.g.
[attribute$="value"]
- contains - e.g.
[attribute*="value"]
- has attribute - e.g.
- universal selector e.g.
*
- pseudo selectors
-
:first
-
:first-child
-
:first-of-type
-
:has()
-
:last
-
:last-child
-
:last-of-type
-
:not()
-
:nth-child
-
:nth-last-child
-
:nth-last-of-type
-
:nth-of-type
-
:root
-
- element e.g.
- traversal
-
.children()
-
.closest()
-
.end()
-
.find()
-
.next()
-
.nextAll()
-
.nextUtil()
-
.parent()
-
.parents()
-
.parentsUtil()
-
.prev()
-
.prevAll()
-
.prevUtil()
-
.siblings()
-
- filtering
-
.eq()
-
.filter()
-
.first()
-
.has()
-
.is()
-
.last()
-
.map()
-
.not()
-
.slice()
-
- manipulation
-
.after()
-
.append()
-
.appendTo()
-
.attr()
-
.before()
-
.forEach()
-
.insertAfter()
-
.insertBefore()
-
.prepend()
-
.prependTo()
-
.remove()
-
.replaceWith()
-
.replaceAll()
-
.sort()
-
- misc
-
.get()
-
.toArray()
-