-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from okbug/study/webpack
学习webpack 一半
- Loading branch information
Showing
264 changed files
with
96,914 additions
and
1,109 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/node_modules | ||
node_modules | ||
./node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
let esprima = require('esprima'); | ||
let estraverse = require('estraverse'); | ||
let escodegen = require('escodegen'); | ||
|
||
let code = ` | ||
function ast() {}; | ||
` | ||
|
||
// 生成语法树 | ||
let res = esprima.parse(code); | ||
|
||
// console.log(res) | ||
|
||
// 遍历语法树 (DFS) | ||
|
||
let indent = 0; | ||
const padding = () => " ".repeat(indent); | ||
estraverse.traverse(res, { | ||
enter(node) { | ||
console.log(padding() + '进入' + node.type); | ||
indent += 2; | ||
}, | ||
leave(node) { | ||
indent -= 2; | ||
console.log(padding() + '离开' + node.type); | ||
} | ||
}) | ||
|
||
// 生成语法树 | ||
let target = escodegen.generate(res); | ||
console.log(target) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
const core = require('@babel/core'); | ||
const types = require('babel-types'); | ||
const plugin1 = require('babel-plugin-transform-es2015-arrow-functions'); | ||
const plugin2 = require('@babel/plugin-transform-classes'); | ||
|
||
const code = ` | ||
const sum = (a, b) => a + b; | ||
` | ||
// babel/core 本身只有 生成、遍历、生成 代码的功能,和上面的三个工具一样 | ||
// 它本身不会在代码遍历的时候做一个处理,除了用插件等方法 | ||
let target = core.transform(code, { | ||
plugins: [plugin1] | ||
}) | ||
// console.log(target.code); | ||
|
||
// babel插件其实就是一个对象,它有一个 visitor(访问器) | ||
|
||
let myPlugin = { | ||
visitor: { | ||
/** | ||
* 函数名称就是在遍历语法树时遇到的类型,意味着给这个类型做转换 | ||
* @param {*} path 节点的数据 | ||
*/ | ||
ArrowFunctionExpression(path) { | ||
path.node.type = 'FunctionExpression'; | ||
// 只是添加这个的话 会转成 function (a, b) a + b 普通函数没有隐式返回 | ||
// 并且在箭头函数中的this没有办法取到 | ||
|
||
// 处理this指针 | ||
const thisBinding = hoistFunctionEnvironmen(path) | ||
} | ||
} | ||
} | ||
function hoistFunctionEnvironmen(fnPath) { | ||
const thisEventFn = fnPath.findParent(p => { | ||
return p.isFunction() && !p.isArrowFunctionExpression() || p.isProgram() | ||
}) | ||
} | ||
|
||
let target2 = core.transform(code, { | ||
plugins: [myPlugin] | ||
}) | ||
|
||
// console.log(target2.code) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
const core = require("@babel/core"); | ||
// const types = require('babel-types'); | ||
const { types } = core; | ||
const plugin2 = require("@babel/plugin-transform-classes"); | ||
|
||
let code2 = ` | ||
class A { | ||
constructor(name) { | ||
this.name = name | ||
} | ||
getName() { | ||
console.log(name) | ||
return this.name | ||
} | ||
setName(newName) { | ||
console.log(newName); | ||
if (newName === this.name) return; | ||
this.name = name; | ||
} | ||
} | ||
`; | ||
|
||
let res2 = core.transform(code2, { | ||
plugins: [plugin2], | ||
}); | ||
const myClassTransformPlugin = { | ||
visitor: { | ||
ClassDeclaration(nodePath) { | ||
let { node } = nodePath; | ||
let { id } = node; | ||
let body = []; | ||
let classMethods = node.body.body; // 方法: constructor, getName等等 | ||
classMethods.forEach((method) => { | ||
if (method.kind === "construcotr") { | ||
// 构造函数的话,就创建一个函数 | ||
let ctorFunc = types.functionDeclaration( | ||
id, | ||
method.params, | ||
method.body, | ||
method.generator, | ||
method.async | ||
); | ||
body.push(ctorFunc); | ||
} else { | ||
// 类上的方法 | ||
const key = method.key.name === "constructor" ? id : method.key; | ||
let left = types.memberExpression( | ||
types.memberExpression(id, types.identifier("prototype")), | ||
method.key | ||
); | ||
let right = types.functionExpression( | ||
key /* 函数的名字 这里传null就是匿名函数 */, | ||
method.params, | ||
method.body, | ||
method.generator, | ||
method.async | ||
); | ||
|
||
let func = types.assignmentExpression("=", left, right); | ||
body.push(func); | ||
} | ||
}); | ||
nodePath.replaceWithMultiple(body); | ||
}, | ||
}, | ||
}; | ||
|
||
let res3 = core.transform(code2, { | ||
plugins: [myClassTransformPlugin], | ||
}); | ||
console.log(res3.code); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
const core = require('@babel/core'); | ||
// const { types, template } = core; | ||
const types = require('babel-types') | ||
const template = require('@babel/template') | ||
let code = ` | ||
function a(x, y) { | ||
console.log(x, y); | ||
return x + y | ||
} | ||
` | ||
|
||
function parseCodeStringToStatement(str) { | ||
let arr = str.split('\n').filter(i => i !== ''); | ||
// console.log(arr) | ||
return arr.map(s => template.statement(s)()) | ||
} | ||
|
||
|
||
const error = 'error' | ||
|
||
let customeCode = ` | ||
console.log(${error}); | ||
` | ||
|
||
let parseResult = parseCodeStringToStatement(customeCode); | ||
let plugin = { | ||
visitor: { | ||
FunctionDeclaration(nodePath) { | ||
let {node} = nodePath; | ||
let {id} = node.id; | ||
let blockStatement = node.body; | ||
if (blockStatement.body && types.isTryStatement(blockStatement.body[0])) return; | ||
|
||
// let catchStatement = template.statement(` | ||
// console.log(error, 1); | ||
// `)(); | ||
|
||
// // [catchStatement, template.statement('console.log(\'hello world\')')()] | ||
let catchClause = types.catchClause(types.identifier(error), types.blockStatement(parseResult)); | ||
|
||
let tryStatement = types.tryStatement(blockStatement, catchClause); | ||
let func = types.functionExpression(id, node.params, types.blockStatement([tryStatement]), node.generator, node.async); | ||
nodePath.replaceWith(func) | ||
} | ||
} | ||
} | ||
|
||
|
||
// let res = core.transform(code, { | ||
// plugins: [plugin] | ||
// }); | ||
|
||
// console.log(res.code) | ||
|
||
function parse(code, errorName, errorBody) { | ||
const parseResult = parseCodeStringToStatement(errorBody) | ||
let plugin = { | ||
visitor: { | ||
FunctionDeclaration(nodePath) { | ||
let {node} = nodePath; | ||
let {id} = node.id; | ||
let blockStatement = node.body; | ||
if (blockStatement.body && types.isTryStatement(blockStatement.body[0])) return; | ||
|
||
// let catchStatement = template.statement(` | ||
// console.log(error, 1); | ||
// `)(); | ||
|
||
// // [catchStatement, template.statement('console.log(\'hello world\')')()] | ||
let catchClause = types.catchClause(types.identifier(errorName), types.blockStatement(parseResult)); | ||
|
||
let tryStatement = types.tryStatement(blockStatement, catchClause); | ||
let func = types.functionExpression(id, node.params, types.blockStatement([tryStatement]), node.generator, node.async); | ||
nodePath.replaceWith(func) | ||
} | ||
} | ||
} | ||
return core.transform(code, { | ||
plugins: [plugin] | ||
}).code; | ||
} | ||
|
||
// console.log(parse(` | ||
// function add(x, y) { | ||
// console.log(x, y); | ||
// return x + y; | ||
// } | ||
// `, 'error', `console.log(error)`)) | ||
|
||
let rt = JSON.stringify(core.parse(`let a = 1`).program, null ,2) | ||
console.log(rt); | ||
module.exports = parse; |
Oops, something went wrong.