15

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)

user2167582
  • 5,986
  • 13
  • 64
  • 121

2 Answers2

19

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();
}
developer033
  • 24,267
  • 8
  • 82
  • 108
bluehipy
  • 2,254
  • 1
  • 13
  • 19
  • 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() – user2167582 Sep 04 '17 at 16:47
  • Also is this how they expect you to insert? seems pretty weird that you can't just insert a node. – user2167582 Sep 04 '17 at 16:53
  • 1
    @user2167582 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. – bluehipy Sep 04 '17 at 16:57
  • but what if the file begins with import statement, how do you use insert at? – user2167582 Sep 04 '17 at 17:22
  • @user2167582 You can test if that s the case and decide what to do. – bluehipy Sep 04 '17 at 17:25
  • i eventually went with finding `j.Declaration` but thanks your suggestions inspired me. – user2167582 Feb 08 '18 at 19:41
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";')
user2167582
  • 5,986
  • 13
  • 64
  • 121