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

6.2k views Asked by At

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)

2

There are 2 answers

6
bluehipy On BEST ANSWER

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();
}
0
user2167582 On

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";')