From cc888e1912eefb1fc49dc634575702e2bb8bac73 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=8E=E6=96=87=E5=AF=8C?= 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 +1552,15 @@ 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 +1619,10 @@ FunctionDeclaration(path) {
}
```
-这些选项会通过`状态>对象传递给插件访问者:
+这些选项会通过 `状态` 对象传递给插件访问者:
-export default function({ types: t }) {
+```js
+export default function({ types: t }) {
return {
visitor: {
FunctionDeclaration(path, state) {
@@ -1629,7 +1632,7 @@ FunctionDeclaration(path) {
}
}
}
-`
+```
这些选项是特定于插件的,您不能访问其他插件中的选项。
@@ -1699,15 +1702,16 @@ export default function({ types: t }) {
# 构建节点
-编写转换时,通常需要构建一些要插入的节点进入AST。 如前所述,您可以使用` babel-types >包中的builder >方法。
+编写转换时,通常需要构建一些要插入的节点进入AST。 如前所述,您可以使用 `babel-types` 包中的 builder方法。
-构建器的方法名称就是您想要的节点类型的名称,除了第一个字母小写。 例如,如果您想建立一个 MemberExpression >您可以使用
t.memberExpression(...)>.
这些构建器的参数由节点定义决定。 有一些正在做的工作,以生成易于阅读的文件定义,但现在他们都可以在此处找到。.
+这些构建器的参数由节点定义决定。 有一些正在做的工作,以生成易于阅读的文件定义,但现在他们都可以在 此处 找到。 -节点定义如下所示:
+节点定义如下所示: -defineType("MemberExpression", {
+```js
+defineType("MemberExpression", {
builder: ["object", "property", "computed"],
visitor: ["object", "property"],
aliases: ["Expression", "LVal"],
@@ -1726,7 +1730,7 @@ export default function({ types: t }) {
}
}
});
-`
+```
在这里你可以看到关于这个特定节点类型的所有信息,包括如何构建它,遍历它,并验证它。
@@ -1736,10 +1740,13 @@ export default function({ types: t }) {
生成器: ["object", "property", "computed"],
```
-> 请注意,有时在节点上可以定制的属性比``构建器>数组包含的属性更多。 这是为了防止生成器有太多的参数。 在这些情况下,您需要手动设置属性。 一个例子是// Example
+```js
+// Example
// because the builder doesn't contain `async` as a property
var node = t.classMethod(
"constructor",
@@ -1749,11 +1756,11 @@ 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
+```
+
+You can see the validation for the builder arguments with the `fields` object.
+
+```js
fields: {
object: {
validate: assertNodeType("Expression")
@@ -1926,7 +1933,8 @@ 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 +1945,7 @@ const MyVisitor = {
path.traverse(nestedVisitor);
}
};
-`
+```
如果您在嵌套的访问者中需要一些状态,像这样:
@@ -2010,7 +2018,8 @@ const MyVisitor = {
我们忽略了类可以嵌套的事实,使用遍历的话,上面我们也会得到一个嵌套的`构造函数>:
-class Foo {
+```js
+class Foo {
constructor() {
class Bar {
constructor() {
@@ -2019,7 +2028,7 @@ const MyVisitor = {
}
}
}
-`
+```
## 单元测试
@@ -2028,7 +2037,7 @@ const MyVisitor = {
首先我们需要一个babel插件,我们将把它放在src / index.js中。
```js
-jest -u >一样简单.
-// src/__tests__/index-test.js
+```js
+// src/__tests__/index-test.js
const babel = require('babel-core');
const plugin = require('../');
@@ -2059,21 +2069,22 @@ 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”并再次运行,则可以得到以下结果:
+如果我们在插件中将 “bar” 更改为 “baz” 并再次运行,则可以得到以下结果:
```diff
-接收到的值与存储的快照1不匹配。
+Received value does not match stored snapshot 1.
- Snapshot
+ Received
@@ -2086,26 +2097,33 @@ if (bar) console.log(bar);"
+if (baz) console.log(baz);"
```
-我们看到我们对插件代码的改变如何影响了我们插件的输出 如果输出看起来不错,我们可以运行`jest -u >来更新快照。
+我们看到我们对插件代码的改变如何影响了我们插件的输出。如果输出看起来不错,我们可以运行 `jest -u` 来更新快照。
-AST 测试
+### AST 测试
-除了快照测试外,我们还可以手动检查AST。 这是一个简单但是脆弱的例子。 对于更多涉及的情况,您可能希望利用Babel-遍历。 它允许您用访问者>键指定一个对象,就像您使用插件本身。
+除了快照测试外,我们还可以手动检查AST。
+这是一个简单但是脆弱的例子。
+对于更多涉及的情况,您可能希望利用Babel-遍历。
+它允许您指定一个带有 `visitor` 字段的对象,就像您使用插件本身。
-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>。 这确保如果我们的插件做了奇怪的操作,如意外删除断言线,但测试仍然失败。
+在这里,我们将转换代码,然后评估它的行为是否正确。
+请注意,我们在测试中没有使用 `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,13 +2137,15 @@ if (bar) console.log(bar);"
var res = f();
assert(res === 1, 'res is 1');
});
-``
+```
-Babel核心使用类似的方法>去获取快照和执行测试。
+Babel 核心使用 [类似的方法](https://github.com/babel/babel/blob/7.0/CONTRIBUTING.md#writing-tests) 去获取快照和执行测试。
### [`babel-plugin-tester`](https://github.com/kentcdodds/babel-plugin-tester)
-这个包使测试插件更容易。 如果您熟悉ESLint的[ RuleTester](http://eslint.org/docs/developer-guide/working-with-rules#rule-unit-tests)您应该对这是熟悉的。 您可以看看[the docs](https://github.com/kentcdodds/babel-plugin-tester/blob/master/README.md)去充分了解可能的情况,但这里有一个简单的例子:
+这个包使测试插件更容易。
+如果您熟悉 ESLint 的 [RuleTester](http://eslint.org/docs/developer-guide/working-with-rules#rule-unit-tests) 您应该对这是熟悉的。
+您可以看看 [the docs](https://github.com/kentcdodds/babel-plugin-tester/blob/master/README.md) 去充分了解可能的情况,但这里有一个简单的例子:
```js
import pluginTester from 'babel-plugin-tester';
@@ -2155,7 +2175,3 @@ pluginTester({
},
});
```
-
-* * *
-
-> ***对于将来的更新,请跟随 @thejameskyle >和 @babeljs > 的Twitter。
\ No newline at end of file