简体   繁体   English

如何在 Jscodeshift 中正确导出常量

[英]How to properly export a const in Jscodeshift

I am writing my first codemod using Jscodeshift.我正在使用 Jscodeshift 编写我的第一个 codemod。 My current goal is to export a const that is assigned a certain identifier.我当前的目标是导出分配了某个标识符的 const。

So that, if I target every variable named stuff , it will be named-exported after the script runs.因此,如果我针对每个名为stuff变量,它将在脚本运行后命名导出。

IN:在:

const stuff = 4;

OUT:出去:

export const stuff = 4;

This is a stripped down version of what I have.这是我所拥有的精简版。 It sort of works but it looks very brittle and has a number of drawbacks.有点工作,但它看起来很脆弱并且有许多缺点。

const constName = "stuff";

module.exports = (fileInfo, api) => {
  const j = api.jscodeshift;
  const root = j(fileInfo.source);

  const declaration = root.find(j.VariableDeclaration, {
    declarations: [
      {
        id: {
          type: "Identifier",
          name: constName
        }
      }
    ]
  });

  declaration.forEach(n => {
    n.insertBefore("export");
  });

  return root.toSource();
};

AST AST

This will result in (notice the unwanted new line)这将导致(注意不需要的新行)

export
const stuff = 4;

This also crucially fails if this source is fed to the script.如果将此源提供给脚本,这也将严重失败。

IN:在:

// hey
const stuff = 4;

OUT:出去:

export
// hey
const stuff = 4;

I am quite convinced that n.insertBefore("export");我非常确信n.insertBefore("export"); is really the culprit here, and I'd like to build the named export myself using jscodeshift builders but really can't get it work.真的是这里的罪魁祸首,我想使用 jscodeshift 构建器自己构建命名导出,但真的无法让它工作。

Any suggestions here?这里有什么建议吗?

.insertBefore is not the right method to use. .insertBefore不是正确的使用方法。 This is for inserting a whole new node before another node.这是为了在另一个节点之前插入一个全新的节点。

How want to replace a VariableDeclaration with an ExportNamedDeclaration .如何用ExportNamedDeclaration替换VariableDeclaration If you look at the AST for export const stuff = 4;如果您查看 AST 中的export const stuff = 4; you can see that it has a property declaration whose value is a VariableDeclaration node.您可以看到它有一个属性declaration其值为VariableDeclaration节点。 That makes the transformation easy for us: Find the VariableDeclaration , create a new ExportNamedDeclaration , set it's declaration property to the found node and replace the found node with the new node.这使我们的转换变得容易:找到VariableDeclaration ,创建一个新的ExportNamedDeclaration ,将它的declaration属性设置为找到的节点,并用新节点替换找到的节点。

To find out how to build the node we can look at ast-type 's ast definitions .要了解如何构建节点,我们可以查看ast-type的 ast 定义

const constName = "stuff";

module.exports = (fileInfo, api) => {
  const j = api.jscodeshift;

  return j(fileInfo.source)
    .find(j.VariableDeclaration, {
      declarations: [
        {
          id: {
            type: "Identifier",
            name: constName
          }
        }
      ]
    })
    .replaceWith(p => j.exportDeclaration(false, p.node))
    .toSource();
};

astexplorer 星际探索者

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM