javascriptabstract-syntax-treejscodeshift

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


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)


Solution

  • 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();
    }