Skip to content
This repository has been archived by the owner on Aug 16, 2023. It is now read-only.

Commit

Permalink
feat(src): add createElement
Browse files Browse the repository at this point in the history
  • Loading branch information
zeromake committed Jul 14, 2017
1 parent afddb4c commit dbe3811
Show file tree
Hide file tree
Showing 14 changed files with 1,939 additions and 17 deletions.
6 changes: 6 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"presets": ["es2015"],
"plugins": [
["transform-react-jsx", { "pragma":"h" }]
]
}
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.json]
indent_size = 2
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,6 @@ typings/

# dotenv environment variables file
.env
/dist/
/test/test.js

33 changes: 22 additions & 11 deletions config/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
import rollupTypescript from 'rollup-plugin-typescript'
import uglify from 'rollup-plugin-uglify'
import { minify } from 'uglify-es'
// import uglify from 'rollup-plugin-uglify'
// import { minify } from 'uglify-es'
import pkg from '../package.json'
// import typescript from 'typescript'

const isProduction = process.env.NODE_ENV === 'production'

// set new typescript
const rollupTypescriptPlugin = rollupTypescript()
export default {
entry: 'src/index.ts',
format: 'umd',
entry: 'src/zreact.ts',
moduleName: 'Zreact',
dest: 'dist/zreact.js',
plugins: isProduction ? [
uglify({}, minify),
rollupTypescript()
]: [rollupTypescript()],
sourceMap: !isProduction
}
// dest: isProduction ? 'dist/zreact.min.js' : 'dist/zreact.js',
plugins: [rollupTypescriptPlugin],
sourceMap: !isProduction,
targets: [
{
format: 'umd',
dest: pkg.main
},
{
format: 'es',
dest: pkg.module
}
]
}
27 changes: 27 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "zreact",
"version": "0.0.1",
"description": "React mini",
"main": "dist/zreact.js",
"module": "dist/zreact.es.js",
"repository": "https://github.com/zeromake/zreact",
"author": "zeromake <a390720046@gmail.com>",
"license": "MIT",
"scripts": {
"build": "cross-env NODE_ENV=production rollup -c config/rollup.config.js",
"dev": "rollup -c config/rollup.config.js -w",
"test": "babel test/test.jsx -o test/test.js && node test/test.js"
},
"devDependencies": {
"babel-cli": "^6.24.1",
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-preset-es2015": "^6.24.1",
"cross-env": "^5.0.1",
"rimraf": "^2.6.1",
"rollup": "^0.45.2",
"rollup-plugin-typescript": "zeromake/rollup-plugin-typescript",
"rollup-watch": "^4.3.1",
"tslint": "^5.5.0",
"typescript": "^2.4.1"
}
}
96 changes: 96 additions & 0 deletions src/h.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import options from "./options";
import { VNode } from "./vnode";

// const EMPTY_CHILDREN: any[] = [];

/** JSX/hyperscript reviver
* Benchmarks: https://esbench.com/bench/57ee8f8e330ab09900a1a1a0
* 标准JSX转换函数
* @param {string} nodeName 组件或者原生dom组件名
* @param {{key: string => value: string}} attributes 组件属性
* @see http://jasonformat.com/wtf-is-jsx
* @public
*/
export function h(nodeName: string, attributes: any) {
// 初始化子元素列表
const stack: any[] = [];
const children: any[] = [];
// let i: number;
// let child: any;
// 是否为原生组件
let simple: boolean;
// 上一个子元素是否为原生组件
let lastSimple: boolean = false;
// 把剩余的函数参数全部倒序放入stack
for (let i = arguments.length; i-- > 2; ) {
stack.push(arguments[i]);
}
// 把元素上属性的children放入栈
if (attributes && attributes.children != null) {
if (!stack.length) {
stack.push(attributes.children);
}
// 删除
delete attributes.children;
}
// 把stack一次一次取出
while (stack.length) {
// 取出最后一个
let child: any = stack.pop();
if (child && child.pop !== undefined) {
// 如果是个数组就倒序放入stack
for (let i = child.length; i-- ; ) {
stack.push(child[i]);
}
} else {
// 清空布尔
if (typeof child === "boolean") {
child = null;
}
// 判断当前组件是否为自定义组件
simple = typeof nodeName !== "function";
if (simple) {
// 原生组件的子元素处理
if (child == null) {
// null to ""
child = "";
} else if (typeof child === "number") {
// num to string
child = String(child);
} else if (typeof child !== "string") {
// 不是 null,number,string 的不做处理
// 并且设置标记不是一个字符串
simple = false;
}
}
if (simple && lastSimple) {
// 当前为原生组件且子元素为字符串,并且上一个也是。
// 就把当前子元素加到上一次的后面。
children[children.length - 1] += child;
} else {
// 其它情况直接加入children
children.push(child);
}
/* else if (children === EMPTY_CHILDREN) {
children = [child];
} */
// 记录这次的子元素状态
lastSimple = simple;
}
}
const p = new VNode();
// 设置原生组件名字或自定义组件class(function)
p.nodeName = nodeName;
// 设置子元素
p.children = children;
// 设置属性
p.attributes = attributes == null ? undefined : attributes;
// 设置key
p.key = attributes == null ? undefined : attributes.key;

// vnode 钩子
if (options.vnode !== undefined) {
options.vnode(p);
}
return p;
}
Empty file removed src/index.ts
Empty file.
10 changes: 10 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { VNode } from "./vnode";

const options: {
syncComponentUpdates?: boolean;
debounceRendering?: (render: () => void) => void;
vnode?: (vnode: VNode) => void;
event?: (event: Event) => Event;
} = {};

export default options;
6 changes: 6 additions & 0 deletions src/vnode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export class VNode {
public nodeName: string;
public children: any[];
public attributes: any | undefined;
public key: any | undefined;
}
14 changes: 14 additions & 0 deletions src/zreact.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { h, h as createElement } from "./h";
import options from "./options";

export default {
createElement,
h,
options,
};

export {
createElement,
h,
options,
};
27 changes: 27 additions & 0 deletions test/test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { h } from '../dist/zreact'


class App {
render() {
return <h1>testApp</h1>
}
}

const test = {
render() {
return <div>
<App/>
{
[1, 2, 3].map(function(modeItem) {
return (<div data-options="{test: 1}">
<p>{modeItem}</p>
</div>)
})
}
</div>
}
}

console.log(test.render())

export default test;
17 changes: 11 additions & 6 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
{
"compilerOptions": {
"module": "es6",
"outDir": "build",
"sourceMap": true,
"target": "es5"
"module": "es6", // 目标代码模块方式
"outDir": "build", // 输出目录
"sourceMap": true,
"target": "es5", // 目标代码平台
"strict": true, // TS严格模式
"allowSyntheticDefaultImports": true // 使用 ES2015 默认的 imports 风格
},
"exclude": [
"node_modeles"
"node_modeles" // 不转换 node_modeles
],
"files": [
"src/zreact.ts"
]
}
}
24 changes: 24 additions & 0 deletions tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"defaultSeverity": "error",
"extends": [
"tslint:recommended"
],
"jsRules": {
"max-line-length": [120]
},
"rules": {
"max-line-length": [120],
"quotes": [
1, "single"
],
"no-console": [
"debug",
"info",
"log",
"time",
"timeEnd",
"trace"
]
},
"rulesDirectory": []
}

0 comments on commit dbe3811

Please sign in to comment.