diff --git a/.vscode/settings.json b/.vscode/settings.json
index 0676d0c..54e9289 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -9,6 +9,9 @@
"[javascript]": {
"editor.formatOnSave": true
},
+ "[markdown]": {
+ "editor.formatOnSave": true
+ },
"editor.tabSize": 2,
"editor.insertSpaces": true,
"files.associations": {
diff --git a/README-zh_CN.md b/README-zh_CN.md
index 9720c4a..0e53483 100644
--- a/README-zh_CN.md
+++ b/README-zh_CN.md
@@ -14,18 +14,18 @@ npm i @unis/core @unis/dom
## Vite 开发
-```jsx
+```shell
npm i vite @unis/vite-preset -D
```
vite.config.js
-```jsx
-import { defineConfig } from "vite"
-import { unisPreset } from "@unis/vite-preset"
+```javascript
+import { defineConfig } from "vite";
+import { unisPreset } from "@unis/vite-preset";
export default defineConfig({
- plugins: [unisPreset()]
+ plugins: [unisPreset()],
});
```
@@ -42,7 +42,7 @@ tsconfig.json
index.html
-```jsx
+```javascript
...
@@ -54,16 +54,12 @@ index.html
index.tsx
-```tsx
+```javascript
function App() {
- return () => (
-
- hello
-
- )
+ return () => hello
;
}
-render(, document.querySelector('#root'))
+render(, document.querySelector("#root"));
```
## 用法
@@ -74,110 +70,100 @@ Unis 并不是 React 的复刻,而是保留了 React 使用体验的全新框
在 unis 中组件是一个高阶函数。
-```jsx
-import { render } from '@unis/dom'
+```javascript
+import { render } from "@unis/dom";
const App = () => {
- return () => ( // 返回一个函数
-
- hello world
-
- )
-}
+ return () => (
+ // 返回一个函数
+ hello world
+ );
+};
-render(, document.querySelector('#root'))
+render(, document.querySelector("#root"));
```
### 组件状态
Unis 中的 `useState` 用法和 React 相似,但是要注意的是 unis 中 `use` 系列方法,定义类型必须为 `let` ,因为 unis 使用了 Callback Reassign 编译策略,[@callback-reassign/rollup-plugin](https://github.com/anuoua/callback-reassign) 帮我们补全了 Callback Reassign 代码。
-```jsx
-import { useState } from "@unis/core"
+```javascript
+import { useState } from "@unis/core";
const App = () => {
- let [msg, setMsg] = useState('hello')
+ let [msg, setMsg] = useState("hello");
/**
* Compile to:
- *
+ *
* let [msg, setMsg] = useState('hello', ([$0, $1]) => { msg = $0; setMsg = $1 });
*/
- return () => (
- {msg}
- )
-}
+ return () => {msg}
;
+};
```
### Props
Unis 直接使用 props 会无法获取最新值,所以 unis 提供了 useProps。
-```jsx
-import { useProps } from "@unis/core"
+```javascript
+import { useProps } from "@unis/core";
const App = (p) => {
- let { some } = useProps(p)
+ let { some } = useProps(p);
/**
* Compile to:
- *
+ *
* let { some } = useProps(p, ({ some: $0 }) => { some = $0 });
*/
- return () => (
- {some}
- )
-}
+ return () => {some}
;
+};
```
### 副作用
Unis 保留了和 React 基本一致的 `useEffect` 和 `useLayoutEffect` ,但 deps 是一个返回数组的函数。
-```jsx
-import { useEffect } from "@unis/core"
+```javascript
+import { useEffect } from "@unis/core";
const App = () => {
-
useEffect(
() => {
// ...
return () => {
// 清理...
- }
+ };
},
() => [] // deps 是一个返回数组的函数
- )
+ );
- return () => (
- hello
- )
-}
+ return () => hello
;
+};
```
### 自定义 hook
Unis 的自定义 hook ,在有返回值的场景需要搭配 `use` 方法使用,原因则是前面提到的 Callback Reassign 编译策略。自定义 hook 的命名我们约定以小写字母 `u` 开头,目的是用于区分其他函数,同时在 IDE 的提示下更加方便的导入。
-```jsx
-import { use, useState } from "@unis/core"
+```javascript
+import { use, useState } from "@unis/core";
// 创建自定义 hook 高阶函数
const uCount = () => {
- let [count, setCount] = useState(0)
- const add = () => setCount(count + 1)
- return () => [count, add]
-}
+ let [count, setCount] = useState(0);
+ const add = () => setCount(count + 1);
+ return () => [count, add];
+};
// 通过 `use` 使用 hook
function App() {
- let [count, add] = use(uCount())
+ let [count, add] = use(uCount());
/**
* Compile to:
- *
+ *
* let [count, add] = use(uCount(), ([$0, $1]) => { count = $0; add = $1 });
*/
- return () => (
- {count}
- )
+ return () => {count}
;
}
```
@@ -185,8 +171,8 @@ function App() {
### Fragment
-```jsx
-import { Fragment } from '@unis/core'
+```javascript
+import { Fragment } from "@unis/core";
function App() {
return () => (
@@ -194,45 +180,76 @@ function App() {
- )
+ );
}
```
### Portal
-```jsx
-import { createPortal } from '@unis/core'
+```javascript
+import { createPortal } from "@unis/core";
function App() {
- return () => createPortal(
- ,
- document.body
- )
+ return () => createPortal(, document.body);
}
```
### Context
-```jsx
-import { createContext } from '@unis/core'
-import { render } from '@unis/dom'
+```javascript
+import { createContext } from "@unis/core";
+import { render } from "@unis/dom";
-const ThemeContext = createContext('light')
+const ThemeContext = createContext("light");
function App() {
- let theme = useContext(ThemeContext)
-
- return () => (
- {theme}
- )
+ let theme = useContext(ThemeContext);
+
+ return () => {theme}
;
}
render(
,
- document.querySelector('#root')
-)
+ document.querySelector("#root")
+);
+```
+
+## SSR 服务端渲染
+
+服务端
+
+```javascript
+import express from "express";
+import { renderToString } from "@unis/dom/server";
+
+const app = express();
+
+app.get("/", (req, res) => {
+ const SSR_CONTENT = renderToString(hello world
);
+
+ res.send(`
+
+
+
+ ${SSR_CONTENT}
+
+
+ `);
+});
+```
+
+客户端
+
+```javascript
+import { render } from "@unis/dom";
+
+render(
+ ,
+ document.querySelector("#root"),
+ true // true 代表使用 hydrate (水合)进行渲染,复用 server 端的内容。
+);
```
## Todo 项目
@@ -245,6 +262,7 @@ render(
## API
- Core
+
- h
- h2 (for jsx2)
- Fragment
diff --git a/README.md b/README.md
index 93d749a..f508a10 100644
--- a/README.md
+++ b/README.md
@@ -2,30 +2,30 @@
-# Unis [中文](README-zh_CN.md)
+# Unis
-Unis is a simpler and easier to use front-end framework than React
+Unis is a frontend framework that is simpler and easier to use than React.
-## Install
+## Installation
```bash
-npm i @unis/unis
-````
+npm i @unis/core @unis/dom
+```
-## Vite development
+## Vite Development
-```jsx
+```shell
npm i vite @unis/vite-preset -D
-````
+```
vite.config.js
-```jsx
+```javascript
import { defineConfig } from "vite";
import { unisPreset } from "@unis/vite-preset";
export default defineConfig({
- plugins: [unisPreset()]
+ plugins: [unisPreset()],
});
```
@@ -35,14 +35,14 @@ tsconfig.json
{
"compilerOptions": {
"jsx": "react-jsx",
- "jsxImportSource": "@unis/unis"
+ "jsxImportSource": "@unis/core"
}
}
```
index.html
-```jsx
+```javascript
...
@@ -50,116 +50,112 @@ index.html
-````
+```
index.tsx
-```tsx
+```javascript
function App() {
- return () => (
-
- hello
-
- )
+ return () => hello
;
}
-render(, document.querySelector('#root'))
-````
+render(, document.querySelector("#root"));
+```
## Usage
-Unis is not a fork of React, but a brand-new framework that retains the experience of using React. The usage of Unis is very simple, and those familiar with React can get started quickly.
+Unis is not a replica of React, but a brand new framework that retains the user experience of React. Unis is easy to use, and those who are familiar with React can quickly get started.
### Components
-A component in unis is a higher-order function.
+In Unis, the component is a higher-order function.
-```jsx
-import { render } from '@unis/unis'
+```javascript
+import { render } from "@unis/dom";
const App = () => {
- return () => ( // return a function
-
- hello world
-
- )
-}
+ return () => (
+ // Returns a function
+ hello world
+ );
+};
-render(, document.querySelector('#root'))
-````
+render(, document.querySelector("#root"));
+```
### Component State
-The usage of `useState` in Unis is similar to that of React, but it should be noted that for the `use` series methods in unis, the definition type must be `let`, because unis uses the Callback Reassign compilation strategy, and rollup-plugin-reassign helps us complete it Callback Reassign code.
+The usage of `useState` in Unis is similar to React, but it should be noted that for the `use` method series in Unis, the defined type must be `let`. This is because Unis uses the Callback Reassign compilation strategy, and [@callback-reassign/rollup-plugin](https://github.com/anuoua/callback-reassign) helps us complete the Callback Reassign code.
+
+```javascript
+import { useState } from "@unis/core";
-```jsx
const App = () => {
- let [msg, setMsg] = useState('hello');
+ let [msg, setMsg] = useState("hello");
/**
* Compile to:
*
* let [msg, setMsg] = useState('hello', ([$0, $1]) => { msg = $0; setMsg = $1 });
*/
- return () => (
- {msg}
- )
-}
-````
+ return () => {msg}
;
+};
+```
### Props
-Unis will not be able to get the latest value when using props directly, so unis provides useProps.
+Directly using `props` in Unis will be unable to get the latest value, so Unis provides `useProps`.
+
+```javascript
+import { useProps } from "@unis/core";
-```jsx
const App = (p) => {
- let { some } = useProps(p)
+ let { some } = useProps(p);
/**
* Compile to:
*
* let { some } = useProps(p, ({ some: $0 }) => { some = $0 });
*/
- return () => (
- {some}
- )
-}
-````
+ return () => {some}
;
+};
+```
-### Side effect
+### Side Effects
-Unis keeps `useEffect` and `useLayoutEffect` basically the same as React, but deps is a function that returns an array.
+Unis retains the familiar `useEffect` and `useLayoutEffect` methods from React, but the `deps` parameter is a function that returns an array.
-```jsx
-const App = () => {
+```javascript
+import { useEffect } from "@unis/core";
+const App = () => {
useEffect(
() => {
// ...
- return() => {
- // clean up...
- }
+ return () => {
+ // Clean up...
+ };
},
() => [] // deps is a function that returns an array
- )
+ );
- return () => (
- hello
- )
-}
-````
+ return () => hello
;
+};
+```
+
+### Custom Hook
-### Custom hook
+For Unis' custom hooks that have a return value, the `use` method should be used accordingly, due to the Callback Reassign compilation strategy mentioned earlier. We conventionally name custom hooks with a lowercase `u` at the beginning, to differentiate them from other functions and make them easy to import with IDE hints.
-The custom hook of Unis needs to be used with the `use` method in scenarios with return values, because of the Callback Reassign compilation strategy mentioned above. The naming convention of custom hooks starts with a lowercase letter `u`, which is used to distinguish other functions, and at the same time, it is more convenient to import at the prompt of IDE.
+```javascript
+import { use, useState } from "@unis/core";
-```jsx
-// Create custom hook higher-order function
+// Create a higher-order function for the custom hook
const uCount = () => {
let [count, setCount] = useState(0);
const add = () => setCount(count + 1);
- return () => [count, add]
-}
+ return () => [count, add];
+};
-// use hook via `use`
+// Use the hook through `use`
function App() {
let [count, add] = use(uCount());
/**
@@ -167,18 +163,16 @@ function App() {
*
* let [count, add] = use(uCount(), ([$0, $1]) => { count = $0; add = $1 });
*/
- return () => (
- {count}
- )
+ return () => {count}
;
}
-````
+```
## Features
### Fragment
-```jsx
-import { Fragment } from '@unis/unis'
+```javascript
+import { Fragment } from "@unis/core";
function App() {
return () => (
@@ -186,60 +180,92 @@ function App() {
- )
+ );
}
-````
+```
### Portal
-```jsx
-import { createPortal } from '@unis/unis'
+```javascript
+import { createPortal } from "@unis/core";
function App() {
- return () => createPortal(
- ,
- document.body
- )
+ return () => createPortal(, document.body);
}
-````
+```
### Context
-```jsx
-import { createContext, render } from '@unis/unis'
+```javascript
+import { createContext } from "@unis/core";
+import { render } from "@unis/dom";
-const ThemeContext = createContext('light')
+const ThemeContext = createContext("light");
function App() {
- let theme = useContext(ThemeContext)
-
- return () => (
- {theme}
- )
+ let theme = useContext(ThemeContext);
+
+ return () => {theme}
;
}
render(
,
- document.querySelector('#root')
-)
-````
+ document.querySelector("#root")
+);
+```
+
+## Server-Side Rendering
+
+Server
+
+```javascript
+import express from "express";
+import { renderToString } from "@unis/dom/server";
+
+const app = express();
+
+app.get("/", (req, res) => {
+ const SSR_CONTENT = renderToString(hello world
);
+
+ res.send(`
+
+
+
+ ${SSR_CONTENT}
+
+
+ `);
+});
+```
+
+Client
+
+```javascript
+import { render } from "@unis/dom";
+
+render(
+ ,
+ document.querySelector("#root"),
+ true // true means using hydration to render and reuse the server-side rendered content.
+);
+```
## Todo Project
-Check out the full project
+See complete project at
- [packages/unis-example](packages/unis-example) Todo example
-- [stackbliz](https://stackblitz.com/edit/vitejs-vite-4cfy2b) Trial
+- [stackbliz](https://stackblitz.com/edit/vitejs-vite-8hn3pz) Try it out
## API
- Core
+
- h
- h2 (for jsx2)
- Fragment
- - FGMT: it is Fragment alias, will be removed when vite support `jsxImportSource`
- createPortal
- createContext
- render