{"id":13561123,"url":"https://github.com/anuoua/unis","last_synced_at":"2025-04-07T11:03:57.658Z","repository":{"id":40389877,"uuid":"420155471","full_name":"anuoua/unis","owner":"anuoua","description":"Unis is a new front-end framework. Its innovative compilation strategy and component API built help you create web UI more easily.","archived":false,"fork":false,"pushed_at":"2023-06-07T08:06:03.000Z","size":1606,"stargazers_count":231,"open_issues_count":0,"forks_count":7,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-03-31T10:11:13.074Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/anuoua.png","metadata":{"files":{"readme":"README-zh_CN.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-10-22T15:45:21.000Z","updated_at":"2025-01-22T09:40:23.000Z","dependencies_parsed_at":"2024-01-14T03:02:36.275Z","dependency_job_id":"e72de560-cb89-4298-af40-68c3abd91d3c","html_url":"https://github.com/anuoua/unis","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anuoua%2Funis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anuoua%2Funis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anuoua%2Funis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anuoua%2Funis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anuoua","download_url":"https://codeload.github.com/anuoua/unis/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247640459,"owners_count":20971557,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T13:00:52.739Z","updated_at":"2025-04-07T11:03:57.628Z","avatar_url":"https://github.com/anuoua.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg height=\"300\" src=\"./assets/logo.svg\"\u003e\n\u003c/p\u003e\n\n[![@unis/core CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-core.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-core.yml) [![@unis/dom CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-dom.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-dom.yml) [![@unis/router CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-router.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-router.yml) [![@unis/transition CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-transition.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-transition.yml) [![@unis/vite-preset CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-vite-preset.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-vite-preset.yml) [![@unis/babel-preset CI/CD](https://github.com/anuoua/unis/actions/workflows/unis-babel-preset.yml/badge.svg)](https://github.com/anuoua/unis/actions/workflows/unis-babel-preset.yml)\n\n# Unis\n\nUnis 是一款新的前端框架，创新的编译策略打造的组件 API 帮助你更加轻松的创建网页 UI。\n\n## 性能\n\n\u003cimg height=\"500\" src=\"./assets/bench.png\"\u003e\n\n## 安装\n\n```bash\nnpm i @unis/core @unis/dom\n```\n\n## Vite 开发\n\n```shell\nnpm i vite @unis/vite-preset -D\n```\n\nvite.config.js\n\n```javascript\nimport { defineConfig } from \"vite\";\nimport { unisPreset } from \"@unis/vite-preset\";\n\nexport default defineConfig({\n  plugins: [unisPreset()],\n});\n```\n\ntsconfig.json\n\n```json\n{\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"jsxImportSource\": \"@unis/core\"\n  }\n}\n```\n\nindex.html\n\n```javascript\n\u003chtml\u003e\n  ...\n  \u003cbody\u003e\n    \u003cdiv id=\"root\"\u003e\u003c/div\u003e\n    \u003cscript type=\"module\" src=\"./index.tsx\"\u003e\u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\nindex.tsx\n\n```javascript\nfunction App() {\n  return () =\u003e \u003cdiv\u003ehello\u003c/div\u003e;\n}\n\nrender(\u003cApp /\u003e, document.querySelector(\"#root\"));\n```\n\n## 用法\n\nUnis 并不是 React 的复刻，而是保留了 React 使用体验的全新框架，unis 的用法很简单，熟悉 React 的可以很快上手。\n\n### 组件\n\n在 unis 中组件是一个高阶函数。\n\n```javascript\nimport { render } from \"@unis/dom\";\n\nconst App = () =\u003e {\n  return () =\u003e (\n    // 返回一个函数\n    \u003cdiv\u003ehello world\u003c/div\u003e\n  );\n};\n\nrender(\u003cApp /\u003e, document.querySelector(\"#root\"));\n```\n\n### 组件状态\n\nUnis 中的 `useState` 用法和 React 相似，但是要注意的是 unis 中 `use` 系列方法，定义类型必须为 `let` ，因为 unis 使用了 Callback Reassign 编译策略，[@callback-reassign/rollup-plugin](https://github.com/anuoua/callback-reassign) 帮我们补全了 Callback Reassign 代码。\n\n```javascript\nimport { useState } from \"@unis/core\";\n\nconst App = () =\u003e {\n  let [msg, setMsg] = useState(\"hello\");\n  /**\n   * Compile to:\n   *\n   * let [msg, setMsg] = useState('hello', ([$0, $1]) =\u003e { msg = $0; setMsg = $1 });\n   */\n  return () =\u003e \u003cdiv\u003e{msg}\u003c/div\u003e;\n};\n```\n\n### Props\n\nUnis 直接使用 props 会无法获取最新值，所以 unis 提供了 useProps。\n\n```javascript\nimport { useProps } from \"@unis/core\";\n\nconst App = (p) =\u003e {\n  let { some } = useProps(p);\n  /**\n   * Compile to:\n   *\n   * let { some } = useProps(p, ({ some: $0 }) =\u003e { some = $0 });\n   */\n  return () =\u003e \u003cdiv\u003e{some}\u003c/div\u003e;\n};\n```\n\n### 副作用\n\nUnis 保留了和 React 基本一致的 `useEffect` 和 `useLayoutEffect` ，但 deps 是一个返回数组的函数。\n\n```javascript\nimport { useEffect } from \"@unis/core\";\n\nconst App = () =\u003e {\n  useEffect(\n    () =\u003e {\n      // ...\n      return () =\u003e {\n        // 清理...\n      };\n    },\n    () =\u003e [] // deps 是一个返回数组的函数\n  );\n\n  return () =\u003e \u003cdiv\u003ehello\u003c/div\u003e;\n};\n```\n\n### 自定义 hook\n\nUnis 的自定义 hook ，在有返回值的场景需要搭配 `use` 方法使用，原因则是前面提到的 Callback Reassign 编译策略。自定义 hook 的命名我们约定以小写字母 `u` 开头，目的是用于区分其他函数，同时在 IDE 的提示下更加方便的导入。\n\n```javascript\nimport { use, useState } from \"@unis/core\";\n\n// 创建自定义 hook 高阶函数\nconst uCount = () =\u003e {\n  let [count, setCount] = useState(0);\n  const add = () =\u003e setCount(count + 1);\n  return () =\u003e [count, add];\n};\n\n// 通过 `use` 使用 hook\nfunction App() {\n  let [count, add] = use(uCount());\n  /**\n   * Compile to:\n   *\n   * let [count, add] = use(uCount(), ([$0, $1]) =\u003e { count = $0; add = $1 });\n   */\n  return () =\u003e \u003cdiv onClick={add}\u003e{count}\u003c/div\u003e;\n}\n```\n\n## 特性\n\n### Fragment\n\n```javascript\nimport { Fragment } from \"@unis/core\";\n\nfunction App() {\n  return () =\u003e (\n    \u003cFragment\u003e\n      \u003cdiv\u003e\u003c/div\u003e\n      \u003cspan\u003e\u003c/span\u003e\n    \u003c/Fragment\u003e\n  );\n}\n```\n\n### Portal\n\n```javascript\nimport { createPortal } from \"@unis/core\";\n\nfunction App() {\n  return () =\u003e createPortal(\u003cdiv\u003e\u003c/div\u003e, document.body);\n}\n```\n\n### Context\n\n```javascript\nimport { createContext } from \"@unis/core\";\nimport { render } from \"@unis/dom\";\n\nconst ThemeContext = createContext(\"light\");\n\nfunction App() {\n  let theme = useContext(ThemeContext);\n\n  return () =\u003e \u003cdiv\u003e{theme}\u003c/div\u003e;\n}\n\nrender(\n  \u003cThemeContext.Provider value=\"dark\"\u003e\n    \u003cApp /\u003e\n  \u003c/ThemeContext.Provider\u003e,\n  document.querySelector(\"#root\")\n);\n```\n\n## SSR 服务端渲染\n\n服务端\n\n```javascript\nimport express from \"express\";\nimport { renderToString } from \"@unis/dom/server\";\n\nconst app = express();\n\napp.get(\"/\", (req, res) =\u003e {\n  const SSR_CONTENT = renderToString(\u003cdiv\u003ehello world\u003c/div\u003e);\n\n  res.send(`\n    \u003chtml\u003e\n      \u003cheader\u003e...\u003c/header\u003e\n      \u003cbody\u003e\n        \u003cdiv id=\"root\"\u003e${SSR_CONTENT}\u003c/div\u003e\n      \u003c/body\u003e\n    \u003c/html\u003e\n  `);\n});\n```\n\n客户端\n\n```javascript\nimport { render } from \"@unis/dom\";\n\nrender(\n  \u003cApp /\u003e,\n  document.querySelector(\"#root\"),\n  true // true 代表使用 hydrate （水合）进行渲染，复用 server 端的内容。\n);\n```\n\n## Todo 项目\n\n完整项目请查看\n\n- [packages/unis-example](packages/unis-example) Todo 示例\n- [stackbliz](https://stackblitz.com/edit/vitejs-vite-8hn3pz) 试用\n\n## API\n\n- Core\n\n  - h\n  - h2 (for jsx2)\n  - Fragment\n  - createPortal\n  - createContext\n  - render\n  - memo\n\n- Hooks\n  - use\n  - useProps\n  - useState\n  - useReducer\n  - useContext\n  - useMemo\n  - useEffect\n  - useRef\n  - useId\n\n## License\n\nMIT @anuoua\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanuoua%2Funis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanuoua%2Funis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanuoua%2Funis/lists"}