how to use jscodeshift to insert a line in the beginning of the file
Asked Answered
S

2

16

https://astexplorer.net/#/gist/ad90272020dd0bfb15619d93cca81b66/28d3cf7178271f4f99b10bc9352daa873c2f2b20

// file
var a = "a" // what if this is import statement?

// jscodeshift
export default (file, api) => {
  const j = api.jscodeshift;

  const root = j(file.source);

  root.find(j.VariableDeclaration)
    .insertBefore("use strict");
  return root.toSource();
}

How does insertBefore work if the first line of code differs across the files. e.g. (variable declaration, import statements)

Siskin answered 3/9, 2017 at 7:27 Comment(0)
R
20

It looks like you have to "cast" the node to the jscodeshift.

A solution is:

export default (file, api) => {
  const j = api.jscodeshift

  const root = j(file.source)

  j(root.find(j.VariableDeclaration).at(0).get())
    .insertBefore(
      '"use strict";'
    )
  return root.toSource()
}

EDIT

For your clarification.

If you want to insert use strict at the beginning of the file no matter what:

export default (file, api) => {
    const j = api.jscodeshift
    const s = '"use strict";';
    const root = j(file.source)

    root.get().node.program.body.unshift(s);  

    return root.toSource()
}

If you want to add use strict after the import declaration, if any:

export default (file, api) => {
    const j = api.jscodeshift
    const s = '"use strict";';
    const root = j(file.source);
    const imports = root.find(j.ImportDeclaration);
    const n = imports.length;

    if(n){
        //j(imports.at(0).get()).insertBefore(s); // before the imports
       j(imports.at(n-1).get()).insertAfter(s); // after the imports
    }else{
       root.get().node.program.body.unshift(s); // beginning of file
    }         

    return root.toSource();
}
Revers answered 4/9, 2017 at 7:23 Comment(6)
Im not sure what the cast does but i think you are missing my point, what if the file begins with an import statement instead of variable declaration? How would you generically say insert at the beginning? So far i've only been able to get this working by rebuilding with j.program()Siskin
Also is this how they expect you to insert? seems pretty weird that you can't just insert a node.Siskin
@Siskin I solved what you asked for :) You weee trying to use insertBefore. You can use insertAt 0 if you just eant to add sone literal at the begining if the structure.Revers
but what if the file begins with import statement, how do you use insert at?Siskin
@Siskin You can test if that s the case and decide what to do.Revers
i eventually went with finding j.Declaration but thanks your suggestions inspired me.Siskin
S
2

The best solution I have so far is to insert before the first j.Declaration,

j(root.find(j.Declaration).at(0).get())
 .insertBefore('"use strict";')
Siskin answered 7/9, 2017 at 17:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.