From 6e9e9a1a4631a23b57d48f47a37ffadd1533f2f1 Mon Sep 17 00:00:00 2001 From: hbisedm <1368373296@qq.com> Date: Sun, 20 Nov 2022 00:07:36 +0800 Subject: [PATCH] Update plugin-handbook.md --- translations/zh-Hans/plugin-handbook.md | 132 ++++++++++++++---------- 1 file changed, 75 insertions(+), 57 deletions(-) diff --git a/translations/zh-Hans/plugin-handbook.md b/translations/zh-Hans/plugin-handbook.md index 6e0a7c81..0ff86566 100644 --- a/translations/zh-Hans/plugin-handbook.md +++ b/translations/zh-Hans/plugin-handbook.md @@ -1312,8 +1312,8 @@ path.getStatementParent(); * 使用 `path.listKey`获取容器的key > 这些API用于 babel-minify 中使用的 transform-merge-sibling-variables 插件.

-> -> ```js + +```js var a = 1; // pathA, path.key = 0 var b = 2; // pathB, path.key = 1 var c = 3; // pathC, path.key = 2 @@ -1406,8 +1406,8 @@ ReturnStatement(path) { > **注意:当用多个节点替换一个表达式时,它们必须是   声明。 这是因为Babel在更换节点时广泛使用启发式算法,这意味着您可以做一些非常疯狂的转换,否则将会非常冗长。

> > ### 用字符串源码替换节点 -> -> ```js + +```js FunctionDeclaration(path) { path.replaceWithSourceString(`function add(a, b) { return a + b; @@ -1426,8 +1426,8 @@ FunctionDeclaration(path) { > **注意:不建议使用这个API,除非您正在处理动态的源码字符串,否则在访问者外部解析代码更有效率。

> > ### 插入兄弟节点 -> -> ```js + +```js FunctionDeclaration(path) { path.insertBefore(t.expressionStatement(t.stringLiteral("Because I'm easy come, easy go."))); path.insertAfter(t.expressionStatement(t.stringLiteral("A little high, little low."))); @@ -1443,13 +1443,13 @@ FunctionDeclaration(path) { ``` > 注意:这里同样应该使用声明或者一个声明数组。 这个使用了在用多个节点替换一个节点中提到的相同的启发式算法。.

-> -> ### 插入到容器(container)中 -> + +### 插入到容器(container)中 + > 如果您想要在AST节点属性中插入一个像` body 那样的数组。 它与 insertBefore `/` insertAfter ` 类似, 但您必须指定 ` listKey ` (通常是 ` 正文 `). -> -> ```js + +```js ClassMethod(path) { path.get('body').unshiftContainer('body', t.expressionStatement(t.stringLiteral('before'))); path.get('body').pushContainer('body', t.expressionStatement(t.stringLiteral('after'))); @@ -1482,14 +1482,16 @@ FunctionDeclaration(path) { ### 替换父节点 -只需使用parentPath:` path.parentPath 调用 replaceWith 即可

+只需使用parentPath:`path.parentPath` 调用replaceWith 即可 -
BinaryExpression(path) {
+```js
+BinaryExpression(path) {
   path.parentPath.replaceWith(
     t.expressionStatement(t.stringLiteral("Anyway the wind blows, doesn't really matter to me, to me."))
   );
 }
-`
+``` + ```diff function square(n) { @@ -1551,14 +1553,16 @@ FunctionDeclaration(path) { ### 提升变量声明至父级作用域 -有时你可能想要推送一个` VariableDeclaration ,这样你就可以分配给它。

+有时你可能想要推送一个` VariableDeclaration` ,这样你就可以分配给它。 -
FunctionDeclaration(path) {
+```js
+FunctionDeclaration(path) {
   const id = path.scope.generateUidIdentifierBasedOnNode(path.node.id);
   path.remove();
   path.scope.parent.push({ id, init: path.node });
 }
-`
+``` + ```diff - function square(n) { @@ -1617,9 +1621,10 @@ FunctionDeclaration(path) { } ``` -这些选项会通过`状态对象传递给插件访问者:

+这些选项会通过`状态`对象传递给插件访问者: -
export default function({ types: t }) {
+```js
+export default function({ types: t }) {
   return {
     visitor: {
       FunctionDeclaration(path, state) {
@@ -1629,7 +1634,8 @@ FunctionDeclaration(path) {
     }
   }
 }
-`
+``` + 这些选项是特定于插件的,您不能访问其他插件中的选项。 @@ -1657,7 +1663,7 @@ export default function({ types: t }) { ## 在插件中启用其他语法 -插件可以启用babylon plugins,以便用户不需要安装/启用它们。 这可以防止解析错误,而不会继承语法插件。

+插件可以启用`babylon plugins`,以便用户不需要安装/启用它们。 这可以防止解析错误,而不会继承语法插件。

```js export default function({ types: t }) { @@ -1693,7 +1699,7 @@ export default function({ types: t }) { 10 | 11 | "Hovering over a node highlights the \ 12 | corresponding part in the source code", - + * * * @@ -1707,7 +1713,8 @@ export default function({ types: t }) {

节点定义如下所示:

-
defineType("MemberExpression", {
+```js
+defineType("MemberExpression", {
   builder: ["object", "property", "computed"],
   visitor: ["object", "property"],
   aliases: ["Expression", "LVal"],
@@ -1726,7 +1733,8 @@ export default function({ types: t }) {
     }
   }
 });
-`
+``` + 在这里你可以看到关于这个特定节点类型的所有信息,包括如何构建它,遍历它,并验证它。 @@ -1739,7 +1747,8 @@ export default function({ types: t }) { > 请注意,有时在节点上可以定制的属性比``构建器数组包含的属性更多。 这是为了防止生成器有太多的参数。 在这些情况下,您需要手动设置属性。 一个例子是 ClassMethod .

-
// Example
+```js
+// Example
 // because the builder doesn't contain `async` as a property
 var node = t.classMethod(
   "constructor",
@@ -1749,25 +1758,26 @@ var node = t.classMethod(
 )
 // set it manually after creation
 node.async = true;
-``
-> +``` + > You can see the validation for the builder arguments with the `fields` object. > > ```js -fields: { - object: { - validate: assertNodeType("Expression") - }, +> fields: { +object: { + validate: assertNodeType("Expression") + }, property: { - validate(node, key, val) { - let expectedType = node.computed ? "Expression" : "Identifier"; + validate(node, key, val) { + let expectedType = node.computed ? "Expression" : "Identifier"; assertNodeType(expectedType)(node, key, val); - } - }, + } + }, computed: { - default: false + default: false + } } -} + ``` You can see that `object` needs to be an `Expression`, `property` either needs to be an `Expression` or an `Identifier` depending on if the member expression is `computed` or not and `computed` is simply a boolean that defaults to `false`. @@ -1919,14 +1929,11 @@ const MyVisitor = { }; ``` -但是,每当调用`FunctionDeclaration()时都会创建一个新的访问者对象。 That can be costly, because Babel does some processing each time a new -visitor object is passed in (such as exploding keys containing multiple types, -performing validation, and adjusting the object structure). Because Babel stores -flags on visitor objects indicating that it's already performed that processing, -it's better to store the visitor in a variable and pass the same object each -time.

+但是,每当调用`FunctionDeclaration()`时都会创建一个新的访问者对象。 That can be costly, because Babel does some processing each time a new visitor object is passed in (such as exploding keys containing multiple types, performing validation, and adjusting the object structure). Because Babel stores flags on visitor objects indicating that it's already performed that processing, +it's better to store the visitor in a variable and pass the same object each time. -
const nestedVisitor = {
+```js
+const nestedVisitor = {
   Identifier(path) {
     // ...
   }
@@ -1937,7 +1944,9 @@ const MyVisitor = {
     path.traverse(nestedVisitor);
   }
 };
-`
+``` + + 如果您在嵌套的访问者中需要一些状态,像这样: @@ -2010,7 +2019,8 @@ const MyVisitor = { 我们忽略了类可以嵌套的事实,使用遍历的话,上面我们也会得到一个嵌套的`构造函数:

-
class Foo {
+```js
+class Foo {
   constructor() {
     class Bar {
       constructor() {
@@ -2019,7 +2029,8 @@ const MyVisitor = {
     }
   }
 }
-`
+``` + ## 单元测试 @@ -2046,7 +2057,8 @@ const MyVisitor = { 接下来,用`` npm install --save-dev babel-core jest 安装我们的依赖关系, 那么我们可以开始写我们的第一个测试:快照。 快照测试允许我们直观地检查我们的babel插件的输出。 我们给它一个输入,告诉它一个快照,并将其保存到一个文件。 我们检查快照到git中。 这允许我们来看看我们什么时候影响了我们任何试用例子测试的输出。 它也给出了使用差异在拉请求的时候。 当然,您可以用任何测试框架来做到这一点,但是要更新一下快照就像jest -u 一样简单.

-
// src/__tests__/index-test.js
+```js
+// src/__tests__/index-test.js
 const babel = require('babel-core');
 const plugin = require('../');
 
@@ -2058,17 +2070,19 @@ if (foo) console.log(foo);
 it('works', () => {
   const {code} = babel.transform(example, {plugins: [plugin]});
   expect(code).toMatchSnapshot();
-});
-``
+}); +``` -这给了我们一个快照文件在`` src / __ tests __ / __ snapshots __ / index-test.js.snap .

+这给了我们一个快照文件在` src / __ tests __ / __ snapshots __ / index-test.js.snap` .

-
exports[`test works 1`] = `
+```js
+exports[`test works 1`] = `
 "
 var bar = 1;
 if (bar) console.log(bar);"
 `;
-``
+``` + 如果我们在插件中将“bar”更改为“baz”并再次运行,则可以得到以下结果: @@ -2092,20 +2106,23 @@ if (bar) console.log(bar);"

除了快照测试外,我们还可以手动检查AST。 这是一个简单但是脆弱的例子。 对于更多涉及的情况,您可能希望利用Babel-遍历。 它允许您用访问者键指定一个对象,就像您使用插件本身。

-
it('contains baz', () => {
+```js
+it('contains baz', () => {
   const {ast} = babel.transform(example, {plugins: [plugin]});
   const program = ast.program;
   const declaration = program.body[0].declarations[0];
   assert.equal(declaration.id.name, 'baz');
   // or babelTraverse(program, {visitor: ...})
 });
-`
+``` + ### Exec Tests 在这里,我们将转换代码,然后评估它的行为是否正确。 请注意,我们在测试中没有使用``assert。 这确保如果我们的插件做了奇怪的操作,如意外删除断言线,但测试仍然失败。

-
it('foo is an alias to baz', () => {
+```js
+it('foo is an alias to baz', () => {
   var input = `
     var foo = 1;
     // test that foo was renamed to baz
@@ -2119,7 +2136,8 @@ if (bar) console.log(bar);"
   var res = f();
   assert(res === 1, 'res is 1');
 });
-``
+``` + Babel核心使用类似的方法去获取快照和执行测试。