Skip to content

Commit

Permalink
✨ wtf-is-jsx
Browse files Browse the repository at this point in the history
  • Loading branch information
bravepg committed May 18, 2021
1 parent 66e7d49 commit 43b57ce
Show file tree
Hide file tree
Showing 10 changed files with 219 additions and 0 deletions.
39 changes: 39 additions & 0 deletions wtf-is-jsx/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
`babel` 在通过 `cli` 进行 `option``plugins``presets` 配置的时候,一定要保证 `presets` 被安装或者 `preset` 中包含 `plugin`
```
// 一定要保证 @babel/preset-env 被安装
./node_modules/.bin/babel src --out-dir lib --presets=@babel/env
```

@babel/env 会根据浏览器版本进行合适的兼容编译
```
{
"presets": [
[
"@babel/env",
{
"targets": {
// 为了兼容 ie 10,会把箭头函数等都进行编译",
"ie": "10",
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
}
}
]
]
}
```

@babel/polyfill 是很重的使用方式,会增加包体积,对于工具开发者来说,可以使用 @babel/plugin-transform-runtime
useBuiltIns 会在编译的时候自动引入缺失的功能(与 `corejs` 搭配使用)
```
"useBuiltIns": "usage",
"corejs": "3.6.5"
```


// todo
// 插件种类浏览 + 自定义插件
// preset 种类 + 自定义 preset
// babel 7 新特性
37 changes: 37 additions & 0 deletions wtf-is-jsx/babel.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"presets": [
[
"@babel/env",
{
"targets": {
"ie": "10",
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
}
}
],
[
"@babel/preset-react",
{
"pragma": "h",
"runtime": "classic"
}
]
],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": 3,
"helpers": true,
"regenerator": true,
"useESModules": false,
"version": "7.0.0-beta.0"
}
],
["@babel/plugin-proposal-class-properties"]
]
}
15 changes: 15 additions & 0 deletions wtf-is-jsx/babel.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
@startmindmap main
* Babel
** Babel 是什么
** Babel 解决了什么问题
** Babel 的工作原理
*** Presets
**** @babel/preset-env
***** @babel/runtime
***** @babel/polyfill
****** @babel/plugin-transform-runtime
***** polyfilluseBuiltIns 配合才能自动生效,不然自能手动引入
**** @babel/preset-react
**** @babel/preset-flow
**** @babel/preset-typescript
@endmindmap
11 changes: 11 additions & 0 deletions wtf-is-jsx/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
<script src="./lib/index.js"></script>
17 changes: 17 additions & 0 deletions wtf-is-jsx/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"scripts": {
"babel": "babel src --out-dir lib"
},
"devDependencies": {
"@babel/cli": "^7.12.8",
"@babel/core": "^7.12.9",
"@babel/plugin-proposal-class-properties": "^7.13.0",
"@babel/plugin-transform-runtime": "^7.12.10",
"@babel/preset-env": "^7.12.7",
"@babel/preset-react": "^7.12.7"
},
"dependencies": {
"@babel/polyfill": "^7.12.1",
"@babel/runtime": "^7.12.5"
}
}
11 changes: 11 additions & 0 deletions wtf-is-jsx/src/demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const counter = 0;

const fn = () => 1;

Promise.resolve().finally();

async function demo() {
await Promise.resolve(1);
}

export default counter;
10 changes: 10 additions & 0 deletions wtf-is-jsx/src/es6.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class SuperClass {
#age = 20;
setAge(age) {
this.#age = age;
}
getAge() {
console.log(this.#age);
}
}
// new SuperClass().#age
34 changes: 34 additions & 0 deletions wtf-is-jsx/src/fakeIndex.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// 首先我们来看最直观的 jsx 的写法
let foo = '<div class="myDiv">Hello world</div>';
// 经过 babel 编译后会变成
// let foo = h('div', { class: 'myDov' }, 'Hello world');

// 先暂时抛开通过 抽象语法树的编译过程,直击 h 函数是如何实现的
function h(nodeName, attributes, ...args) {
return {
nodeName,
attributes,
children: args.length ? args : null
}
}

// 递归的时候要注意输入的参数形式,在此例中,如果写成
function renderE(nodeName, attributes, ...args) {
// 这种形式就会很难进行终止条件的判断
}

function render(vnode) {
if (typeof vnode === 'string') {
return document.createTextNode(vnode);
}

const n = document.createElement(vnode.nodeName);

const a = vnode.attributes || {};

Object.keys(a).forEach(k => n.setAttribute(key, a[k]));

(vnode.children || []).forEach(node => n.appendChild(render(node)));

return n;
}
42 changes: 42 additions & 0 deletions wtf-is-jsx/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// let foo = <div id="foo">Hello!</div>;
// 通过 tanspilation,会变成

// var foo = h('div', { id: 'foo' }, 'Hello!');

function h(nodeName, attributes, ...args) {
let children = args.length ? [].concat(...args) : null;
return {
nodeName,
attributes,
children,
}
}

function render(vnode) {
// Strings just convert #text Nodes.
if (vnode.split) {
return document.createTextNode(vnode);
}

// create a DOM element with the nodeName of our VDOM element.
const n = document.createElement(vnode.nodeName);

// copy attributes onto the new node
const a = vnode.attributes || {};
Object.keys(a).forEach(k => n.setAttribute(k, a[k]));

// render and then append child nodes
(vnode.children || []).forEach(c => n.appendChild(render(c)));

return n;
}

const arr = ['1', '2', '3'];

function foo(items) {
return items.map(val => <li>{val}</li>);
}

let vdom = <ul>{foo(arr)}</ul>;

document.body.appendChild(render(vdom));
3 changes: 3 additions & 0 deletions wtf-is-jsx/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import counter from './demo';

console.log(counter);

0 comments on commit 43b57ce

Please sign in to comment.