Skip to content

Commit

Permalink
Merge pull request #3 from okbug/study/webpack
Browse files Browse the repository at this point in the history
学习webpack 一半
  • Loading branch information
okbug authored Nov 24, 2021
2 parents 89fe513 + 0aeee66 commit 0c1ded4
Show file tree
Hide file tree
Showing 264 changed files with 96,914 additions and 1,109 deletions.
Binary file modified .DS_Store
Binary file not shown.
3 changes: 3 additions & 0 deletions learnWebpack/ast-demo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/node_modules
node_modules
./node_modules
31 changes: 31 additions & 0 deletions learnWebpack/ast-demo/1.js
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)
45 changes: 45 additions & 0 deletions learnWebpack/ast-demo/2.js
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)

73 changes: 73 additions & 0 deletions learnWebpack/ast-demo/3.js
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);
92 changes: 92 additions & 0 deletions learnWebpack/ast-demo/4.js
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;
Loading

0 comments on commit 0c1ded4

Please sign in to comment.