Compare commits
74 Commits
openinula-
...
master
Author | SHA1 | Date |
---|---|---|
|
68ad2d3e9c | |
|
70f7bb3f51 | |
|
540c8d582b | |
|
002dc545c2 | |
|
9f1d2fbc56 | |
|
9f5c9bb370 | |
|
af32cb79f9 | |
|
fbc9c11946 | |
|
2047bb27db | |
|
847fbd5bc0 | |
|
d488477ca3 | |
|
c901b953c5 | |
|
22772af364 | |
|
f295549122 | |
|
2c2c3926e7 | |
|
ecaaacb812 | |
|
6688cde7ab | |
|
8a7623d281 | |
|
0375ed95fc | |
|
4a825cec88 | |
|
aa4984f997 | |
|
78f4bce57c | |
|
ebfe1eceb9 | |
|
ec34490202 | |
|
eb5cb8237b | |
|
b1b2224c6b | |
|
3ad82f5fe4 | |
|
37dfbb1dff | |
|
63b82c2632 | |
|
c8d0ef933c | |
|
98ca7531c9 | |
|
a3f7709c90 | |
|
7f4eae3127 | |
|
f295f25176 | |
|
22b05d908a | |
|
0903248e2f | |
|
80e22da1ec | |
|
ab1c68de6b | |
|
7c126dd857 | |
|
c3e3007aa6 | |
|
6dc8d0fcfa | |
|
0ac8ab0b6c | |
|
cb01814a27 | |
|
b0f765f798 | |
|
e336483157 | |
|
c9bb4c07de | |
|
b4bbd146e8 | |
|
74a54ceb61 | |
|
95f658a6e5 | |
|
f4d21f69a4 | |
|
444b73f7ec | |
|
c1de5906a9 | |
|
b026ca8786 | |
|
210baeec9f | |
|
b6017e6194 | |
|
3bebf5280e | |
|
32e509f9de | |
|
b2a08e8c6c | |
|
d5780d248d | |
|
d44a968798 | |
|
9a53bbbe54 | |
|
0cfcc3c437 | |
|
81235e6276 | |
|
6595eb7044 | |
|
75bed609fe | |
|
efd914a426 | |
|
955b2cb574 | |
|
fb3180f2f2 | |
|
925a6de0e2 | |
|
b4ba997e72 | |
|
ee784d80cd | |
|
4785c3092c | |
|
949d059816 | |
|
706a904856 |
|
@ -1,3 +1,3 @@
|
||||||
**/node_modules
|
**/node_modules
|
||||||
build/
|
**/build/
|
||||||
*.d.ts
|
*.d.ts
|
||||||
|
|
|
@ -22,7 +22,7 @@ module.exports = {
|
||||||
],
|
],
|
||||||
root: true,
|
root: true,
|
||||||
|
|
||||||
plugins: ['jest', 'no-for-of-loops', 'no-function-declare-after-return', 'react', '@typescript-eslint'],
|
plugins: ['jest', 'no-function-declare-after-return', 'react', '@typescript-eslint'],
|
||||||
|
|
||||||
parser: '@typescript-eslint/parser',
|
parser: '@typescript-eslint/parser',
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
|
@ -56,8 +56,8 @@ module.exports = {
|
||||||
'comma-dangle': ['error', 'only-multiline'],
|
'comma-dangle': ['error', 'only-multiline'],
|
||||||
|
|
||||||
'no-constant-condition': 'off',
|
'no-constant-condition': 'off',
|
||||||
'no-for-of-loops/no-for-of-loops': 'error',
|
|
||||||
'no-function-declare-after-return/no-function-declare-after-return': 'error',
|
'no-function-declare-after-return/no-function-declare-after-return': 'error',
|
||||||
|
'@typescript-eslint/ban-ts-comment': 'warn'
|
||||||
},
|
},
|
||||||
globals: {
|
globals: {
|
||||||
isDev: true,
|
isDev: true,
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
**关联的 Issues:** [请列出与此 PR 相关的 issue 编号]
|
**关联的 Issues:** [请列出与此 PR 相关的 issue 编号]
|
||||||
|
|
||||||
**检查项(无需修改,提交后界面上可勾选):**
|
**检查项(无需修改,提交后界面上可勾选):**
|
||||||
- [ ] 代码已经被检视
|
- [ ] 代码已经被审查
|
||||||
- [ ] 代码符合项目的代码标准和最佳实践
|
- [ ] 代码符合项目的代码标准和最佳实践
|
||||||
- [ ] 代码已经通过所有测试用例
|
- [ ] 代码已经通过所有测试用例
|
||||||
- [ ] 代码不影响现有功能的正常使用
|
- [ ] 代码不影响现有功能的正常使用
|
||||||
|
|
|
@ -5,3 +5,7 @@ package-lock.json
|
||||||
pnpm-lock.yaml
|
pnpm-lock.yaml
|
||||||
/packages/**/node_modules
|
/packages/**/node_modules
|
||||||
/packages/inula-cli/lib
|
/packages/inula-cli/lib
|
||||||
|
build
|
||||||
|
/packages/inula-router/connectRouter
|
||||||
|
/packages/inula-router/router
|
||||||
|
.inula-max
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
. "$(dirname -- "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
npm run commitlint
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
. "$(dirname -- "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
npm run lint-commit
|
|
@ -0,0 +1,3 @@
|
||||||
|
**/build
|
||||||
|
*.md
|
||||||
|
*.html
|
|
@ -16,17 +16,17 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
printWidth: 120, // 一行120字符数,如果超过会进行换行
|
printWidth: 120, // 一行120字符数,如果超过会进行换行
|
||||||
tabWidth: 2, // tab等2个空格
|
tabWidth: 2, // tab等2个空格
|
||||||
useTabs: false, // 用空格缩进行
|
useTabs: false, // 用空格缩进行
|
||||||
semi: true, // 行尾使用分号
|
semi: true, // 行尾使用分号
|
||||||
singleQuote: true, // 字符串使用单引号
|
singleQuote: true, // 字符串使用单引号
|
||||||
quoteProps: 'as-needed', // 仅在需要时在对象属性添加引号
|
quoteProps: 'as-needed', // 仅在需要时在对象属性添加引号
|
||||||
jsxSingleQuote: false, // 在JSX中使用双引号
|
jsxSingleQuote: false, // 在JSX中使用双引号
|
||||||
trailingComma: 'es5', // 使用尾逗号(对象、数组等)
|
trailingComma: 'es5', // 使用尾逗号(对象、数组等)
|
||||||
bracketSpacing: true, // 对象的括号间增加空格
|
bracketSpacing: true, // 对象的括号间增加空格
|
||||||
bracketSameLine: false, // 将多行JSX元素的>放在最后一行的末尾
|
bracketSameLine: false, // 将多行JSX元素的>放在最后一行的末尾
|
||||||
arrowParens: 'avoid', // 在唯一的arrow函数参数周围省略括号
|
arrowParens: 'avoid', // 在唯一的arrow函数参数周围省略括号
|
||||||
vueIndentScriptAndStyle: false, // 不缩进Vue文件中的<script>和<style>标记内的代码
|
vueIndentScriptAndStyle: false, // 不缩进Vue文件中的<script>和<style>标记内的代码
|
||||||
endOfLine: 'lf', // 仅限换行(\n)
|
endOfLine: 'auto', // 仅限换行(\n)
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
version: '1.0'
|
||||||
|
name: branch-pipeline
|
||||||
|
displayName: BranchPipeline
|
||||||
|
stages:
|
||||||
|
- stage:
|
||||||
|
name: compile
|
||||||
|
displayName: 编译
|
||||||
|
steps:
|
||||||
|
- step: build@nodejs
|
||||||
|
name: build_nodejs
|
||||||
|
displayName: Nodejs 构建
|
||||||
|
# 支持8.16.2、10.17.0、12.16.1、14.16.0、15.12.0五个版本
|
||||||
|
nodeVersion: 14.16.0
|
||||||
|
# 构建命令:安装依赖 -> 清除上次打包产物残留 -> 执行构建 【请根据项目实际产出进行填写】
|
||||||
|
commands:
|
||||||
|
- npm install && rm -rf ./dist && npm run build
|
||||||
|
# 非必填字段,开启后表示将构建产物暂存,但不会上传到制品库中,7天后自动清除
|
||||||
|
artifacts:
|
||||||
|
# 构建产物名字,作为产物的唯一标识可向下传递,支持自定义,默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址
|
||||||
|
- name: BUILD_ARTIFACT
|
||||||
|
# 构建产物获取路径,是指代码编译完毕之后构建物的所在路径
|
||||||
|
path:
|
||||||
|
- ./dist
|
||||||
|
- step: publish@general_artifacts
|
||||||
|
name: publish_general_artifacts
|
||||||
|
displayName: 上传制品
|
||||||
|
# 上游构建任务定义的产物名,默认BUILD_ARTIFACT
|
||||||
|
dependArtifact: BUILD_ARTIFACT
|
||||||
|
# 上传到制品库时的制品命名,默认output
|
||||||
|
artifactName: output
|
||||||
|
dependsOn: build_nodejs
|
||||||
|
- stage:
|
||||||
|
name: release
|
||||||
|
displayName: 发布
|
||||||
|
steps:
|
||||||
|
- step: publish@release_artifacts
|
||||||
|
name: publish_release_artifacts
|
||||||
|
displayName: '发布'
|
||||||
|
# 上游上传制品任务的产出
|
||||||
|
dependArtifact: output
|
||||||
|
# 发布制品版本号
|
||||||
|
version: '1.0.0.0'
|
||||||
|
# 是否开启版本号自增,默认开启
|
||||||
|
autoIncrement: true
|
||||||
|
triggers:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
exclude:
|
||||||
|
- master
|
||||||
|
include:
|
||||||
|
- .*
|
|
@ -0,0 +1,49 @@
|
||||||
|
version: '1.0'
|
||||||
|
name: master-pipeline
|
||||||
|
displayName: MasterPipeline
|
||||||
|
stages:
|
||||||
|
- stage:
|
||||||
|
name: compile
|
||||||
|
displayName: 编译
|
||||||
|
steps:
|
||||||
|
- step: build@nodejs
|
||||||
|
name: build_nodejs
|
||||||
|
displayName: Nodejs 构建
|
||||||
|
# 支持8.16.2、10.17.0、12.16.1、14.16.0、15.12.0五个版本
|
||||||
|
nodeVersion: 14.16.0
|
||||||
|
# 构建命令:安装依赖 -> 清除上次打包产物残留 -> 执行构建 【请根据项目实际产出进行填写】
|
||||||
|
commands:
|
||||||
|
- npm install && rm -rf ./dist && npm run build
|
||||||
|
# 非必填字段,开启后表示将构建产物暂存,但不会上传到制品库中,7天后自动清除
|
||||||
|
artifacts:
|
||||||
|
# 构建产物名字,作为产物的唯一标识可向下传递,支持自定义,默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址
|
||||||
|
- name: BUILD_ARTIFACT
|
||||||
|
# 构建产物获取路径,是指代码编译完毕之后构建物的所在路径
|
||||||
|
path:
|
||||||
|
- ./dist
|
||||||
|
- step: publish@general_artifacts
|
||||||
|
name: publish_general_artifacts
|
||||||
|
displayName: 上传制品
|
||||||
|
# 上游构建任务定义的产物名,默认BUILD_ARTIFACT
|
||||||
|
dependArtifact: BUILD_ARTIFACT
|
||||||
|
# 上传到制品库时的制品命名,默认output
|
||||||
|
artifactName: output
|
||||||
|
dependsOn: build_nodejs
|
||||||
|
- stage:
|
||||||
|
name: release
|
||||||
|
displayName: 发布
|
||||||
|
steps:
|
||||||
|
- step: publish@release_artifacts
|
||||||
|
name: publish_release_artifacts
|
||||||
|
displayName: '发布'
|
||||||
|
# 上游上传制品任务的产出
|
||||||
|
dependArtifact: output
|
||||||
|
# 发布制品版本号
|
||||||
|
version: '1.0.0.0'
|
||||||
|
# 是否开启版本号自增,默认开启
|
||||||
|
autoIncrement: true
|
||||||
|
triggers:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
include:
|
||||||
|
- master
|
|
@ -0,0 +1,36 @@
|
||||||
|
version: '1.0'
|
||||||
|
name: pr-pipeline
|
||||||
|
displayName: PRPipeline
|
||||||
|
stages:
|
||||||
|
- stage:
|
||||||
|
name: compile
|
||||||
|
displayName: 编译
|
||||||
|
steps:
|
||||||
|
- step: build@nodejs
|
||||||
|
name: build_nodejs
|
||||||
|
displayName: Nodejs 构建
|
||||||
|
# 支持8.16.2、10.17.0、12.16.1、14.16.0、15.12.0五个版本
|
||||||
|
nodeVersion: 14.16.0
|
||||||
|
# 构建命令:安装依赖 -> 清除上次打包产物残留 -> 执行构建 【请根据项目实际产出进行填写】
|
||||||
|
commands:
|
||||||
|
- npm install && rm -rf ./dist && npm run build
|
||||||
|
# 非必填字段,开启后表示将构建产物暂存,但不会上传到制品库中,7天后自动清除
|
||||||
|
artifacts:
|
||||||
|
# 构建产物名字,作为产物的唯一标识可向下传递,支持自定义,默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址
|
||||||
|
- name: BUILD_ARTIFACT
|
||||||
|
# 构建产物获取路径,是指代码编译完毕之后构建物的所在路径
|
||||||
|
path:
|
||||||
|
- ./dist
|
||||||
|
- step: publish@general_artifacts
|
||||||
|
name: publish_general_artifacts
|
||||||
|
displayName: 上传制品
|
||||||
|
# 上游构建任务定义的产物名,默认BUILD_ARTIFACT
|
||||||
|
dependArtifact: BUILD_ARTIFACT
|
||||||
|
# 上传到制品库时的制品命名,默认output
|
||||||
|
artifactName: output
|
||||||
|
dependsOn: build_nodejs
|
||||||
|
triggers:
|
||||||
|
pr:
|
||||||
|
branches:
|
||||||
|
include:
|
||||||
|
- master
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Inula Contributing Guide
|
||||||
|
|
||||||
|
查看[贡献指南](https://docs.openinula.net/docs/%E8%B4%A1%E7%8C%AE%E6%8C%87%E5%8D%97)获取完整指南。
|
73
README.md
73
README.md
|
@ -6,68 +6,73 @@
|
||||||
|
|
||||||
## 技术架构
|
## 技术架构
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### 核心能力
|
## 核心能力
|
||||||
|
|
||||||
#### 响应式API(实验性功能,可在reactive分支查看代码或使用npm仓中experiment版本体验)
|
### 响应式API
|
||||||
|
|
||||||
* openInula 通过最小化重新渲染的范围,从而进行高效的UI渲染。这种方式避免了虚拟 DOM 的开销,使得 openInula 在性能方面表现出色。
|
openInula 通过监听状态变量的变化,以细粒度的依赖追踪机制来实现响应式更新,避免了虚拟 DOM 的开销。通过最小化重新渲染的范围,从而进行高效的UI渲染。无需用户过度关注性能优化。
|
||||||
* openInula 通过比较变化前后的 JavaScript 对象以细粒度的依赖追踪机制来实现响应式更新,无需用户过度关注性能优化。
|
|
||||||
* 简洁API:
|
|
||||||
1. openInula 提供了两组简洁直观的API--响应式 API 和与 React 一致的传统 API,使得开发者可以轻松地构建复杂的交互式界面。
|
|
||||||
2. openInula 简洁的 API 极大降低了开发者的学习成本,开发者使用响应式API可以快速构建高效的前端界面。
|
|
||||||
|
|
||||||
#### 兼容 ReactAPI
|
>(实验性功能,可在 `reactive` 分支查看代码或使用 npm 仓中 experimental 版本体验)
|
||||||
|
|
||||||
* 与React保持一致、可以无缝支持 React 生态。
|
### 兼容 React API
|
||||||
* 使用传统 API 可以无缝将 React 项目切换至 openInula,React 应用可零修改切换至 openInula。
|
|
||||||
|
提供与 React 一致的 API,完全支持 React 生态,可将 React 应用可零修改切换至 openInula。
|
||||||
|
|
||||||
### openInula 配套组件
|
### openInula 配套组件
|
||||||
|
|
||||||
#### 状态管理器 → inula-X
|
#### 状态管理器 inula-X
|
||||||
|
|
||||||
|
inula-X 是 openInula 默认提供的状态管理器。无需额外引入三方库,就可以简单实现跨组件/页面共享状态。
|
||||||
|
|
||||||
inula-X 是 openInula 默认提供的状态管理器,无需额外引入三方库,就可以简单实现跨组件/页面共享状态。
|
|
||||||
inula-X 与 Redux 相比,可创建多个 Store,不需要在 Reducer 中返回 state 并且简化了 Action 和 Reducer 的创建步骤,原生支持异步能力,组件能做到精准重渲染。inula-X 均可使用函数组件、class 组件,能提供 redux 的适配接口及支持响应式的特点。
|
inula-X 与 Redux 相比,可创建多个 Store,不需要在 Reducer 中返回 state 并且简化了 Action 和 Reducer 的创建步骤,原生支持异步能力,组件能做到精准重渲染。inula-X 均可使用函数组件、class 组件,能提供 redux 的适配接口及支持响应式的特点。
|
||||||
|
|
||||||
#### 路由 → inula-router
|
#### 路由 inula-router
|
||||||
|
|
||||||
inula-router 是 openInula 生态组建的一部分,为 openInula 提供前端路由的能力,是构建大型应用必要组件。
|
inula-router 为 openInula 提供前端路由的能力,是构建大型应用必要组件,涵盖 react-router、history、connect-react-router 的功能。
|
||||||
inula-router 涵盖 react-router、history、connect-react-router 的功能。
|
|
||||||
|
|
||||||
#### 请求 → inula-request
|
#### 请求 inula-request
|
||||||
|
|
||||||
inula-request 是 openInula 生态组件,涵盖常见的网络请求方式,并提供动态轮询钩子函数给用户更便捷的定制化请求体验。
|
inula-request 是 openInula 的网络请求组件,不仅涵盖常见的网络请求方式,还提供动态轮询钩子函数给用户更便捷的定制化请求体验。
|
||||||
|
|
||||||
#### 国际化 → inula-intl
|
#### 国际化 inula-intl
|
||||||
|
|
||||||
inula-intl 是基于 openInula 生态组件,其主要提供了国际化功能,涵盖了基本的国际化组件和钩子函数,便于用户在构建国际化能力时方便操作。
|
inula-intl 是基于 openInula 的国际化组件,涵盖了基本的国际化组件和钩子函数,允许用户更方便地构建国际化能力。
|
||||||
|
|
||||||
#### 调试工具 → inula-dev-tools
|
#### 调试工具 inula-dev-tools
|
||||||
|
|
||||||
inula-dev-tools 是一个为 openInula 开发者提供的强大工具集,能够方便地查看和编辑组件树、管理应用状态以及进行性能分析,极大提高了开发效率和诊断问题的便捷性。
|
inula-dev-tools 是一个为 openInula 开发者提供的强大工具集,能够方便地查看和编辑组件树、管理应用状态以及进行性能分析,极大提高了开发效率和诊断问题的便捷性。
|
||||||
|
|
||||||
#### 脚手架 → inula-cli
|
#### 脚手架 create-inula
|
||||||
|
|
||||||
inula-cli 是一套针对 openInula 的编译期插件,它支持代码优化、JSX 语法转换以及代码分割,有助于提高应用的性能、可读性和可维护性。
|
create-inula 是一套用于创建 openInula 项目的脚手架工具。它预置了一系列项目模板,允许开发者通过命令行按需快速生成可运行的项目代码。
|
||||||
|
|
||||||
## openInula 文档
|
## 参与贡献
|
||||||
|
|
||||||
|
我们鼓励开发者以各种方式参与代码贡献、生态拓展或文档反馈,献您的原创内容,详细请参考[贡献指南](https://docs.openinula.net/docs/%E8%B4%A1%E7%8C%AE%E6%8C%87%E5%8D%97)。
|
||||||
|
|
||||||
|
### 官方链接
|
||||||
|
|
||||||
欢迎访问 openInula 官网与文档仓库,参与 openInula 开发者文档开源项目,与我们一起完善开发者文档。
|
欢迎访问 openInula 官网与文档仓库,参与 openInula 开发者文档开源项目,与我们一起完善开发者文档。
|
||||||
|
|
||||||
+ openInula 官网地址:[https://www.openinula.net/](https://www.openinula.net/)
|
* openInula 官网:[https://www.openinula.net/](https://www.openinula.net/)
|
||||||
+ openInula 文档站地址:[https://docs.openinula.net/](https://docs.openinula.net/)
|
* openInula 文档:[https://docs.openinula.net/](https://docs.openinula.net/)
|
||||||
|
* openInula 仓库地址:[https://gitee.com/openinula/inula](https://gitee.com/openinula/inula)
|
||||||
|
* openInula 社提案备忘录(RFC):[https://gitee.com/openInula/rfcs](https://gitee.com/openInula/rfcs)
|
||||||
|
|
||||||
## 代码仓地址
|
### 社区贡献者案例
|
||||||
|
|
||||||
openInula 仓库地址:[https://gitee.com/openinula](https://gitee.com/openinula)
|
**[`umi-inula`](https://gitee.com/congxiaochen/inula)**
|
||||||
|
|
||||||
## 如何参与
|
基于 umijs 与 openInula 的开发框架,集成官方组件与UI、AIGC等功能,开箱即用。
|
||||||
|
|
||||||
**参与贡献**
|
**[`VoerkaI18n`](https://github.com/zhangfisher/voerka-i18n/)**
|
||||||
欢迎您参与贡献,我们鼓励开发者以各种方式参与文档反馈和贡献。
|
|
||||||
|
|
||||||
您可以对现有文档进行评价、简单更改、反馈文档质量问题、贡献您的原创内容,详细请参考[贡献指南](https://docs.openinula.net/docs/%E8%B4%A1%E7%8C%AE%E6%8C%87%E5%8D%97)。
|
适用于多框架的 JavaScript 国际化解决方案,提供对 openInula 的适配。
|
||||||
|
|
||||||
|
- [适配示例](https://gitee.com/link?target=https%3A%2F%2Fgithub.com%2Fzhangfisher%2Fvoerka-i18n%2Ftree%2Fmaster%2Fexamples%2Fopeninula)
|
||||||
|
- [适配文档](https://gitee.com/link?target=https%3A%2F%2Fzhangfisher.github.io%2Fvoerka-i18n%2F%23%2Fzh%2Fguide%2Fintegration%2Fopeninula)
|
||||||
|
|
||||||
## 许可协议
|
## 许可协议
|
||||||
|
|
||||||
|
@ -75,6 +80,8 @@ openInula 主要遵循 [Mulan Permissive Software License v2](http://license.cos
|
||||||
|
|
||||||
## 联系方式
|
## 联系方式
|
||||||
|
|
||||||
team@inulajs.org
|
* 官方邮箱: [team@inulajs.org](mailto:team@inulajs.org)
|
||||||
|
|
||||||
|
* 微信公众号:
|
||||||
|
|
||||||
|

|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Huawei Technologies Co.,Ltd.
|
||||||
|
*
|
||||||
|
* openInula is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
*
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
extends: ['@commitlint/config-conventional'],
|
||||||
|
'type-enum': ['build', 'chore', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test', 'types'],
|
||||||
|
};
|
107
package.json
107
package.json
|
@ -5,65 +5,86 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint . --ext .ts --fix",
|
"lint": "eslint . --ext .ts --fix",
|
||||||
"prettier": "prettier -w libs/**/*.ts",
|
"lint-commit": "lint-staged",
|
||||||
|
"prettier": "prettier .prettierrc.js -w packages/**/*.{ts,tsx,js,jsx}",
|
||||||
"build:inula": "pnpm -F openinula build",
|
"build:inula": "pnpm -F openinula build",
|
||||||
"test:inula": "pnpm -F openinula test",
|
"test:inula": "pnpm -F openinula test",
|
||||||
|
"test:inula-intl": "pnpm -F inula-intl test",
|
||||||
|
"test:inula-request": "pnpm -F inula-request test",
|
||||||
|
"test:inula-router": "pnpm -F inula-router test",
|
||||||
"build:inula-cli": "pnpm -F inula-cli build",
|
"build:inula-cli": "pnpm -F inula-cli build",
|
||||||
"build:inula-intl": "pnpm -F inula-intl build",
|
"build:inula-intl": "pnpm -F inula-intl build",
|
||||||
"build:inula-request": "pnpm -F inula-request build",
|
"build:inula-request": "pnpm -F inula-request build",
|
||||||
"build:inula-router": "pnpm -F inula-router build"
|
"build:inula-router": "pnpm -F inula-router build",
|
||||||
|
"commitlint": "commitlint --config commitlint.config.js -e",
|
||||||
|
"postinstall": "husky install"
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"*.{js,jsx,ts,tsx}": [
|
||||||
|
"prettier .prettierrc.js -w"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.16.7",
|
"@babel/core": "7.23.7",
|
||||||
"@babel/plugin-proposal-class-properties": "7.16.7",
|
"@babel/plugin-proposal-class-properties": "7.18.6",
|
||||||
"@babel/plugin-proposal-nullish-coalescing-operator": "7.16.7",
|
"@babel/plugin-proposal-nullish-coalescing-operator": "7.18.6",
|
||||||
"@babel/plugin-proposal-object-rest-spread": "7.16.7",
|
"@babel/plugin-proposal-object-rest-spread": "7.20.7",
|
||||||
"@babel/plugin-proposal-optional-chaining": "7.16.7",
|
"@babel/plugin-proposal-optional-chaining": "7.21.0",
|
||||||
"@babel/plugin-proposal-private-methods": "7.16.7",
|
"@babel/plugin-proposal-private-methods": "7.18.6",
|
||||||
"@babel/plugin-proposal-private-property-in-object": "7.16.7",
|
"@babel/plugin-proposal-private-property-in-object": "7.21.11",
|
||||||
"@babel/plugin-syntax-jsx": "7.16.7",
|
"@babel/plugin-syntax-jsx": "7.23.3",
|
||||||
"@babel/plugin-transform-arrow-functions": "7.16.7",
|
"@babel/plugin-transform-arrow-functions": "7.23.3",
|
||||||
"@babel/plugin-transform-block-scoped-functions": "7.16.7",
|
"@babel/plugin-transform-block-scoped-functions": "7.23.3",
|
||||||
"@babel/plugin-transform-block-scoping": "7.16.7",
|
"@babel/plugin-transform-block-scoping": "7.23.4",
|
||||||
"@babel/plugin-transform-classes": "7.16.7",
|
"@babel/plugin-transform-classes": "7.23.8",
|
||||||
"@babel/plugin-transform-computed-properties": "7.16.7",
|
"@babel/plugin-transform-computed-properties": "7.23.3",
|
||||||
"@babel/plugin-transform-destructuring": "7.16.7",
|
"@babel/plugin-transform-destructuring": "7.23.3",
|
||||||
"@babel/plugin-transform-for-of": "7.16.7",
|
"@babel/plugin-transform-for-of": "7.23.6",
|
||||||
"@babel/plugin-transform-literals": "7.16.7",
|
"@babel/plugin-transform-literals": "7.23.3",
|
||||||
"@babel/plugin-transform-object-assign": "7.16.7",
|
"@babel/plugin-transform-object-assign": "7.23.3",
|
||||||
"@babel/plugin-transform-object-super": "7.16.7",
|
"@babel/plugin-transform-object-super": "7.23.3",
|
||||||
"@babel/plugin-transform-parameters": "7.16.7",
|
"@babel/plugin-transform-parameters": "7.23.3",
|
||||||
"@babel/plugin-transform-react-jsx": "7.16.7",
|
"@babel/plugin-transform-react-jsx": "7.23.4",
|
||||||
"@babel/plugin-transform-react-jsx-source": "^7.16.7",
|
"@babel/plugin-transform-react-jsx-source": "^7.23.3",
|
||||||
"@babel/plugin-transform-runtime": "7.16.7",
|
"@babel/plugin-transform-runtime": "7.23.7",
|
||||||
"@babel/plugin-transform-shorthand-properties": "7.16.7",
|
"@babel/plugin-transform-shorthand-properties": "7.23.3",
|
||||||
"@babel/plugin-transform-spread": "7.16.7",
|
"@babel/plugin-transform-spread": "7.23.3",
|
||||||
"@babel/plugin-transform-template-literals": "7.16.7",
|
"@babel/plugin-transform-template-literals": "7.23.3",
|
||||||
"@babel/preset-env": "7.16.7",
|
"@babel/preset-env": "7.23.8",
|
||||||
"@babel/preset-typescript": "7.16.7",
|
"@babel/preset-typescript": "7.23.3",
|
||||||
"@babel/runtime": "7.16.7",
|
"@babel/runtime": "7.23.8",
|
||||||
"@rollup/plugin-babel": "^5.3.1",
|
"@commitlint/cli": "^17.8.1",
|
||||||
"@rollup/plugin-node-resolve": "^13.3.0",
|
"@commitlint/config-conventional": "^17.8.1",
|
||||||
|
"@rollup/plugin-babel": "^6.0.4",
|
||||||
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||||
"@rollup/plugin-replace": "^4.0.0",
|
"@rollup/plugin-replace": "^4.0.0",
|
||||||
"@types/jest": "^26.0.24",
|
"@types/jest": "^29.5.11",
|
||||||
"@types/node": "^17.0.18",
|
"@types/node": "^17.0.18",
|
||||||
"@typescript-eslint/eslint-plugin": "4.8.0",
|
"@typescript-eslint/eslint-plugin": "^6.18.1",
|
||||||
"@typescript-eslint/parser": "4.8.0",
|
"@typescript-eslint/parser": "6.18.1",
|
||||||
"babel-jest": "^27.5.1",
|
"@babel/parser": "^7.24.7",
|
||||||
|
"magic-string": "^0.30.10",
|
||||||
|
"babel-jest": "^29.7.0",
|
||||||
"ejs": "^3.1.8",
|
"ejs": "^3.1.8",
|
||||||
"eslint": "7.13.0",
|
"eslint": "^8.56.0",
|
||||||
"eslint-config-prettier": "^6.9.0",
|
"eslint-config-prettier": "^6.9.0",
|
||||||
"eslint-plugin-jest": "^22.15.0",
|
"eslint-plugin-jest": "^22.15.0",
|
||||||
"eslint-plugin-no-for-of-loops": "^1.0.0",
|
|
||||||
"eslint-plugin-no-function-declare-after-return": "^1.0.0",
|
"eslint-plugin-no-function-declare-after-return": "^1.0.0",
|
||||||
"eslint-plugin-react": "7.14.3",
|
"eslint-plugin-react": "7.14.3",
|
||||||
"jest": "^25.5.4",
|
"husky": "^8.0.3",
|
||||||
"jest-environment-jsdom-sixteen": "^1.0.3",
|
"jest": "^29.7.0",
|
||||||
"prettier": "2.6.2",
|
"jest-environment-jsdom": "^29.7.0",
|
||||||
"rollup": "^2.75.5",
|
"lint-staged": "^15.2.0",
|
||||||
|
"openinula": "workspace:*",
|
||||||
|
"prettier": "^3.1.1",
|
||||||
|
"rollup": "^2.79.1",
|
||||||
|
"rollup-plugin-dts": "^6.1.0",
|
||||||
"rollup-plugin-execute": "^1.1.1",
|
"rollup-plugin-execute": "^1.1.1",
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
"typescript": "4.2.3"
|
"rollup-plugin-esbuild": "^6.1.1",
|
||||||
|
"rollup-plugin-polyfill-node": "^0.13.0",
|
||||||
|
"ts-jest": "^29.1.1",
|
||||||
|
"typescript": "^4.9.5"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.x",
|
"node": ">=10.x",
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
|
||||||
*
|
|
||||||
* openInula is licensed under Mulan PSL v2.
|
|
||||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
* You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
*
|
|
||||||
* http://license.coscl.org.cn/MulanPSL2
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
||||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
||||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the Mulan PSL v2 for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
printWidth: 120, // 一行120字符数,如果超过会进行换行
|
|
||||||
tabWidth: 2, // tab等2个空格
|
|
||||||
useTabs: false, // 用空格缩进行
|
|
||||||
semi: true, // 行尾使用分号
|
|
||||||
singleQuote: true, // 字符串使用单引号
|
|
||||||
quoteProps: 'as-needed', // 仅在需要时在对象属性添加引号
|
|
||||||
jsxSingleQuote: false, // 在JSX中使用双引号
|
|
||||||
trailingComma: 'es5', // 使用尾逗号(对象、数组等)
|
|
||||||
bracketSpacing: true, // 对象的括号间增加空格
|
|
||||||
bracketSameLine: false, // 将多行JSX元素的>放在最后一行的末尾
|
|
||||||
arrowParens: 'avoid', // 在唯一的arrow函数参数周围省略括号
|
|
||||||
vueIndentScriptAndStyle: false, // 不缩进Vue文件中的<script>和<style>标记内的代码
|
|
||||||
endOfLine: 'lf', // 仅限换行(\n)
|
|
||||||
};
|
|
|
@ -140,8 +140,7 @@ class BasicGenerator extends Generator {
|
||||||
if (fs.lstatSync(fullpath).isDirectory()) {
|
if (fs.lstatSync(fullpath).isDirectory()) {
|
||||||
this.traverseDirBubble(fullpath, dirCallback, fileCallback);
|
this.traverseDirBubble(fullpath, dirCallback, fileCallback);
|
||||||
dirCallback(fullpath);
|
dirCallback(fullpath);
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
fileCallback(fullpath);
|
fileCallback(fullpath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"openinula": "^0.0.1"
|
"openinula": "^0.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.21.4",
|
"@babel/core": "^7.21.4",
|
||||||
|
|
|
@ -34,7 +34,9 @@ function App() {
|
||||||
<h2>了解更多</h2>
|
<h2>了解更多</h2>
|
||||||
<p>
|
<p>
|
||||||
要了解 Inula,查看{' '}
|
要了解 Inula,查看{' '}
|
||||||
<a href="https://openinula.com/" target="_blank">Inula 官网</a>
|
<a href="https://openinula.net/" target="_blank">
|
||||||
|
Inula 官网
|
||||||
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"openinula": "^0.0.1"
|
"openinula": "^0.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.21.4",
|
"@babel/core": "^7.21.4",
|
||||||
|
|
|
@ -35,7 +35,9 @@ class App extends Inula.Component {
|
||||||
<h2>了解更多</h2>
|
<h2>了解更多</h2>
|
||||||
<p>
|
<p>
|
||||||
要了解 Inula,查看{' '}
|
要了解 Inula,查看{' '}
|
||||||
<a href="https://openinula.org" target="_blank">Inula 官网</a>
|
<a href="https://openinula.org" target="_blank">
|
||||||
|
Inula 官网
|
||||||
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -26,7 +26,7 @@ function App() {
|
||||||
</div>
|
</div>
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<div className="card animate__animated animate__zoomIn">
|
<div className="card animate__animated animate__zoomIn">
|
||||||
<ReactiveComponent/>
|
<ReactiveComponent />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
@ -34,7 +34,9 @@ function App() {
|
||||||
<h2>了解更多</h2>
|
<h2>了解更多</h2>
|
||||||
<p>
|
<p>
|
||||||
要了解 Inula,查看{' '}
|
要了解 Inula,查看{' '}
|
||||||
<a href="https://openinula.com/" target="_blank">Inula 官网</a>
|
<a href="https://openinula.net/" target="_blank">
|
||||||
|
Inula 官网
|
||||||
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -27,7 +27,7 @@ class App extends Inula.Component {
|
||||||
</div>
|
</div>
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<div className="card animate__animated animate__zoomIn">
|
<div className="card animate__animated animate__zoomIn">
|
||||||
<ReactiveComponent/>
|
<ReactiveComponent />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
@ -35,7 +35,9 @@ class App extends Inula.Component {
|
||||||
<h2>了解更多</h2>
|
<h2>了解更多</h2>
|
||||||
<p>
|
<p>
|
||||||
要了解 Inula,查看{' '}
|
要了解 Inula,查看{' '}
|
||||||
<a href="https://openinula.org" target="_blank">Inula 官网</a>
|
<a href="https://openinula.org" target="_blank">
|
||||||
|
Inula 官网
|
||||||
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -32,8 +32,8 @@ const generatorType = fs
|
||||||
});
|
});
|
||||||
|
|
||||||
const runGenerator = async (templatePath, { name = '', cwd = process.cwd(), args = {} }) => {
|
const runGenerator = async (templatePath, { name = '', cwd = process.cwd(), args = {} }) => {
|
||||||
return new Promise(resolve => {
|
|
||||||
let currentPath;
|
let currentPath;
|
||||||
|
return new Promise(resolve => {
|
||||||
if (name) {
|
if (name) {
|
||||||
mkdirp.sync(name);
|
mkdirp.sync(name);
|
||||||
currentPath = path.join(cwd, name);
|
currentPath = path.join(cwd, name);
|
||||||
|
@ -68,7 +68,7 @@ const run = async config => {
|
||||||
{
|
{
|
||||||
name: 'projectName',
|
name: 'projectName',
|
||||||
message: 'Project name',
|
message: 'Project name',
|
||||||
type: 'input'
|
type: 'input',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
config.name = answers.projectName;
|
config.name = answers.projectName;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "create-inula",
|
"name": "create-inula",
|
||||||
"version": "0.0.6",
|
"version": "0.0.8",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
|
||||||
*
|
|
||||||
* openInula is licensed under Mulan PSL v2.
|
|
||||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
* You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
*
|
|
||||||
* http://license.coscl.org.cn/MulanPSL2
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
||||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
||||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the Mulan PSL v2 for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
'parser': 'babel-eslint',
|
|
||||||
'env': {
|
|
||||||
'amd': true,
|
|
||||||
'es6': true,
|
|
||||||
'browser': true,
|
|
||||||
'node': false
|
|
||||||
},
|
|
||||||
'parserOptions': {
|
|
||||||
'ecmaVersion': 6,
|
|
||||||
'sourceType': 'module',
|
|
||||||
'ecmaFeatures': {
|
|
||||||
'jsx': true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'ignorePatterns': [
|
|
||||||
"src/template"
|
|
||||||
],
|
|
||||||
'rules': {
|
|
||||||
'indent': [
|
|
||||||
'error',
|
|
||||||
4,
|
|
||||||
{
|
|
||||||
SwitchCase: 1,
|
|
||||||
flatTernaryExpressions: true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'no-unused-vars': 'off', // 允许变量声明后未使用
|
|
||||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
|
||||||
"no-underscore-dangle": ["off", "always"], // 允许私有变量 _xxx的变量命名方式
|
|
||||||
'filenames/match-exported': 0,
|
|
||||||
'consistent-return': 0,
|
|
||||||
"comma-dangle": [2, "never"], // 组和对象键值对最后一个逗号, never参数:不能带末尾的逗号, always参数:必须带末尾的逗号
|
|
||||||
'global-require': 0, // 允许require语句不出现在顶层中
|
|
||||||
'no-nested-ternary': 0, // 允许嵌套三元表达式
|
|
||||||
'no-unused-expressions': 0, // 允许使用未执行的表达式。比如fn是一个函数,允许 fn && fn()
|
|
||||||
'no-throw-literal': 0, // 允许throw抛出对象格式
|
|
||||||
'@typescript-eslint/member-ordering': 0 // 禁用TypeScript声明规范
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
node_modules/
|
|
||||||
webpack/
|
|
||||||
public/
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
|
||||||
*
|
|
||||||
* openInula is licensed under Mulan PSL v2.
|
|
||||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
* You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
*
|
|
||||||
* http://license.coscl.org.cn/MulanPSL2
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
||||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
||||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the Mulan PSL v2 for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default {
|
|
||||||
printWidth: 120, // 一行120字符数,如果超过会进行换行
|
|
||||||
tabWidth: 2, // tab等2个空格
|
|
||||||
useTabs: false, // 用空格缩进行
|
|
||||||
semi: true, // 行尾使用分号
|
|
||||||
singleQuote: true, // 字符串使用单引号
|
|
||||||
quoteProps: 'as-needed', // 仅在需要时在对象属性添加引号
|
|
||||||
jsxSingleQuote: false, // 在JSX中使用双引号
|
|
||||||
trailingComma: 'es5', // 使用尾逗号(对象、数组等)
|
|
||||||
bracketSpacing: true, // 对象的括号间增加空格
|
|
||||||
jsxBracketSameLine: false, // 将多行JSX元素的>放在最后一行的末尾
|
|
||||||
arrowParens: 'avoid', // 在唯一的arrow函数参数周围省略括号
|
|
||||||
vueIndentScriptAndStyle: false, // 不缩进Vue文件中的<script>和<style>标记内的代码
|
|
||||||
endOfLine: 'lf', // 仅限换行(\n)
|
|
||||||
};
|
|
|
@ -13,29 +13,4 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const {preset} = require("./jest.config");
|
declare module 'crequire';
|
||||||
module.exports = {
|
|
||||||
presets: [
|
|
||||||
[
|
|
||||||
'@babel/preset-env',
|
|
||||||
{
|
|
||||||
targets: {
|
|
||||||
browsers: ['> 1%', 'last 2 versions', 'not ie <= 8'],
|
|
||||||
node: 'current',
|
|
||||||
},
|
|
||||||
useBuiltIns: 'usage',
|
|
||||||
corejs: 3,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'@babel/preset-typescript',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"@babel/preset-react",
|
|
||||||
{
|
|
||||||
"runtime": "automatic",
|
|
||||||
"importSource": "openinula"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
};
|
|
|
@ -1,51 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
|
||||||
*
|
|
||||||
* openInula is licensed under Mulan PSL v2.
|
|
||||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
* You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
*
|
|
||||||
* http://license.coscl.org.cn/MulanPSL2
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
||||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
||||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the Mulan PSL v2 for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import webpack from 'webpack';
|
|
||||||
import { build } from 'vite';
|
|
||||||
|
|
||||||
export default (api: any) => {
|
|
||||||
api.registerCommand({
|
|
||||||
name: 'build',
|
|
||||||
description: 'build application for production',
|
|
||||||
initialState: api.buildConfig,
|
|
||||||
fn: async function (args: any, state: any) {
|
|
||||||
switch (api.compileMode) {
|
|
||||||
case 'webpack':
|
|
||||||
if (state) {
|
|
||||||
api.applyHook({ name: 'beforeCompile', args: state });
|
|
||||||
state.forEach((s: any) => {
|
|
||||||
webpack(s.config, (err: any, stats: any) => {
|
|
||||||
if (err || stats.hasErrors()) {
|
|
||||||
api.logger.error(`Build failed.err: ${err}, stats:${stats}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
api.logger.error(`Build failed. Can't find build config.`);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'vite':
|
|
||||||
if (state) {
|
|
||||||
api.applyHook({ name: 'beforeCompile' });
|
|
||||||
build(state);
|
|
||||||
} else {
|
|
||||||
api.logger.error(`Build failed. Can't find build config.`);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -19,7 +19,6 @@ import { createServer } from 'vite';
|
||||||
import { API } from '../../../types/types';
|
import { API } from '../../../types/types';
|
||||||
import setupProxy from '../../../utils/setupProxy.js';
|
import setupProxy from '../../../utils/setupProxy.js';
|
||||||
|
|
||||||
|
|
||||||
export default (api: API) => {
|
export default (api: API) => {
|
||||||
api.registerCommand({
|
api.registerCommand({
|
||||||
name: 'dev',
|
name: 'dev',
|
||||||
|
@ -46,7 +45,7 @@ export default (api: API) => {
|
||||||
if (api.userConfig.devBuildConfig.devProxy) {
|
if (api.userConfig.devBuildConfig.devProxy) {
|
||||||
devServerOptions.onBeforeSetupMiddleware = (devServer: WebpackDevServer) => {
|
devServerOptions.onBeforeSetupMiddleware = (devServer: WebpackDevServer) => {
|
||||||
setupProxy(devServer.app, api);
|
setupProxy(devServer.app, api);
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
api.applyHook({
|
api.applyHook({
|
||||||
|
|
|
@ -33,15 +33,17 @@ export default (api: API) => {
|
||||||
args._.shift();
|
args._.shift();
|
||||||
}
|
}
|
||||||
if (args._.length === 0) {
|
if (args._.length === 0) {
|
||||||
api.logger.warn("Can't find any generate options.");
|
api.logger.warn('Can\'t find any generate options.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (args._[0]) {
|
switch (args._[0]) {
|
||||||
case 'jest':
|
case 'jest':
|
||||||
|
{
|
||||||
args._.shift();
|
args._.shift();
|
||||||
const isESM = api.packageJson['type'] === 'module';
|
const isESM = api.packageJson['type'] === 'module';
|
||||||
await generateJest(args, api.cwd, isESM);
|
await generateJest(args, api.cwd, isESM);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
@ -50,7 +52,7 @@ export default (api: API) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateJest = async (args: yargsParser.Arguments, cwd: string, isESM: boolean) => {
|
const generateJest = async (args: yargsParser.Arguments, cwd: string, isESM: boolean) => {
|
||||||
let isTs: boolean = false;
|
let isTs = false;
|
||||||
if (args['ts']) {
|
if (args['ts']) {
|
||||||
isTs = true;
|
isTs = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -25,7 +25,7 @@ export default (api: any) => {
|
||||||
initialState: api.userConfig.remoteProxy,
|
initialState: api.userConfig.remoteProxy,
|
||||||
fn: async function (args: any, state: any) {
|
fn: async function (args: any, state: any) {
|
||||||
if (!state) {
|
if (!state) {
|
||||||
api.logger.error(`Invalid proxy config!`);
|
api.logger.error('Invalid proxy config!');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
|
@ -46,7 +46,7 @@ export default async function run() {
|
||||||
initializeEnv();
|
initializeEnv();
|
||||||
|
|
||||||
if (command === 'version' || command === 'help') {
|
if (command === 'version' || command === 'help') {
|
||||||
process.env.INNER_COMMAND = "true"
|
process.env.INNER_COMMAND = 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
|
@ -61,9 +61,9 @@ export default async function run() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let enableDebug: boolean = false;
|
let enableDebug = false;
|
||||||
|
|
||||||
if (process.env.DEBUG === "true") {
|
if (process.env.DEBUG === 'true') {
|
||||||
enableDebug = true;
|
enableDebug = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ export default class Config {
|
||||||
|
|
||||||
getConfigFile(): string | null {
|
getConfigFile(): string | null {
|
||||||
const configFileList: string[] = DEFAULT_CONFIG_FILES.map(f => join(this.cwd, f));
|
const configFileList: string[] = DEFAULT_CONFIG_FILES.map(f => join(this.cwd, f));
|
||||||
for (let configFile of configFileList) {
|
for (const configFile of configFileList) {
|
||||||
if (existsSync(configFile)) {
|
if (existsSync(configFile)) {
|
||||||
return configFile;
|
return configFile;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,11 +46,11 @@ export default class Hub {
|
||||||
userConfig: UserConfig = {};
|
userConfig: UserConfig = {};
|
||||||
packageJson: PackageJSON;
|
packageJson: PackageJSON;
|
||||||
stage: ServiceStage = ServiceStage.uninitialized;
|
stage: ServiceStage = ServiceStage.uninitialized;
|
||||||
buildConfig: {name:string, config: object}[] = [];
|
buildConfig: { name: string; config: Record<string, unknown> }[] = [];
|
||||||
pluginManager: Plugin;
|
pluginManager: Plugin;
|
||||||
buildConfigPath: BuildConfig[] = [];
|
buildConfigPath: BuildConfig[] = [];
|
||||||
devBuildConfig: object = {};
|
devBuildConfig: Record<string, unknown> = {};
|
||||||
compileMode: string = '';
|
compileMode = '';
|
||||||
builtInPlugins: string[] = [];
|
builtInPlugins: string[] = [];
|
||||||
pluginPaths: string[] = [];
|
pluginPaths: string[] = [];
|
||||||
devProxy: DevProxy | null = null;
|
devProxy: DevProxy | null = null;
|
||||||
|
@ -95,7 +95,7 @@ export default class Hub {
|
||||||
this.userConfig = await this.configManager.getUserConfig();
|
this.userConfig = await this.configManager.getUserConfig();
|
||||||
|
|
||||||
// 设置编译模式
|
// 设置编译模式
|
||||||
this.setCompileMode()
|
this.setCompileMode();
|
||||||
|
|
||||||
// 获取编译配置
|
// 获取编译配置
|
||||||
await this.analyzeBuildConfig();
|
await this.analyzeBuildConfig();
|
||||||
|
@ -135,8 +135,8 @@ export default class Hub {
|
||||||
: this.pluginManager.commands[command];
|
: this.pluginManager.commands[command];
|
||||||
|
|
||||||
if (commands === undefined) {
|
if (commands === undefined) {
|
||||||
this.logger.error(`Invalid command ${command}`)
|
this.logger.error(`Invalid command ${command}`);
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
const { fn } = commands as ICommand;
|
const { fn } = commands as ICommand;
|
||||||
|
|
||||||
|
@ -150,21 +150,22 @@ export default class Hub {
|
||||||
|
|
||||||
async analyzeBuildConfig() {
|
async analyzeBuildConfig() {
|
||||||
if (this.userConfig.devBuildConfig) {
|
if (this.userConfig.devBuildConfig) {
|
||||||
let { name, path, env } = this.userConfig.devBuildConfig;
|
let { path } = this.userConfig.devBuildConfig;
|
||||||
|
const { env } = this.userConfig.devBuildConfig;
|
||||||
path = isAbsolute(path) ? path : join(process.cwd(), path);
|
path = isAbsolute(path) ? path : join(process.cwd(), path);
|
||||||
if (!existsSync(path)) {
|
if (!existsSync(path)) {
|
||||||
this.logger.warn(`Cant't find dev build config. Path is ${path}`);
|
this.logger.warn(`Cant't find dev build config. Path is ${path}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.logger.debug(`Find dev build config. Path is ${path}`);
|
this.logger.debug(`Find dev build config. Path is ${path}`);
|
||||||
let bc = await loadModule<object | Function>(path);
|
const bc = await loadModule<Record<string, unknown> | ((...args: any[]) => any)>(path);
|
||||||
if (bc == undefined) {
|
if (bc == undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let finalBc = {};
|
let finalBc = {};
|
||||||
if (typeof bc === 'function') {
|
if (typeof bc === 'function') {
|
||||||
finalBc = bc(env)
|
finalBc = bc(env);
|
||||||
this.devBuildConfig = finalBc;
|
this.devBuildConfig = finalBc;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -175,55 +176,54 @@ export default class Hub {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!this.userConfig.buildConfig) {
|
if (!this.userConfig.buildConfig) {
|
||||||
switch (this.compileMode) {
|
switch (this.compileMode) {
|
||||||
case 'webpack':
|
case 'webpack':
|
||||||
this.buildConfigPath.push({name:'default', path:'./webpack.config.js'})
|
this.buildConfigPath.push({ name: 'default', path: './webpack.config.js' });
|
||||||
break;
|
break;
|
||||||
case 'vite':
|
case 'vite':
|
||||||
this.buildConfigPath.push({name:'default', path:'./vite.config.js'})
|
this.buildConfigPath.push({ name: 'default', path: './vite.config.js' });
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this.logger.warn(`Unknown compile mode ${this.compileMode}`);
|
this.logger.warn(`Unknown compile mode ${this.compileMode}`);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.userConfig.buildConfig.forEach((userBuildConfig) => {
|
this.userConfig.buildConfig.forEach(userBuildConfig => {
|
||||||
if (typeof userBuildConfig === 'object') {
|
if (typeof userBuildConfig === 'object') {
|
||||||
this.buildConfigPath.push(userBuildConfig);
|
this.buildConfigPath.push(userBuildConfig);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.buildConfigPath.forEach(async (config) => {
|
this.buildConfigPath.forEach(async config => {
|
||||||
let {name, path} = config;
|
let { path } = config;
|
||||||
|
const { name } = config;
|
||||||
path = isAbsolute(path) ? path : join(process.cwd(), path);
|
path = isAbsolute(path) ? path : join(process.cwd(), path);
|
||||||
if (!existsSync(path)) {
|
if (!existsSync(path)) {
|
||||||
this.logger.debug(`Cant't find build config. Path is ${path}`);
|
this.logger.debug(`Cant't find build config. Path is ${path}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.logger.debug(`Find build config. Path is ${path}`);
|
this.logger.debug(`Find build config. Path is ${path}`);
|
||||||
let bc = await loadModule<object | Function >(path);
|
const bc = await loadModule<Record<string, unknown> | ((...args: any[]) => any)>(path);
|
||||||
if (bc == undefined) {
|
if (bc == undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let finalBc = {};
|
let finalBc = {};
|
||||||
if (typeof bc === 'function') {
|
if (typeof bc === 'function') {
|
||||||
finalBc = bc(config.env)
|
finalBc = bc(config.env);
|
||||||
this.buildConfig.push({name: name, config: finalBc});
|
this.buildConfig.push({ name: name, config: finalBc });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.buildConfig.push({name: name, config: bc});
|
this.buildConfig.push({ name: name, config: bc });
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getConfigName(name: string): string {
|
getConfigName(name: string): string {
|
||||||
name = name.replace('webpack.', '');
|
name = name.replace('webpack.', '');
|
||||||
name = name.replace('.js', '');
|
name = name.replace('.js', '');
|
||||||
name = name.replace('.ts', '');
|
name = name.replace('.ts', '');
|
||||||
return name
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ export interface IPlugin {
|
||||||
id: string;
|
id: string;
|
||||||
key: string;
|
key: string;
|
||||||
path: string;
|
path: string;
|
||||||
apply: Function;
|
apply: (...args: any[]) => any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Plugin {
|
export default class Plugin {
|
||||||
|
@ -57,7 +57,7 @@ export default class Plugin {
|
||||||
} = {};
|
} = {};
|
||||||
hub: Hub;
|
hub: Hub;
|
||||||
logger: Logger;
|
logger: Logger;
|
||||||
registerFunction: Function[] = [];
|
registerFunction: ((...args: any[]) => any)[] = [];
|
||||||
// 解决调用this[props]时ts提示属性未知
|
// 解决调用this[props]时ts提示属性未知
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ export default class Plugin {
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const obj of objs) {
|
for (const obj of objs) {
|
||||||
const module: Function | undefined = await loadModule(obj.path);
|
const module: ((...args: any[]) => any) | undefined = await loadModule(obj.path);
|
||||||
if (module) {
|
if (module) {
|
||||||
try {
|
try {
|
||||||
module(obj.api);
|
module(obj.api);
|
||||||
|
@ -135,15 +135,11 @@ export default class Plugin {
|
||||||
return new Proxy(pluginAPI, {
|
return new Proxy(pluginAPI, {
|
||||||
get: (target: PluginAPI, prop: string) => {
|
get: (target: PluginAPI, prop: string) => {
|
||||||
if (['userConfig', 'devBuildConfig', 'buildConfig', 'compileMode', 'packageJson', 'cwd'].includes(prop)) {
|
if (['userConfig', 'devBuildConfig', 'buildConfig', 'compileMode', 'packageJson', 'cwd'].includes(prop)) {
|
||||||
return typeof this.hub[prop] === 'function'
|
return typeof this.hub[prop] === 'function' ? this.hub[prop].bind(this.hub) : this.hub[prop];
|
||||||
? this.hub[prop].bind(this.hub)
|
|
||||||
: this.hub[prop];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (['setStore', 'logger', 'commands'].includes(prop)) {
|
if (['setStore', 'logger', 'commands'].includes(prop)) {
|
||||||
return typeof this[prop] === 'function'
|
return typeof this[prop] === 'function' ? this[prop].bind(this) : this[prop];
|
||||||
? this[prop].bind(this)
|
|
||||||
: this[prop];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return target[prop];
|
return target[prop];
|
||||||
|
|
|
@ -55,11 +55,11 @@ export default class PluginAPI {
|
||||||
this.register(hook);
|
this.register(hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
registerMethod(fn: Function) {
|
registerMethod(fn: (...args: any[]) => any) {
|
||||||
this.manager.registerFunction.push(fn);
|
this.manager.registerFunction.push(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
async applyHook(name: string, args?: any ) {
|
async applyHook(name: string, args?: any) {
|
||||||
const hooks: IHook[] = this.manager.hooks[name] || [];
|
const hooks: IHook[] = this.manager.hooks[name] || [];
|
||||||
let config: any = undefined;
|
let config: any = undefined;
|
||||||
for (const hook of hooks) {
|
for (const hook of hooks) {
|
||||||
|
|
|
@ -19,11 +19,8 @@ import { Logger } from '../utils/logger.js';
|
||||||
import type * as http from 'http';
|
import type * as http from 'http';
|
||||||
import type * as express from 'express';
|
import type * as express from 'express';
|
||||||
|
|
||||||
|
type Request = express.Request;
|
||||||
interface Request extends express.Request {
|
type Response = express.Response;
|
||||||
}
|
|
||||||
interface Response extends express.Response {
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IDep {
|
export interface IDep {
|
||||||
[name: string]: string;
|
[name: string]: string;
|
||||||
|
@ -40,7 +37,7 @@ export interface IPlugin {
|
||||||
id: string;
|
id: string;
|
||||||
key: string;
|
key: string;
|
||||||
path: string;
|
path: string;
|
||||||
apply: Function;
|
apply: (...args: any[]) => any;
|
||||||
|
|
||||||
config?: IPluginConfig;
|
config?: IPluginConfig;
|
||||||
isPreset?: boolean;
|
isPreset?: boolean;
|
||||||
|
@ -48,7 +45,7 @@ export interface IPlugin {
|
||||||
|
|
||||||
export interface IPluginConfig {
|
export interface IPluginConfig {
|
||||||
default?: any;
|
default?: any;
|
||||||
onChange?: string | Function;
|
onChange?: string | ((...args: any[]) => any);
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IHook {
|
export interface IHook {
|
||||||
|
@ -97,8 +94,8 @@ export interface API {
|
||||||
(hook: IHook): void;
|
(hook: IHook): void;
|
||||||
};
|
};
|
||||||
registerMethod: {
|
registerMethod: {
|
||||||
(method: Function): void;
|
(method: (...args: any[]) => any): void;
|
||||||
}
|
};
|
||||||
applyHook: {
|
applyHook: {
|
||||||
(opts: applyHookConfig): void;
|
(opts: applyHookConfig): void;
|
||||||
};
|
};
|
||||||
|
@ -136,22 +133,22 @@ export interface MockConfig {
|
||||||
export interface DevBuildConfig {
|
export interface DevBuildConfig {
|
||||||
name: string;
|
name: string;
|
||||||
path: string;
|
path: string;
|
||||||
args?: object;
|
args?: Record<string, unknown>;
|
||||||
env?: object;
|
env?: Record<string, unknown>;
|
||||||
devProxy?: DevProxy;
|
devProxy?: DevProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DevProxy {
|
export interface DevProxy {
|
||||||
target: string;
|
target: string;
|
||||||
matcher: ((pathname: string, req: Request) => boolean);
|
matcher: (pathname: string, req: Request) => boolean;
|
||||||
onProxyRes: (proxyRes: http.IncomingMessage, req: Request, res: Response) => void;
|
onProxyRes: (proxyRes: http.IncomingMessage, req: Request, res: Response) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BuildConfig {
|
export interface BuildConfig {
|
||||||
name: string;
|
name: string;
|
||||||
path: string;
|
path: string;
|
||||||
args?: object;
|
args?: Record<string, unknown>;
|
||||||
env?: object;
|
env?: Record<string, unknown>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ExportUserConfig = UserConfig | Promise<UserConfig>;
|
export type ExportUserConfig = UserConfig | Promise<UserConfig>;
|
||||||
|
|
|
@ -52,7 +52,7 @@ const buildConfig = async (fileName: string, format: 'esm' | 'cjs' = 'esm'): Pro
|
||||||
|
|
||||||
return {
|
return {
|
||||||
loader: args.path.endsWith('.ts') ? 'ts' : 'js',
|
loader: args.path.endsWith('.ts') ? 'ts' : 'js',
|
||||||
contents: contents
|
contents: contents,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -27,7 +27,6 @@ export async function loadModule<T>(filePath: string): Promise<T | undefined> {
|
||||||
const isTsFile: boolean = filePath.endsWith('ts');
|
const isTsFile: boolean = filePath.endsWith('ts');
|
||||||
const isJsFile: boolean = filePath.endsWith('js');
|
const isJsFile: boolean = filePath.endsWith('js');
|
||||||
|
|
||||||
|
|
||||||
let content: T | undefined;
|
let content: T | undefined;
|
||||||
|
|
||||||
// js文件,可以直接通过import引用
|
// js文件,可以直接通过import引用
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
import chokidar from 'chokidar';
|
import chokidar from 'chokidar';
|
||||||
import bodyParser from 'body-parser';
|
import bodyParser from 'body-parser';
|
||||||
import {globSync} from 'glob';
|
import { globSync } from 'glob';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { createRequire } from 'module';
|
import { createRequire } from 'module';
|
||||||
|
@ -38,13 +38,15 @@ function getMocksFile() {
|
||||||
const mockFiles = globSync('**/*.js', {
|
const mockFiles = globSync('**/*.js', {
|
||||||
cwd: mockDir,
|
cwd: mockDir,
|
||||||
});
|
});
|
||||||
let ret = mockFiles.reduce((mocks: any, mockFile: string) => {
|
const ret = mockFiles.reduce((mocks: any, mockFile: string) => {
|
||||||
if (!mockFile.startsWith('_')) {
|
if (!mockFile.startsWith('_')) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
const file = require(join(mockDir, mockFile));
|
||||||
mocks = {
|
mocks = {
|
||||||
...mocks,
|
...mocks,
|
||||||
...require(join(mockDir, mockFile)),
|
...file,
|
||||||
};
|
};
|
||||||
console.log('mockFile', require(join(mockDir, mockFile)));
|
console.log('mockFile', file);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mocks;
|
return mocks;
|
||||||
|
@ -54,8 +56,8 @@ function getMocksFile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateRoutes(app: any) {
|
function generateRoutes(app: any) {
|
||||||
let mockStartIndex = app._router.stack.length,
|
const mockStartIndex = app._router.stack.length;
|
||||||
mocks: Mock = {};
|
let mocks: Mock = {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mocks = getMocksFile();
|
mocks = getMocksFile();
|
||||||
|
|
|
@ -18,11 +18,13 @@ import { API } from '../types/types';
|
||||||
|
|
||||||
export default (app: any, api: API) => {
|
export default (app: any, api: API) => {
|
||||||
const { devProxy } = api.userConfig.devBuildConfig;
|
const { devProxy } = api.userConfig.devBuildConfig;
|
||||||
app.use(createProxyMiddleware(devProxy.matcher, {
|
app.use(
|
||||||
|
createProxyMiddleware(devProxy.matcher, {
|
||||||
target: devProxy.target,
|
target: devProxy.target,
|
||||||
secure: false,
|
secure: false,
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
ws: false,
|
ws: false,
|
||||||
onProxyRes: devProxy.onProxyRes
|
onProxyRes: devProxy.onProxyRes,
|
||||||
}));
|
})
|
||||||
}
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
import { dirname } from 'path';
|
import { dirname } from 'path';
|
||||||
import { readFileSync, writeFileSync } from 'fs';
|
import { readFileSync, writeFileSync } from 'fs';
|
||||||
import resolve from 'resolve';
|
import resolve from 'resolve';
|
||||||
// @ts-ignore
|
import crequire from 'crequire';
|
||||||
import crequire from 'crequire'
|
|
||||||
import { createRequire } from 'module';
|
import { createRequire } from 'module';
|
||||||
const require = createRequire(import.meta.url);
|
const require = createRequire(import.meta.url);
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,15 @@
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
},
|
},
|
||||||
"include": ["src/**/*"],
|
"include": [
|
||||||
"exclude": ["node_modules", "**/*.spec.ts", "./src/template/**/*"],
|
"src/**/*",
|
||||||
|
"./externals.d.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"./src/template/**/*"
|
||||||
|
],
|
||||||
"ts-node": {
|
"ts-node": {
|
||||||
"esm": true,
|
"esm": true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -17,9 +17,7 @@ module.exports = api => {
|
||||||
const isTest = api.env('test');
|
const isTest = api.env('test');
|
||||||
console.log('isTest', isTest);
|
console.log('isTest', isTest);
|
||||||
|
|
||||||
const plugins = [
|
const plugins = [['@babel/plugin-proposal-class-properties', { loose: false }]];
|
||||||
['@babel/plugin-proposal-class-properties', { loose: false }],
|
|
||||||
];
|
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
plugins.push(['@babel/plugin-transform-react-jsx-source']);
|
plugins.push(['@babel/plugin-transform-react-jsx-source']);
|
||||||
|
@ -30,11 +28,13 @@ module.exports = api => {
|
||||||
'@babel/preset-env',
|
'@babel/preset-env',
|
||||||
'@babel/preset-typescript',
|
'@babel/preset-typescript',
|
||||||
[
|
[
|
||||||
'@babel/preset-react', {
|
'@babel/preset-react',
|
||||||
|
{
|
||||||
runtime: 'classic',
|
runtime: 'classic',
|
||||||
'pragma': 'Inula.createElement',
|
pragma: 'Inula.createElement',
|
||||||
'pragmaFrag': 'Inula.Fragment',
|
pragmaFrag: 'Inula.Fragment',
|
||||||
}]
|
},
|
||||||
|
],
|
||||||
],
|
],
|
||||||
plugins,
|
plugins,
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,6 +14,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
declare module '*.less' {
|
declare module '*.less' {
|
||||||
const resource: {[key: string]: string};
|
const resource: { [key: string]: string };
|
||||||
export = resource;
|
export = resource;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
"webpack-dev-server": "^4.7.4"
|
"webpack-dev-server": "^4.7.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"openinula": "^0.0.1",
|
"openinula": "^0.1.1",
|
||||||
"flatted-object": "^0.1.2",
|
"flatted-object": "^0.1.2",
|
||||||
"json-decycle": "^2.0.1",
|
"json-decycle": "^2.0.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { checkMessage, packagePayload, changeSource } from "../utils/transferUtils";
|
import { checkMessage, packagePayload, changeSource } from '../utils/transferUtils';
|
||||||
import { RequestAllVNodeTreeInfos, InitDevToolPageConnection, DevToolBackground } from "../utils/constants";
|
import { RequestAllVNodeTreeInfos, InitDevToolPageConnection, DevToolBackground } from '../utils/constants';
|
||||||
import { DevToolPanel, DevToolContentScript } from "../utils/constants";
|
import { DevToolPanel, DevToolContentScript } from '../utils/constants';
|
||||||
|
|
||||||
// 多个页面 tab 页共享一个 background,需要建立连接池,给每个 tab 建立连接
|
// 多个页面 tab 页共享一个 background,需要建立连接池,给每个 tab 建立连接
|
||||||
export const connections = {};
|
export const connections = {};
|
||||||
|
|
|
@ -47,7 +47,7 @@ function requestObservedComponents(tabId) {
|
||||||
packagePayload(
|
packagePayload(
|
||||||
{
|
{
|
||||||
type: 'inulax request observed components',
|
type: 'inulax request observed components',
|
||||||
data: {}
|
data: {},
|
||||||
},
|
},
|
||||||
'dev tool background'
|
'dev tool background'
|
||||||
)
|
)
|
||||||
|
@ -65,7 +65,7 @@ function executeAction(tabId, storeId, action, params) {
|
||||||
action,
|
action,
|
||||||
storeId,
|
storeId,
|
||||||
params,
|
params,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
'dev tool background'
|
'dev tool background'
|
||||||
)
|
)
|
||||||
|
@ -82,7 +82,7 @@ function queueAction(tabId, storeId, action, params) {
|
||||||
action,
|
action,
|
||||||
storeId,
|
storeId,
|
||||||
params,
|
params,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
'sev tool background'
|
'sev tool background'
|
||||||
)
|
)
|
||||||
|
@ -167,7 +167,8 @@ chrome.runtime.onMessage.addListener(function (message, sender) {
|
||||||
type: 'INULA_DEV_TOOLS',
|
type: 'INULA_DEV_TOOLS',
|
||||||
payload: {
|
payload: {
|
||||||
type: 'inulax stores',
|
type: 'inulax stores',
|
||||||
stores: storesPerTab[tabId]?.map(store => {
|
stores:
|
||||||
|
storesPerTab[tabId]?.map(store => {
|
||||||
// 连接被监测的组件
|
// 连接被监测的组件
|
||||||
requestObservedComponents(tabId);
|
requestObservedComponents(tabId);
|
||||||
const observedComponents = getObservedComponents(store, tabId);
|
const observedComponents = getObservedComponents(store, tabId);
|
||||||
|
@ -184,7 +185,8 @@ chrome.runtime.onMessage.addListener(function (message, sender) {
|
||||||
type: 'INULA_DEV_TOOLS',
|
type: 'INULA_DEV_TOOLS',
|
||||||
payload: {
|
payload: {
|
||||||
type: 'inulax stores',
|
type: 'inulax stores',
|
||||||
stores: storesPerTab[sender.tab.id]?.map(store => {
|
stores:
|
||||||
|
storesPerTab[sender.tab.id]?.map(store => {
|
||||||
// 连接被监测的组件
|
// 连接被监测的组件
|
||||||
const observedComponents = getObservedComponents(store, sender.tab?.id);
|
const observedComponents = getObservedComponents(store, sender.tab?.id);
|
||||||
return { ...store, observedComponents };
|
return { ...store, observedComponents };
|
||||||
|
@ -200,30 +202,17 @@ chrome.runtime.onMessage.addListener(function (message, sender) {
|
||||||
if (message.from === DevToolPanel) {
|
if (message.from === DevToolPanel) {
|
||||||
// panel -> inulaXHandler
|
// panel -> inulaXHandler
|
||||||
if (message.payload.type === 'inulax run action') {
|
if (message.payload.type === 'inulax run action') {
|
||||||
executeAction(
|
executeAction(message.payload.tabId, message.payload.storeId, message.payload.action, message.payload.args);
|
||||||
message.payload.tabId,
|
|
||||||
message.payload.storeId,
|
|
||||||
message.payload.action,
|
|
||||||
message.payload.args
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.payload.type === 'inulax change state') {
|
if (message.payload.type === 'inulax change state') {
|
||||||
chrome.tabs.sendMessage(
|
chrome.tabs.sendMessage(message.payload.tabId, packagePayload(message.payload, 'dev tool background'));
|
||||||
message.payload.tabId,
|
|
||||||
packagePayload(message.payload, 'dev tool background')
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.payload.type === 'inulax queue action') {
|
if (message.payload.type === 'inulax queue action') {
|
||||||
queueAction(
|
queueAction(message.payload.tabId, message.payload.storeId, message.payload.action, message.payload.args);
|
||||||
message.payload.tabId,
|
|
||||||
message.payload.storeId,
|
|
||||||
message.payload.action,
|
|
||||||
message.payload.args
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +229,7 @@ chrome.runtime.onMessage.addListener(function (message, sender) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.payload.type === 'inula setPersistent'){
|
if (message.payload.type === 'inula setPersistent') {
|
||||||
const { tabId, persistent } = message.payload;
|
const { tabId, persistent } = message.payload;
|
||||||
eventPersistencePerTab[tabId] = persistent;
|
eventPersistencePerTab[tabId] = persistent;
|
||||||
return;
|
return;
|
||||||
|
@ -278,12 +267,10 @@ chrome.runtime.onMessage.addListener(function (message, sender) {
|
||||||
type: 'INULA_DEV_TOOLS',
|
type: 'INULA_DEV_TOOLS',
|
||||||
payload: {
|
payload: {
|
||||||
type: 'inulax stores',
|
type: 'inulax stores',
|
||||||
stores: storesPerTab[message.payload.tabId]?.map(store => {
|
stores:
|
||||||
|
storesPerTab[message.payload.tabId]?.map(store => {
|
||||||
requestObservedComponents(message.payload.tabId);
|
requestObservedComponents(message.payload.tabId);
|
||||||
const observedComponents = getObservedComponents(
|
const observedComponents = getObservedComponents(store.id, message.payload.tabId);
|
||||||
store.id,
|
|
||||||
message.payload.tabId
|
|
||||||
);
|
|
||||||
return { ...store, observedComponents };
|
return { ...store, observedComponents };
|
||||||
}) || [],
|
}) || [],
|
||||||
},
|
},
|
||||||
|
|
|
@ -47,7 +47,7 @@ const ComponentAttr = memo(function ComponentAttr({
|
||||||
attrs,
|
attrs,
|
||||||
id,
|
id,
|
||||||
dropdownRef,
|
dropdownRef,
|
||||||
}: {
|
}: {
|
||||||
attrsName: string;
|
attrsName: string;
|
||||||
attrsType: string;
|
attrsType: string;
|
||||||
attrs: IAttr[];
|
attrs: IAttr[];
|
||||||
|
@ -421,7 +421,12 @@ function ComponentInfo({ name, attrs, parents, id, source, onClickParent }: ICom
|
||||||
<b>Copy value to console</b>
|
<b>Copy value to console</b>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
onClick={() => storeVariable((dropdownRef.current as any).attrInfo.attrsName, (dropdownRef.current as any).attrInfo.path)}
|
onClick={() =>
|
||||||
|
storeVariable(
|
||||||
|
(dropdownRef.current as any).attrInfo.attrsName,
|
||||||
|
(dropdownRef.current as any).attrInfo.path
|
||||||
|
)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<b>Store as global variable</b>
|
<b>Store as global variable</b>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -38,7 +38,7 @@ export default function Search(props: SearchProps) {
|
||||||
onchange={handleChange}
|
onchange={handleChange}
|
||||||
className={styles.search}
|
className={styles.search}
|
||||||
value={value}
|
value={value}
|
||||||
placeholder='Search Component'
|
placeholder="Search Component"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ export function SizeObserver(props) {
|
||||||
const { children, ...rest } = props;
|
const { children, ...rest } = props;
|
||||||
const containerRef = useRef<HTMLDivElement>();
|
const containerRef = useRef<HTMLDivElement>();
|
||||||
const [size, setSize] = useState<{ width: number; height: number }>();
|
const [size, setSize] = useState<{ width: number; height: number }>();
|
||||||
const notifyChild = (element) => {
|
const notifyChild = element => {
|
||||||
setSize({
|
setSize({
|
||||||
width: element.offsetWidth,
|
width: element.offsetWidth,
|
||||||
height: element.offsetHeight,
|
height: element.offsetHeight,
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
* 确保继续渲染项在新渲染数组中的位置和旧渲染数组中的位置不发生改变
|
* 确保继续渲染项在新渲染数组中的位置和旧渲染数组中的位置不发生改变
|
||||||
*/
|
*/
|
||||||
export default class ItemMap<T> {
|
export default class ItemMap<T> {
|
||||||
|
|
||||||
// 不要用 indexOf 进行位置计算,它会遍历数组
|
// 不要用 indexOf 进行位置计算,它会遍历数组
|
||||||
private lastRenderItemToIndexMap: Map<T | undefined, number>;
|
private lastRenderItemToIndexMap: Map<T | undefined, number>;
|
||||||
|
|
||||||
|
@ -26,7 +25,7 @@ export default class ItemMap<T> {
|
||||||
this.lastRenderItemToIndexMap = new Map();
|
this.lastRenderItemToIndexMap = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
public calculateReSortedItems(nextItems: T[]): (T|undefined)[] {
|
public calculateReSortedItems(nextItems: T[]): (T | undefined)[] {
|
||||||
if (this.lastRenderItemToIndexMap.size === 0) {
|
if (this.lastRenderItemToIndexMap.size === 0) {
|
||||||
nextItems.forEach((item, index) => {
|
nextItems.forEach((item, index) => {
|
||||||
this.lastRenderItemToIndexMap.set(item, index);
|
this.lastRenderItemToIndexMap.set(item, index);
|
||||||
|
|
|
@ -36,13 +36,13 @@ interface IProps<T extends { id: number | string }> {
|
||||||
|
|
||||||
export type RenderInfoType<T> = {
|
export type RenderInfoType<T> = {
|
||||||
visibleItems: T[];
|
visibleItems: T[];
|
||||||
}
|
};
|
||||||
|
|
||||||
function parseTranslate<T>(data: T[], itemHeight: number) {
|
function parseTranslate<T>(data: T[], itemHeight: number) {
|
||||||
const map = new Map<T, number>();
|
const map = new Map<T, number>();
|
||||||
data.forEach((item, index) => {
|
data.forEach((item, index) => {
|
||||||
map.set(item, index * itemHeight);
|
map.set(item, index * itemHeight);
|
||||||
})
|
});
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ export function VList<T extends { id: number | string }>(props: IProps<T>) {
|
||||||
className={styles.item}
|
className={styles.item}
|
||||||
style={{ transform: `translateY(${itemToTranslateYMap.get(item)}px)` }}
|
style={{ transform: `translateY(${itemToTranslateYMap.get(item)}px)` }}
|
||||||
>
|
>
|
||||||
{children(item,indentationLength)}
|
{children(item, indentationLength)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -152,7 +152,7 @@ function Item(props: IItem) {
|
||||||
return (
|
return (
|
||||||
<div {...itemAttr}>
|
<div {...itemAttr}>
|
||||||
<div
|
<div
|
||||||
style={{marginLeft: indentation * indentationLength}}
|
style={{ marginLeft: indentation * indentationLength }}
|
||||||
className={styles.treeIcon}
|
className={styles.treeIcon}
|
||||||
onclick={handleClickCollapse}
|
onclick={handleClickCollapse}
|
||||||
>
|
>
|
||||||
|
@ -182,15 +182,7 @@ function VTree(props: {
|
||||||
selectItem: IData;
|
selectItem: IData;
|
||||||
onSelectItem: (item: IData) => void;
|
onSelectItem: (item: IData) => void;
|
||||||
}) {
|
}) {
|
||||||
const {
|
const { data, maxDeep, highlightValue, scrollToItem, onRendered, onCollapseNode, onSelectItem } = props;
|
||||||
data,
|
|
||||||
maxDeep,
|
|
||||||
highlightValue,
|
|
||||||
scrollToItem,
|
|
||||||
onRendered,
|
|
||||||
onCollapseNode,
|
|
||||||
onSelectItem
|
|
||||||
} = props;
|
|
||||||
const [collapseNode, setCollapseNode] = useState(props.collapsedNodes || []);
|
const [collapseNode, setCollapseNode] = useState(props.collapsedNodes || []);
|
||||||
const [selectItem, setSelectItem] = useState(props.selectItem);
|
const [selectItem, setSelectItem] = useState(props.selectItem);
|
||||||
const [childItems, setChildItems] = useState<Array<IData>>([]);
|
const [childItems, setChildItems] = useState<Array<IData>>([]);
|
||||||
|
@ -251,12 +243,9 @@ function VTree(props: {
|
||||||
[onSelectItem]
|
[onSelectItem]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleMouseEnterItem = useCallback(
|
const handleMouseEnterItem = useCallback(item => {
|
||||||
item => {
|
|
||||||
postMessageToBackground(Highlight, item);
|
postMessageToBackground(Highlight, item);
|
||||||
},
|
}, null);
|
||||||
null
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleMouseLeaveItem = () => {
|
const handleMouseLeaveItem = () => {
|
||||||
postMessageToBackground(RemoveHighlight);
|
postMessageToBackground(RemoveHighlight);
|
||||||
|
|
|
@ -20,7 +20,7 @@ const overlayStyles = {
|
||||||
background: 'rgba(120, 170, 210, 0.7)',
|
background: 'rgba(120, 170, 210, 0.7)',
|
||||||
padding: 'rgba(77, 200, 0, 0.3)',
|
padding: 'rgba(77, 200, 0, 0.3)',
|
||||||
margin: 'rgba(255, 155, 0, 0.3)',
|
margin: 'rgba(255, 155, 0, 0.3)',
|
||||||
border: 'rgba(255, 200, 50, 0.3)'
|
border: 'rgba(255, 200, 50, 0.3)',
|
||||||
};
|
};
|
||||||
|
|
||||||
type Rect = {
|
type Rect = {
|
||||||
|
@ -58,7 +58,7 @@ function getOwnerIframe(node: Element): Element | null {
|
||||||
|
|
||||||
function getElementStyle(domElement: Element) {
|
function getElementStyle(domElement: Element) {
|
||||||
const style = window.getComputedStyle(domElement);
|
const style = window.getComputedStyle(domElement);
|
||||||
return{
|
return {
|
||||||
marginLeft: parseInt(style.marginLeft, 10),
|
marginLeft: parseInt(style.marginLeft, 10),
|
||||||
marginRight: parseInt(style.marginRight, 10),
|
marginRight: parseInt(style.marginRight, 10),
|
||||||
marginTop: parseInt(style.marginTop, 10),
|
marginTop: parseInt(style.marginTop, 10),
|
||||||
|
@ -70,7 +70,7 @@ function getElementStyle(domElement: Element) {
|
||||||
paddingLeft: parseInt(style.paddingLeft, 10),
|
paddingLeft: parseInt(style.paddingLeft, 10),
|
||||||
paddingRight: parseInt(style.paddingRight, 10),
|
paddingRight: parseInt(style.paddingRight, 10),
|
||||||
paddingTop: parseInt(style.paddingTop, 10),
|
paddingTop: parseInt(style.paddingTop, 10),
|
||||||
paddingBottom: parseInt(style.paddingBottom, 10)
|
paddingBottom: parseInt(style.paddingBottom, 10),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ function mergeRectOffsets(rects: Array<Rect>): Rect {
|
||||||
width: previousRect.width + rect.width,
|
width: previousRect.width + rect.width,
|
||||||
height: previousRect.height + rect.height,
|
height: previousRect.height + rect.height,
|
||||||
bottom: previousRect.bottom + rect.bottom,
|
bottom: previousRect.bottom + rect.bottom,
|
||||||
right: previousRect.right + rect.right
|
right: previousRect.right + rect.right,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -99,18 +99,15 @@ function getBoundingClientRectWithBorderOffset(node: Element) {
|
||||||
top: dimensions.borderTop,
|
top: dimensions.borderTop,
|
||||||
left: dimensions.borderLeft,
|
left: dimensions.borderLeft,
|
||||||
bottom: dimensions.borderBottom,
|
bottom: dimensions.borderBottom,
|
||||||
right:dimensions.borderRight,
|
right: dimensions.borderRight,
|
||||||
// 高度和宽度不会被使用
|
// 高度和宽度不会被使用
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0
|
height: 0,
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNestedBoundingClientRect(
|
function getNestedBoundingClientRect(node: HTMLElement, boundaryWindow): Rect {
|
||||||
node: HTMLElement,
|
|
||||||
boundaryWindow
|
|
||||||
): Rect {
|
|
||||||
const ownerIframe = getOwnerIframe(node);
|
const ownerIframe = getOwnerIframe(node);
|
||||||
if (ownerIframe && ownerIframe !== boundaryWindow) {
|
if (ownerIframe && ownerIframe !== boundaryWindow) {
|
||||||
const rects = [node.getBoundingClientRect()] as Rect[];
|
const rects = [node.getBoundingClientRect()] as Rect[];
|
||||||
|
@ -125,7 +122,7 @@ function getNestedBoundingClientRect(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentIframe &&getOwnerWindow(currentIframe) === boundaryWindow) {
|
if (currentIframe && getOwnerWindow(currentIframe) === boundaryWindow) {
|
||||||
onlyOneMore = true;
|
onlyOneMore = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,7 +153,7 @@ class OverlayRect {
|
||||||
assign(this.node.style, {
|
assign(this.node.style, {
|
||||||
borderColor: overlayStyles.margin,
|
borderColor: overlayStyles.margin,
|
||||||
pointerEvents: 'none',
|
pointerEvents: 'none',
|
||||||
position: 'fixed'
|
position: 'fixed',
|
||||||
});
|
});
|
||||||
|
|
||||||
this.node.style.zIndex = '10000000';
|
this.node.style.zIndex = '10000000';
|
||||||
|
@ -179,13 +176,25 @@ class OverlayRect {
|
||||||
setBoxStyle(eleStyle, 'padding', this.padding);
|
setBoxStyle(eleStyle, 'padding', this.padding);
|
||||||
|
|
||||||
assign(this.content.style, {
|
assign(this.content.style, {
|
||||||
height: boxRect.height - eleStyle.borderTop - eleStyle.borderBottom - eleStyle.paddingTop - eleStyle.paddingBottom + 'px',
|
height:
|
||||||
width: boxRect.width - eleStyle.borderLeft - eleStyle.borderRight - eleStyle.paddingLeft - eleStyle.paddingRight + 'px'
|
boxRect.height -
|
||||||
|
eleStyle.borderTop -
|
||||||
|
eleStyle.borderBottom -
|
||||||
|
eleStyle.paddingTop -
|
||||||
|
eleStyle.paddingBottom +
|
||||||
|
'px',
|
||||||
|
width:
|
||||||
|
boxRect.width -
|
||||||
|
eleStyle.borderLeft -
|
||||||
|
eleStyle.borderRight -
|
||||||
|
eleStyle.paddingLeft -
|
||||||
|
eleStyle.paddingRight +
|
||||||
|
'px',
|
||||||
});
|
});
|
||||||
|
|
||||||
assign(this.node.style, {
|
assign(this.node.style, {
|
||||||
top: boxRect.top - eleStyle.marginTop + 'px',
|
top: boxRect.top - eleStyle.marginTop + 'px',
|
||||||
left: boxRect.left - eleStyle.marginLeft + 'px'
|
left: boxRect.left - eleStyle.marginLeft + 'px',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,7 +244,7 @@ class ElementOverlay {
|
||||||
top: Number.POSITIVE_INFINITY,
|
top: Number.POSITIVE_INFINITY,
|
||||||
right: Number.NEGATIVE_INFINITY,
|
right: Number.NEGATIVE_INFINITY,
|
||||||
bottom: Number.NEGATIVE_INFINITY,
|
bottom: Number.NEGATIVE_INFINITY,
|
||||||
left: Number.POSITIVE_INFINITY
|
left: Number.POSITIVE_INFINITY,
|
||||||
};
|
};
|
||||||
|
|
||||||
elements.forEach((element, index) => {
|
elements.forEach((element, index) => {
|
||||||
|
|
|
@ -44,7 +44,7 @@ import {
|
||||||
ClassComponent,
|
ClassComponent,
|
||||||
IncompleteClassComponent,
|
IncompleteClassComponent,
|
||||||
ForwardRef,
|
ForwardRef,
|
||||||
MemoComponent
|
MemoComponent,
|
||||||
} from '../../../inula/src/renderer/vnode/VNodeTags';
|
} from '../../../inula/src/renderer/vnode/VNodeTags';
|
||||||
import { pickElement } from './pickElement';
|
import { pickElement } from './pickElement';
|
||||||
|
|
||||||
|
@ -101,11 +101,7 @@ function parseCompAttrs(id: number) {
|
||||||
function calculateNextValue(editValue, value, attrPath) {
|
function calculateNextValue(editValue, value, attrPath) {
|
||||||
let nextState;
|
let nextState;
|
||||||
const editValueType = typeof editValue;
|
const editValueType = typeof editValue;
|
||||||
if (
|
if (editValueType === 'string' || editValueType === 'undefined' || editValueType === 'boolean') {
|
||||||
editValueType === 'string' ||
|
|
||||||
editValueType === 'undefined' ||
|
|
||||||
editValueType === 'boolean'
|
|
||||||
) {
|
|
||||||
nextState = value;
|
nextState = value;
|
||||||
} else if (editValueType === 'number') {
|
} else if (editValueType === 'number') {
|
||||||
const numValue = Number(value);
|
const numValue = Number(value);
|
||||||
|
@ -125,10 +121,7 @@ function calculateNextValue(editValue, value, attrPath) {
|
||||||
nextState = newValue;
|
nextState = newValue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error(
|
console.error('The dev tools tried to edit a non-editable value, this is a bug, please report.', editValue);
|
||||||
'The dev tools tried to edit a non-editable value, this is a bug, please report.',
|
|
||||||
editValue
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return nextState;
|
return nextState;
|
||||||
}
|
}
|
||||||
|
@ -153,10 +146,7 @@ function modifyVNodeAttrs(data) {
|
||||||
const nextState = calculateNextValue(editValue, value, path.slice(1));
|
const nextState = calculateNextValue(editValue, value, path.slice(1));
|
||||||
helper.updateHooks(vNode, path[0], nextState);
|
helper.updateHooks(vNode, path[0], nextState);
|
||||||
} else {
|
} else {
|
||||||
console.error(
|
console.error('The dev tools tried to edit a non-editable hook, this is a bug, please report.', hooks);
|
||||||
'The dev tools tried to edit a non-editable hook, this is a bug, please report.',
|
|
||||||
hooks
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else if (type === ModifyState) {
|
} else if (type === ModifyState) {
|
||||||
const oldState = vNode.state || {};
|
const oldState = vNode.state || {};
|
||||||
|
@ -190,11 +180,7 @@ function logComponentData(id: number) {
|
||||||
* @param {Array<string | number>} path 路径
|
* @param {Array<string | number>} path 路径
|
||||||
* @param {string} attrsName 值的类型(props 或者 hooks)
|
* @param {string} attrsName 值的类型(props 或者 hooks)
|
||||||
*/
|
*/
|
||||||
const getValueByPath = (
|
const getValueByPath = (vNode: VNode, path: Array<string | number>, attrsName: string) => {
|
||||||
vNode: VNode,
|
|
||||||
path: Array<string | number>,
|
|
||||||
attrsName: string
|
|
||||||
) => {
|
|
||||||
if (attrsName === 'Props') {
|
if (attrsName === 'Props') {
|
||||||
return path.reduce((previousValue, currentValue) => {
|
return path.reduce((previousValue, currentValue) => {
|
||||||
return previousValue[currentValue];
|
return previousValue[currentValue];
|
||||||
|
@ -218,12 +204,7 @@ const getValueByPath = (
|
||||||
* @param {Array<string | number>} path 值的路径
|
* @param {Array<string | number>} path 值的路径
|
||||||
* @param {string} attrsName 值的类型
|
* @param {string} attrsName 值的类型
|
||||||
*/
|
*/
|
||||||
function logDataWithPath(
|
function logDataWithPath(id: number, itemName: string, path: Array<string | number>, attrsName: string) {
|
||||||
id: number,
|
|
||||||
itemName: string,
|
|
||||||
path: Array<string | number>,
|
|
||||||
attrsName: string
|
|
||||||
) {
|
|
||||||
const vNode = queryVNode(id);
|
const vNode = queryVNode(id);
|
||||||
if (vNode === null) {
|
if (vNode === null) {
|
||||||
console.warn(`Could not find vNode with id "${id}"`);
|
console.warn(`Could not find vNode with id "${id}"`);
|
||||||
|
@ -246,11 +227,7 @@ function logDataWithPath(
|
||||||
* @param {Array<string |number>} path 值的路径
|
* @param {Array<string |number>} path 值的路径
|
||||||
* @param {string} attrsName 值的类型
|
* @param {string} attrsName 值的类型
|
||||||
*/
|
*/
|
||||||
function storeDataWithPath(
|
function storeDataWithPath(id: number, path: Array<string | number>, attrsName: string) {
|
||||||
id: number,
|
|
||||||
path: Array<string | number>,
|
|
||||||
attrsName: string
|
|
||||||
) {
|
|
||||||
const vNode = queryVNode(id);
|
const vNode = queryVNode(id);
|
||||||
if (vNode === null) {
|
if (vNode === null) {
|
||||||
console.warn(`Could not find vNode with id "${id}"`);
|
console.warn(`Could not find vNode with id "${id}"`);
|
||||||
|
@ -284,9 +261,7 @@ export function getElement(travelVNodeTree, treeRoot: VNode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(node: VNode) =>
|
(node: VNode) => node.realNode != null && (Object.keys(node.realNode).length > 0 || node.realNode.size > 0)
|
||||||
node.realNode != null &&
|
|
||||||
(Object.keys(node.realNode).length > 0 || node.realNode.size > 0)
|
|
||||||
);
|
);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,20 +56,14 @@ const inspectVNode = () => {
|
||||||
|
|
||||||
let currentPanel = null;
|
let currentPanel = null;
|
||||||
|
|
||||||
chrome.devtools.inspectedWindow.eval(
|
chrome.devtools.inspectedWindow.eval('window.__INULA_DEV_HOOK__', function (isInula, error) {
|
||||||
'window.__INULA_DEV_HOOK__',
|
|
||||||
function (isInula, error) {
|
|
||||||
if (!isInula || panelCreated) {
|
if (!isInula || panelCreated) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
panelCreated = true;
|
panelCreated = true;
|
||||||
chrome.devtools.panels.create(
|
chrome.devtools.panels.create('Inula', '', 'panel.html', extensionPanel => {
|
||||||
'Inula',
|
extensionPanel.onShown.addListener(panel => {
|
||||||
'',
|
|
||||||
'panel.html',
|
|
||||||
(extensionPanel) => {
|
|
||||||
extensionPanel.onShown.addListener((panel) => {
|
|
||||||
if (currentPanel === panel) {
|
if (currentPanel === panel) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -78,15 +72,10 @@ chrome.devtools.inspectedWindow.eval(
|
||||||
const element = createElement(Panel, { viewSource, inspectVNode });
|
const element = createElement(Panel, { viewSource, inspectVNode });
|
||||||
render(element, container);
|
render(element, container);
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
chrome.devtools.panels.create(
|
chrome.devtools.panels.create('InulaX', '', 'panelX.html', extensionPanel => {
|
||||||
'InulaX',
|
extensionPanel.onShown.addListener(panel => {
|
||||||
'',
|
|
||||||
'panelX.html',
|
|
||||||
(extensionPanel) => {
|
|
||||||
extensionPanel.onShown.addListener((panel) => {
|
|
||||||
if (currentPanel === panel) {
|
if (currentPanel === panel) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +84,5 @@ chrome.devtools.inspectedWindow.eval(
|
||||||
const element = createElement(PanelX, {});
|
const element = createElement(PanelX, {});
|
||||||
render(element, container);
|
render(element, container);
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
);
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
|
@ -13,15 +13,7 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import { useState, useEffect, useRef, memo, useMemo, useCallback, useReducer } from 'openinula';
|
||||||
useState,
|
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
memo,
|
|
||||||
useMemo,
|
|
||||||
useCallback,
|
|
||||||
useReducer,
|
|
||||||
} from 'openinula';
|
|
||||||
import VTree, { IData } from '../components/VTree';
|
import VTree, { IData } from '../components/VTree';
|
||||||
import Search from '../components/Search';
|
import Search from '../components/Search';
|
||||||
import ComponentInfo from '../components/ComponentInfo';
|
import ComponentInfo from '../components/ComponentInfo';
|
||||||
|
@ -134,26 +126,20 @@ interface IIdToNodeMap {
|
||||||
* @param {null | HTMLElement} resizeElement 要改变宽度的页面元素
|
* @param {null | HTMLElement} resizeElement 要改变宽度的页面元素
|
||||||
* @param {number} percentage 宽度占比
|
* @param {number} percentage 宽度占比
|
||||||
*/
|
*/
|
||||||
const setResizePCTForElement = (
|
const setResizePCTForElement = (resizeElement: null | HTMLElement, percentage: number): void => {
|
||||||
resizeElement: null | HTMLElement,
|
|
||||||
percentage: number
|
|
||||||
): void => {
|
|
||||||
if (resizeElement !== null) {
|
if (resizeElement !== null) {
|
||||||
resizeElement.style.setProperty(
|
resizeElement.style.setProperty('--horizontal-percentage', `${percentage}`);
|
||||||
'--horizontal-percentage',
|
|
||||||
`${percentage}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function resizeReducer(state: ResizeState, action: ResizeAction): ResizeState {
|
function resizeReducer(state: ResizeState, action: ResizeAction): ResizeState {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case "START_RESIZE":
|
case 'START_RESIZE':
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
isResizing: action.payload,
|
isResizing: action.payload,
|
||||||
};
|
};
|
||||||
case "SET_HORIZONTAL_PERCENTAGE":
|
case 'SET_HORIZONTAL_PERCENTAGE':
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
horizontalPercentage: action.payload,
|
horizontalPercentage: action.payload,
|
||||||
|
@ -183,11 +169,7 @@ function Panel({ viewSource, inspectVNode }) {
|
||||||
const [isPicking, setPicking] = useState(false);
|
const [isPicking, setPicking] = useState(false);
|
||||||
const [source, setSource] = useState<Source>(null);
|
const [source, setSource] = useState<Source>(null);
|
||||||
const idToTreeNodeMapref = useRef<IIdToNodeMap>({});
|
const idToTreeNodeMapref = useRef<IIdToNodeMap>({});
|
||||||
const [state, dispatch] = useReducer(
|
const [state, dispatch] = useReducer(resizeReducer, null, initResizeState);
|
||||||
resizeReducer,
|
|
||||||
null,
|
|
||||||
initResizeState
|
|
||||||
);
|
|
||||||
const pageRef = useRef<null | HTMLElement>(null);
|
const pageRef = useRef<null | HTMLElement>(null);
|
||||||
const treeRef = useRef<null | HTMLElement>(null);
|
const treeRef = useRef<null | HTMLElement>(null);
|
||||||
|
|
||||||
|
@ -214,16 +196,12 @@ function Panel({ viewSource, inspectVNode }) {
|
||||||
// 对象数据只是记录了引用,内容可能在后续被修改,打印字符串可以获取当前真正内容,不被后续修改影响
|
// 对象数据只是记录了引用,内容可能在后续被修改,打印字符串可以获取当前真正内容,不被后续修改影响
|
||||||
logger.info(JSON.stringify(payload));
|
logger.info(JSON.stringify(payload));
|
||||||
if (payload) {
|
if (payload) {
|
||||||
const {type, data} = payload;
|
const { type, data } = payload;
|
||||||
if (type === AllVNodeTreeInfos) {
|
if (type === AllVNodeTreeInfos) {
|
||||||
const idToTreeNodeMap = idToTreeNodeMapref.current;
|
const idToTreeNodeMap = idToTreeNodeMapref.current;
|
||||||
const nextIdToTreeNodeMap: IIdToNodeMap = {};
|
const nextIdToTreeNodeMap: IIdToNodeMap = {};
|
||||||
const allTreeData = data.reduce((pre, current) => {
|
const allTreeData = data.reduce((pre, current) => {
|
||||||
const parsedTreeData = parseVNodeData(
|
const parsedTreeData = parseVNodeData(current, idToTreeNodeMap, nextIdToTreeNodeMap);
|
||||||
current,
|
|
||||||
idToTreeNodeMap,
|
|
||||||
nextIdToTreeNodeMap
|
|
||||||
);
|
|
||||||
return pre.concat(parsedTreeData);
|
return pre.concat(parsedTreeData);
|
||||||
}, []);
|
}, []);
|
||||||
idToTreeNodeMapref.current = nextIdToTreeNodeMap;
|
idToTreeNodeMapref.current = nextIdToTreeNodeMap;
|
||||||
|
@ -284,10 +262,7 @@ function Panel({ viewSource, inspectVNode }) {
|
||||||
setShowItems(info.visibleItems);
|
setShowItems(info.visibleItems);
|
||||||
};
|
};
|
||||||
|
|
||||||
const parents = useMemo(
|
const parents = useMemo(() => getParents(selectComp, parsedVNodeData), [selectComp, parsedVNodeData]);
|
||||||
() => getParents(selectComp, parsedVNodeData),
|
|
||||||
[selectComp, parsedVNodeData]
|
|
||||||
);
|
|
||||||
|
|
||||||
const viewSourceFunction = useMemo(
|
const viewSourceFunction = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
|
@ -338,7 +313,7 @@ function Panel({ viewSource, inspectVNode }) {
|
||||||
const mouseAbscissa = event.clientX - left;
|
const mouseAbscissa = event.clientX - left;
|
||||||
|
|
||||||
const pageSizeMin = MINIMUM_SIZE;
|
const pageSizeMin = MINIMUM_SIZE;
|
||||||
const pageSizeMax = width-MINIMUM_SIZE;
|
const pageSizeMax = width - MINIMUM_SIZE;
|
||||||
|
|
||||||
const isMouseInPage = mouseAbscissa > pageSizeMin && mouseAbscissa < pageSizeMax;
|
const isMouseInPage = mouseAbscissa > pageSizeMin && mouseAbscissa < pageSizeMax;
|
||||||
|
|
||||||
|
@ -394,16 +369,10 @@ function Panel({ viewSource, inspectVNode }) {
|
||||||
{`${matchItems.indexOf(currentItem) + 1}/${matchItems.length}`}
|
{`${matchItems.indexOf(currentItem) + 1}/${matchItems.length}`}
|
||||||
</span>
|
</span>
|
||||||
<div className={styles.divider} />
|
<div className={styles.divider} />
|
||||||
<button
|
<button className={styles.searchAction} onClick={onSelectLast}>
|
||||||
className={styles.searchAction}
|
|
||||||
onClick={onSelectLast}
|
|
||||||
>
|
|
||||||
<Arrow direction={'up'} />
|
<Arrow direction={'up'} />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button className={styles.searchAction} onClick={onSelectNext}>
|
||||||
className={styles.searchAction}
|
|
||||||
onClick={onSelectNext}
|
|
||||||
>
|
|
||||||
<Arrow direction={'down'} />
|
<Arrow direction={'down'} />
|
||||||
</button>
|
</button>
|
||||||
<button className={styles.searchAction} onClick={onClear}>
|
<button className={styles.searchAction} onClick={onClear}>
|
||||||
|
|
|
@ -51,11 +51,7 @@ export function initBackgroundConnection(type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let reconnectionTimes = 0;
|
let reconnectionTimes = 0;
|
||||||
export function postMessageToBackground(
|
export function postMessageToBackground(type: string, data?: any, inulaX?: boolean) {
|
||||||
type: string,
|
|
||||||
data?: any,
|
|
||||||
inulaX?: boolean
|
|
||||||
) {
|
|
||||||
try {
|
try {
|
||||||
const payload = data
|
const payload = data
|
||||||
? { type, tabId: chrome.devtools.inspectedWindow.tabId, data }
|
? { type, tabId: chrome.devtools.inspectedWindow.tabId, data }
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
import { useState } from 'openinula';
|
import { useState } from 'openinula';
|
||||||
import styles from './PanelX.less';
|
import styles from './PanelX.less';
|
||||||
import { Tree } from './Tree';
|
import { Tree } from './Tree';
|
||||||
import {displayValue, omit} from './utils';
|
import { displayValue, omit } from './utils';
|
||||||
|
|
||||||
type Mutation = {
|
type Mutation = {
|
||||||
mutation: boolean;
|
mutation: boolean;
|
||||||
|
@ -118,11 +118,7 @@ export function DiffTree({
|
||||||
fontFamily: 'monospace',
|
fontFamily: 'monospace',
|
||||||
}}
|
}}
|
||||||
className={`${
|
className={`${
|
||||||
expanded
|
expanded ? 'expanded' : `not-expanded ${mutated && !isPrimitive && !expanded ? styles.changed : ''}`
|
||||||
? 'expanded'
|
|
||||||
: `not-expanded ${
|
|
||||||
mutated && !isPrimitive && !expanded ? styles.changed : ''
|
|
||||||
}`
|
|
||||||
}`}
|
}`}
|
||||||
onClick={e => {
|
onClick={e => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
@ -165,11 +161,7 @@ export function DiffTree({
|
||||||
// 如果至少有一个是复杂变量,则需要展开按钮
|
// 如果至少有一个是复杂变量,则需要展开按钮
|
||||||
<>
|
<>
|
||||||
{forcedExpand ? '' : expanded ? <span>▼</span> : <span>▶</span>}
|
{forcedExpand ? '' : expanded ? <span>▼</span> : <span>▶</span>}
|
||||||
{index === 0 || index ? (
|
{index === 0 || index ? <b className={styles.purple}>{displayValue(index, search)}: </b> : ''}
|
||||||
<b className={styles.purple}>{displayValue(index, search)}: </b>
|
|
||||||
) : (
|
|
||||||
''
|
|
||||||
)}
|
|
||||||
{isArray ? (
|
{isArray ? (
|
||||||
// 如果都是数组进行比较
|
// 如果都是数组进行比较
|
||||||
expanded ? (
|
expanded ? (
|
||||||
|
@ -210,17 +202,10 @@ export function DiffTree({
|
||||||
) : isSet ? (
|
) : isSet ? (
|
||||||
expanded ? (
|
expanded ? (
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>{forcedLabel || `Set(${mutation.to?.values.length})`}</div>
|
||||||
{forcedLabel || `Set(${mutation.to?.values.length})`}
|
{Array(Math.max(mutation.from?.values.length, mutation.to?.values.length))
|
||||||
</div>
|
|
||||||
{Array(
|
|
||||||
Math.max(
|
|
||||||
mutation.from?.values.length,
|
|
||||||
mutation.to?.values.length
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.fill(true)
|
.fill(true)
|
||||||
.map((i ,index) => (
|
.map((i, index) => (
|
||||||
<div>
|
<div>
|
||||||
{mutation.values[index].mutation ? (
|
{mutation.values[index].mutation ? (
|
||||||
<DiffTree
|
<DiffTree
|
||||||
|
@ -244,22 +229,13 @@ export function DiffTree({
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<span>
|
<span>{forcedLabel || `Set(${mutation.to?.values.length})`}</span>
|
||||||
{forcedLabel || `Set(${mutation.to?.values.length})`}
|
|
||||||
</span>
|
|
||||||
)
|
)
|
||||||
) : isMap ? (
|
) : isMap ? (
|
||||||
expanded ? (
|
expanded ? (
|
||||||
<>
|
<>
|
||||||
<span>
|
<span>{forcedLabel || `Map(${mutation.to?.entries.length})`}</span>
|
||||||
{forcedLabel || `Map(${mutation.to?.entries.length})`}
|
{Array(Math.max(mutation.from?.entries.length, mutation.to?.entries.length))
|
||||||
</span>
|
|
||||||
{Array(
|
|
||||||
Math.max(
|
|
||||||
mutation.from?.entries.length,
|
|
||||||
mutation.to?.entries.length
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.fill(true)
|
.fill(true)
|
||||||
.map((i, index) =>
|
.map((i, index) =>
|
||||||
mutation.entries[index].mutation ? (
|
mutation.entries[index].mutation ? (
|
||||||
|
@ -289,9 +265,7 @@ export function DiffTree({
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<span>
|
<span>{forcedLabel || `Map(${mutation.to?.entries.length})`}</span>
|
||||||
{forcedLabel || `Map(${mutation.to?.entries.length})`}
|
|
||||||
</span>
|
|
||||||
)
|
)
|
||||||
) : expanded ? (
|
) : expanded ? (
|
||||||
// 如果都是 object 进行比较
|
// 如果都是 object 进行比较
|
||||||
|
|
|
@ -22,7 +22,7 @@ import {
|
||||||
} from '../panelConnection';
|
} from '../panelConnection';
|
||||||
import { Table } from './Table';
|
import { Table } from './Table';
|
||||||
import { Tree } from './Tree';
|
import { Tree } from './Tree';
|
||||||
import {fullTextSearch, omit} from './utils';
|
import { fullTextSearch, omit } from './utils';
|
||||||
import styles from './PanelX.less';
|
import styles from './PanelX.less';
|
||||||
import { Checkbox } from '../utils/Checkbox';
|
import { Checkbox } from '../utils/Checkbox';
|
||||||
import { DiffTree } from './DiffTree';
|
import { DiffTree } from './DiffTree';
|
||||||
|
@ -57,9 +57,7 @@ function extractDataByType(message, search) {
|
||||||
>
|
>
|
||||||
<Tree
|
<Tree
|
||||||
data={{
|
data={{
|
||||||
Action: `${message.data.action.action}${
|
Action: `${message.data.action.action}${message.data.fromQueue ? ' (queued)' : ''}`,
|
||||||
message.data.fromQueue ? ' (queued)' : ''
|
|
||||||
}`
|
|
||||||
}}
|
}}
|
||||||
expand={true}
|
expand={true}
|
||||||
indent={-4}
|
indent={-4}
|
||||||
|
@ -92,7 +90,7 @@ function extractDataByType(message, search) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <span className={styles.grey}>N/A</span>
|
return <span className={styles.grey}>N/A</span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function EventLog({ setNextStore, setEventFilter, eventFilter }) {
|
export default function EventLog({ setNextStore, setEventFilter, eventFilter }) {
|
||||||
|
@ -204,7 +202,8 @@ export default function EventLog({ setNextStore, setEventFilter, eventFilter })
|
||||||
timestamp: event.timestamp,
|
timestamp: event.timestamp,
|
||||||
type: event.message.type,
|
type: event.message.type,
|
||||||
time: `${date.toLocaleTimeString()} - ${date.toLocaleDateString()}`,
|
time: `${date.toLocaleTimeString()} - ${date.toLocaleDateString()}`,
|
||||||
state: event.message.type === eventTypes.STATE_CHANGE ? (
|
state:
|
||||||
|
event.message.type === eventTypes.STATE_CHANGE ? (
|
||||||
<DiffTree
|
<DiffTree
|
||||||
mutation={event.message.data.change.mutation}
|
mutation={event.message.data.change.mutation}
|
||||||
expand={true}
|
expand={true}
|
||||||
|
@ -235,10 +234,7 @@ export default function EventLog({ setNextStore, setEventFilter, eventFilter })
|
||||||
{event.message.data.store.id}
|
{event.message.data.store.id}
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
additionalData: extractDataByType(
|
additionalData: extractDataByType(event.message, eventFilter['fulltext']),
|
||||||
event.message,
|
|
||||||
eventFilter['fulltext']
|
|
||||||
),
|
|
||||||
storeId: event.message.data.store.id,
|
storeId: event.message.data.store.id,
|
||||||
event,
|
event,
|
||||||
};
|
};
|
||||||
|
@ -271,7 +267,7 @@ export default function EventLog({ setNextStore, setEventFilter, eventFilter })
|
||||||
<span className={styles.grey}>{' | '}</span>
|
<span className={styles.grey}>{' | '}</span>
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
cursor: 'pointer'
|
cursor: 'pointer',
|
||||||
}}
|
}}
|
||||||
onClick={e => {
|
onClick={e => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
@ -342,18 +338,14 @@ export default function EventLog({ setNextStore, setEventFilter, eventFilter })
|
||||||
{Object.values(eventTypes).map(eventType => {
|
{Object.values(eventTypes).map(eventType => {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
className={`${styles.filterButton} ${
|
className={`${styles.filterButton} ${usedTypes[eventType] ? '' : styles.grey} ${
|
||||||
usedTypes[eventType] ? '' : styles.grey
|
|
||||||
} ${
|
|
||||||
eventFilter['message.type'] === eventType ? styles.active : ''
|
eventFilter['message.type'] === eventType ? styles.active : ''
|
||||||
}`}
|
}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
addFilter('message.type', eventType);
|
addFilter('message.type', eventType);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{`${eventType.replace('inulax ', '')}(${
|
{`${eventType.replace('inulax ', '')}(${usedTypes[eventType] || 0})`}
|
||||||
usedTypes[eventType] || 0
|
|
||||||
})`}
|
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@ -374,20 +366,12 @@ export default function EventLog({ setNextStore, setEventFilter, eventFilter })
|
||||||
type: data.type,
|
type: data.type,
|
||||||
store: {
|
store: {
|
||||||
actions: Object.fromEntries(
|
actions: Object.fromEntries(
|
||||||
Object.entries(message.data.store.$config.actions).map(
|
Object.entries(message.data.store.$config.actions).map(([id, action]) => {
|
||||||
([id, action]) => {
|
return [id, (action as string).replace(/\{.*}/gms, '{...}').replace('function ', '')];
|
||||||
return [
|
})
|
||||||
id,
|
|
||||||
(action as string).replace(/\{.*}/gms, '{...}').replace('function ', ''),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
computed: Object.fromEntries(
|
computed: Object.fromEntries(
|
||||||
Object.keys(message.data.store.$c).map(key => [
|
Object.keys(message.data.store.$c).map(key => [key, message.data.store.expanded[key]])
|
||||||
key,
|
|
||||||
message.data.store.expanded[key],
|
|
||||||
])
|
|
||||||
),
|
),
|
||||||
state: message.data.store.$s,
|
state: message.data.store.$s,
|
||||||
id: message.data.store.id,
|
id: message.data.store.id,
|
||||||
|
|
|
@ -73,7 +73,7 @@ export function Modal({
|
||||||
<input
|
<input
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
onKeyPress={({key}) => {
|
onKeyPress={({ key }) => {
|
||||||
if (key === 'Enter') {
|
if (key === 'Enter') {
|
||||||
tryGatherData();
|
tryGatherData();
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,12 +32,7 @@ export default function PanelX() {
|
||||||
{
|
{
|
||||||
id: 'stores',
|
id: 'stores',
|
||||||
title: 'Stores',
|
title: 'Stores',
|
||||||
getComponent: () => (
|
getComponent: () => <Stores nextStoreId={nextStoreId} showFilteredEvents={showFilterEvents} />,
|
||||||
<Stores
|
|
||||||
nextStoreId={nextStoreId}
|
|
||||||
showFilteredEvents={showFilterEvents}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'events',
|
id: 'events',
|
||||||
|
@ -60,10 +55,7 @@ export default function PanelX() {
|
||||||
<div style={{ marginBottom: '10px' }}>
|
<div style={{ marginBottom: '10px' }}>
|
||||||
{tabs.map(tab =>
|
{tabs.map(tab =>
|
||||||
tab.id === active ? (
|
tab.id === active ? (
|
||||||
<button
|
<button className={`${styles.tab} ${styles.active}`} disabled={true}>
|
||||||
className={`${styles.tab} ${styles.active}`}
|
|
||||||
disabled={true}
|
|
||||||
>
|
|
||||||
{tab.title}
|
{tab.title}
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useState } from 'openinula';
|
import { useState } from 'openinula';
|
||||||
import {Tree} from './Tree';
|
import { Tree } from './Tree';
|
||||||
import styles from './PanelX.less';
|
import styles from './PanelX.less';
|
||||||
|
|
||||||
type displayKeysType = [string, string][];
|
type displayKeysType = [string, string][];
|
||||||
|
@ -84,14 +84,10 @@ export function Table({
|
||||||
<span></span>
|
<span></span>
|
||||||
{data.map(row => (
|
{data.map(row => (
|
||||||
<div
|
<div
|
||||||
className={`${styles.row} ${
|
className={`${styles.row} ${keyToDisplay === row[dataKey] ? styles.active : ''}`}
|
||||||
keyToDisplay === row[dataKey] ? styles.active : ''
|
|
||||||
}`}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setManualOverride(true);
|
setManualOverride(true);
|
||||||
setKeyToDisplay(
|
setKeyToDisplay(keyToDisplay === row[dataKey] ? null : row[dataKey]);
|
||||||
keyToDisplay === row[dataKey] ? null : row[dataKey]
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className={styles.cell}>{row?.[attr] || ''}</div>
|
<div className={styles.cell}>{row?.[attr] || ''}</div>
|
||||||
|
@ -119,11 +115,7 @@ export function Table({
|
||||||
<div className={styles.row}>
|
<div className={styles.row}>
|
||||||
<div className={styles.cell}>
|
<div className={styles.cell}>
|
||||||
<Tree
|
<Tree
|
||||||
data={
|
data={displayDataProcessor ? displayDataProcessor(displayRow) : displayRow}
|
||||||
displayDataProcessor
|
|
||||||
? displayDataProcessor(displayRow)
|
|
||||||
: displayRow
|
|
||||||
}
|
|
||||||
indent={displayRow[displayKeys[0][0]]}
|
indent={displayRow[displayKeys[0][0]]}
|
||||||
expand={true}
|
expand={true}
|
||||||
search={search}
|
search={search}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
import { useState } from 'openinula';
|
import { useState } from 'openinula';
|
||||||
import styles from './PanelX.less';
|
import styles from './PanelX.less';
|
||||||
import {Modal} from './Modal';
|
import { Modal } from './Modal';
|
||||||
import { displayValue, omit } from './utils';
|
import { displayValue, omit } from './utils';
|
||||||
|
|
||||||
export function Tree({
|
export function Tree({
|
||||||
|
@ -36,7 +36,7 @@ export function Tree({
|
||||||
expand?: boolean;
|
expand?: boolean;
|
||||||
search?: string;
|
search?: string;
|
||||||
forcedExpand?: boolean;
|
forcedExpand?: boolean;
|
||||||
className?: string | undefined
|
className?: string | undefined;
|
||||||
omitAttrs?: string[];
|
omitAttrs?: string[];
|
||||||
onEdit?: (path: any[], value: any) => void | null;
|
onEdit?: (path: any[], value: any) => void | null;
|
||||||
forcedLabel?: string | number | null;
|
forcedLabel?: string | number | null;
|
||||||
|
@ -71,11 +71,7 @@ export function Tree({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{new Array(Math.max(indent, 0)).fill(<span> </span>)}
|
{new Array(Math.max(indent, 0)).fill(<span> </span>)}
|
||||||
{forcedExpand || isVNode ? null : expanded ? (
|
{forcedExpand || isVNode ? null : expanded ? <span>▼</span> : <span>▶</span>}
|
||||||
<span>▼</span>
|
|
||||||
) : (
|
|
||||||
<span>▶</span>
|
|
||||||
)}
|
|
||||||
{index === 0 || index ? (
|
{index === 0 || index ? (
|
||||||
<>
|
<>
|
||||||
<b className={styles.purple}>{displayValue(index, search)}: </b>
|
<b className={styles.purple}>{displayValue(index, search)}: </b>
|
||||||
|
@ -138,7 +134,7 @@ export function Tree({
|
||||||
{data.entries.map(([key, value]) => {
|
{data.entries.map(([key, value]) => {
|
||||||
return (
|
return (
|
||||||
<Tree
|
<Tree
|
||||||
data={{key, value}}
|
data={{ key, value }}
|
||||||
indent={indent + 4}
|
indent={indent + 4}
|
||||||
search={search}
|
search={search}
|
||||||
className={className}
|
className={className}
|
||||||
|
|
|
@ -25,7 +25,7 @@ export function highlight(source, search) {
|
||||||
const parts = source.split(search);
|
const parts = source.split(search);
|
||||||
const result = [];
|
const result = [];
|
||||||
|
|
||||||
for (let i= 0; i < parts.length * 2 - 1; i++) {
|
for (let i = 0; i < parts.length * 2 - 1; i++) {
|
||||||
if (i % 2) {
|
if (i % 2) {
|
||||||
result.push(<span className={styles.highlighted}>{search}</span>);
|
result.push(<span className={styles.highlighted}>{search}</span>);
|
||||||
} else {
|
} else {
|
||||||
|
@ -38,11 +38,7 @@ export function highlight(source, search) {
|
||||||
|
|
||||||
export function displayValue(val: any, search = '') {
|
export function displayValue(val: any, search = '') {
|
||||||
if (typeof val === 'boolean') {
|
if (typeof val === 'boolean') {
|
||||||
return (
|
return <span>{highlight(val ? 'true' : 'false', search)}</span>;
|
||||||
<span>
|
|
||||||
{highlight(val ? 'true' : 'false', search)}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val === '') {
|
if (val === '') {
|
||||||
|
@ -62,10 +58,7 @@ export function displayValue(val: any, search = '') {
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
<i>ƒ</i>
|
<i>ƒ</i>
|
||||||
{highlight(
|
{highlight(val.match(/^function\s?\([\w,]*\)/g)[0].replace(/^function\s?/, ''), search)}
|
||||||
val.match(/^function\s?\([\w,]*\)/g)[0].replace(/^function\s?/, ''),
|
|
||||||
search
|
|
||||||
)}
|
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -75,7 +68,10 @@ export function displayValue(val: any, search = '') {
|
||||||
return <span className={styles.blue}>{highlight('' + val, search)}</span>;
|
return <span className={styles.blue}>{highlight('' + val, search)}</span>;
|
||||||
}
|
}
|
||||||
if (typeof val === 'function') {
|
if (typeof val === 'function') {
|
||||||
const args = val.toString().match(/^function\s?\([\w,]*\)/g)[0].replace(/^function\s?/, '');
|
const args = val
|
||||||
|
.toString()
|
||||||
|
.match(/^function\s?\([\w,]*\)/g)[0]
|
||||||
|
.replace(/^function\s?/, '');
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
<i>ƒ</i>
|
<i>ƒ</i>
|
||||||
|
@ -108,9 +104,7 @@ export function fullTextSearch(value, search) {
|
||||||
return value.values.some(val => fullTextSearch(val, search));
|
return value.values.some(val => fullTextSearch(val, search));
|
||||||
}
|
}
|
||||||
if (value?._type === 'Map') {
|
if (value?._type === 'Map') {
|
||||||
return value.entries.some(
|
return value.entries.some((key, val) => fullTextSearch(key, search) || fullTextSearch(val, search));
|
||||||
(key, val) => fullTextSearch(key, search) || fullTextSearch(val, search)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return Object.values(value).some(val => fullTextSearch(val, search));
|
return Object.values(value).some(val => fullTextSearch(val, search));
|
||||||
}
|
}
|
||||||
|
@ -165,8 +159,7 @@ export function stringify(data) {
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
<span className={styles.purple}>{key}</span>:{' '}
|
<span className={styles.purple}>{key}</span>: {`Array(${value.length})`}
|
||||||
{`Array(${value.length})`}
|
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -188,16 +181,14 @@ export function stringify(data) {
|
||||||
if ((value as any)?._type === 'Set') {
|
if ((value as any)?._type === 'Set') {
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
<span className={styles.purple}>{key}</span>:{' '}
|
<span className={styles.purple}>{key}</span>: {`Set(${(value as Set<any>).size})`}
|
||||||
{`Set(${(value as Set<any>).size})`}
|
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ((value as any)?._type === 'Map') {
|
if ((value as any)?._type === 'Map') {
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
<span className={styles.purple}>{key}</span>:{' '}
|
<span className={styles.purple}>{key}</span>: {`Map(${(value as Map<any, any>).size})`}
|
||||||
{`Map(${(value as Map<any, any>).size})`}
|
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,12 +52,12 @@ export type IAttr = {
|
||||||
| {
|
| {
|
||||||
type: ShowAsStringType;
|
type: ShowAsStringType;
|
||||||
value: string;
|
value: string;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
type: 'boolean';
|
type: 'boolean';
|
||||||
value: boolean;
|
value: boolean;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
type ShowType = ShowAsStringType | 'boolean';
|
type ShowType = ShowAsStringType | 'boolean';
|
||||||
|
|
||||||
|
@ -79,10 +79,7 @@ const getObjectKeys = (attr: Record<string, any>): Array<string | number | symbo
|
||||||
let current = attr;
|
let current = attr;
|
||||||
try {
|
try {
|
||||||
while (current != null) {
|
while (current != null) {
|
||||||
const currentKeys = [
|
const currentKeys = [...Object.keys(current), ...Object.getOwnPropertySymbols(current)];
|
||||||
...Object.keys(current),
|
|
||||||
...Object.getOwnPropertySymbols(current)
|
|
||||||
];
|
|
||||||
const descriptors = Object.getOwnPropertyDescriptors(current);
|
const descriptors = Object.getOwnPropertyDescriptors(current);
|
||||||
currentKeys.forEach(key => {
|
currentKeys.forEach(key => {
|
||||||
// @ts-ignore key 可以为 symbol 类型
|
// @ts-ignore key 可以为 symbol 类型
|
||||||
|
@ -99,10 +96,7 @@ const getObjectKeys = (attr: Record<string, any>): Array<string | number | symbo
|
||||||
};
|
};
|
||||||
|
|
||||||
// 用于比较两个 key 值的顺序
|
// 用于比较两个 key 值的顺序
|
||||||
export function sortKeys(
|
export function sortKeys(firstKey: string | number | symbol, secondKey: string | number | symbol): number {
|
||||||
firstKey: string | number | symbol,
|
|
||||||
secondKey: string | number | symbol
|
|
||||||
): number {
|
|
||||||
if (firstKey.toString() > secondKey.toString()) {
|
if (firstKey.toString() > secondKey.toString()) {
|
||||||
return 1;
|
return 1;
|
||||||
} else if (secondKey.toString() > firstKey.toString()) {
|
} else if (secondKey.toString() > firstKey.toString()) {
|
||||||
|
@ -137,11 +131,7 @@ const parseSubTitle = <T>(attr: T) => {
|
||||||
} else if (AttrType === 'function') {
|
} else if (AttrType === 'function') {
|
||||||
const funcName = attr['name'];
|
const funcName = attr['name'];
|
||||||
return `ƒ ${funcName}() {}`;
|
return `ƒ ${funcName}() {}`;
|
||||||
} else if (
|
} else if (AttrType === 'boolean' || AttrType === 'number' || AttrType === 'undefined') {
|
||||||
AttrType === 'boolean' ||
|
|
||||||
AttrType === 'number' ||
|
|
||||||
AttrType === 'undefined'
|
|
||||||
) {
|
|
||||||
return `${attr}`;
|
return `${attr}`;
|
||||||
} else if (AttrType === 'object') {
|
} else if (AttrType === 'object') {
|
||||||
if (attr === null) {
|
if (attr === null) {
|
||||||
|
@ -179,24 +169,13 @@ const parseSubTitle = <T>(attr: T) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseSubAttr = (
|
const parseSubAttr = (attr: any, parentIndentation: number, attrName: string, result: IAttr[], hIndex?: number) => {
|
||||||
attr: any,
|
|
||||||
parentIndentation: number,
|
|
||||||
attrName: string,
|
|
||||||
result: IAttr[],
|
|
||||||
hIndex?: number
|
|
||||||
) => {
|
|
||||||
const AttrType = typeof attr;
|
const AttrType = typeof attr;
|
||||||
let value: any;
|
let value: any;
|
||||||
let showType: any;
|
let showType: any;
|
||||||
let addSubState;
|
let addSubState;
|
||||||
|
|
||||||
if (
|
if (AttrType === 'boolean' || AttrType === 'number' || AttrType === 'undefined' || AttrType === 'string') {
|
||||||
AttrType === 'boolean' ||
|
|
||||||
AttrType === 'number' ||
|
|
||||||
AttrType === 'undefined' ||
|
|
||||||
AttrType === 'string'
|
|
||||||
) {
|
|
||||||
value = attr;
|
value = attr;
|
||||||
showType = AttrType;
|
showType = AttrType;
|
||||||
} else if (AttrType === 'function') {
|
} else if (AttrType === 'function') {
|
||||||
|
@ -308,11 +287,7 @@ export function parseAttr(rootAttr: any) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseHooks(
|
export function parseHooks(hooks: Hook<any, any>[] | null, depContexts: Array<ContextType<any>> | null, getHookInfo) {
|
||||||
hooks: Hook<any, any>[] | null,
|
|
||||||
depContexts: Array<ContextType<any>> | null,
|
|
||||||
getHookInfo
|
|
||||||
) {
|
|
||||||
const result: IAttr[] = [];
|
const result: IAttr[] = [];
|
||||||
const indentation = 0;
|
const indentation = 0;
|
||||||
if (depContexts !== null && depContexts?.length > 0) {
|
if (depContexts !== null && depContexts?.length > 0) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ import {
|
||||||
ForwardRef,
|
ForwardRef,
|
||||||
FunctionComponent,
|
FunctionComponent,
|
||||||
MemoComponent,
|
MemoComponent,
|
||||||
SuspenseComponent
|
SuspenseComponent,
|
||||||
} from '../../../inula/src/renderer/vnode/VNodeTags';
|
} from '../../../inula/src/renderer/vnode/VNodeTags';
|
||||||
|
|
||||||
export type NameObj = {
|
export type NameObj = {
|
||||||
|
@ -61,13 +61,7 @@ const componentType = [
|
||||||
MemoComponent,
|
MemoComponent,
|
||||||
];
|
];
|
||||||
|
|
||||||
const badgeNameArr: Array<string> = [
|
const badgeNameArr: Array<string> = ['withRouter(', 'SideEffect(', 'Connect(', 'injectIntl(', 'Pure('];
|
||||||
'withRouter(',
|
|
||||||
'SideEffect(',
|
|
||||||
'Connect(',
|
|
||||||
'injectIntl(',
|
|
||||||
'Pure(',
|
|
||||||
];
|
|
||||||
|
|
||||||
export function isUserComponent(tag: string) {
|
export function isUserComponent(tag: string) {
|
||||||
return componentType.includes(tag);
|
return componentType.includes(tag);
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface IArrow {
|
interface IArrow {
|
||||||
direction: 'up' | 'down'
|
direction: 'up' | 'down';
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Arrow({ direction: director }: IArrow) {
|
export default function Arrow({ direction: director }: IArrow) {
|
||||||
|
@ -26,8 +26,8 @@ export default function Arrow({ direction: director }: IArrow) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='1rem' height='1rem'>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="1rem" height="1rem">
|
||||||
<path d={d} fill='currentColor' />
|
<path d={d} fill="currentColor" />
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
|
|
||||||
export default function Close() {
|
export default function Close() {
|
||||||
return (
|
return (
|
||||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='1rem' height='1rem'>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="1rem" height="1rem">
|
||||||
<path d='M4 3 L3 4 L7 8 L3 12 L4 13 L8 9 L12 13 L13 12 L9 8 L13 4 L12 3 L8 7z' fill='currentColor' />
|
<path d="M4 3 L3 4 L7 8 L3 12 L4 13 L8 9 L12 13 L13 12 L9 8 L13 4 L12 3 L8 7z" fill="currentColor" />
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,15 @@
|
||||||
|
|
||||||
export default function Debug() {
|
export default function Debug() {
|
||||||
return (
|
return (
|
||||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='1.3rem' height='1.3rem' margin-top='0.4rem'>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="1.3rem" height="1.3rem" margin-top="0.4rem">
|
||||||
<path d='M0 0h24v24H0z' fill='none'/>
|
<path d="M0 0h24v24H0z" fill="none" />
|
||||||
<path d='M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4 41 15.59 3l-2.17 2.17c12 96 5.06 12.49 5 12 5c-.49 0-.96.06-1.41.17L8.41
|
<path
|
||||||
|
d="M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4 41 15.59 3l-2.17 2.17c12 96 5.06 12.49 5 12 5c-.49 0-.96.06-1.41.17L8.41
|
||||||
3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34 04.67 09 1H4v2h2.81c1.04
|
3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34 04.67 09 1H4v2h2.81c1.04
|
||||||
1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6
|
1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6
|
||||||
8h-4v-2h4v2zm0-4h-4v-2h4v2z'
|
8h-4v-2h4v2zm0-4h-4v-2h4v2z"
|
||||||
fill='currentColor' />
|
fill="currentColor"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,12 +15,15 @@
|
||||||
|
|
||||||
export default function Discover() {
|
export default function Discover() {
|
||||||
return (
|
return (
|
||||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='1.3rem' height='1.3rem'>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="1.3rem" height="1.3rem">
|
||||||
<path d='M0 0h24v24H0z' fill='none' />
|
<path d="M0 0h24v24H0z" fill="none" />
|
||||||
<path d='M15.5 14h-.79l-.28-.27C15 41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91
|
<path
|
||||||
|
d="M15.5 14h-.79l-.28-.27C15 41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91
|
||||||
16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99
|
16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99
|
||||||
5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z'
|
5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"
|
||||||
fill='#343231' p-id='4151' />
|
fill="#343231"
|
||||||
|
p-id="4151"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,12 +15,14 @@
|
||||||
|
|
||||||
export default function Eye() {
|
export default function Eye() {
|
||||||
return (
|
return (
|
||||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='1.3rem' height='1.3rem'>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="1.3rem" height="1.3rem">
|
||||||
<path d='M0 0h24v24H0z' fill='none'/>
|
<path d="M0 0h24v24H0z" fill="none" />
|
||||||
<path d='M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12
|
<path
|
||||||
|
d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12
|
||||||
17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3
|
17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3
|
||||||
3-1.34 3-3-1.34-3-3-3z'
|
3-1.34 3-3-1.34-3-3-3z"
|
||||||
fill='currentColor' />
|
fill="currentColor"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,12 @@
|
||||||
|
|
||||||
export default function Location() {
|
export default function Location() {
|
||||||
return (
|
return (
|
||||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='1.3rem' height='1.3rem'>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="1.3rem" height="1.3rem">
|
||||||
<path d='M0 0h24v24H0z' fill='none' />
|
<path d="M0 0h24v24H0z" fill="none" />
|
||||||
<path d='M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z'
|
<path
|
||||||
fill='currentColor' />
|
d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,20 @@
|
||||||
|
|
||||||
export default function Operation() {
|
export default function Operation() {
|
||||||
return (
|
return (
|
||||||
<svg t="1669105013009" className="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2821" width="1rem" height="1rem">
|
<svg
|
||||||
<path d="M177.23392 943.96416c25.93792 0 50.3296-10.13248 68.70528-28.50816l208.18432-208.18944 29.36832-29.36832 38.90688 14.51008a323.70688 323.70688 0 0 0 112.85504 20.18304c86.48704 0 167.90528-33.664 229.05344-94.90432 83.4816-83.39456 113.4592-203.37152 83.99872-312.96512L795.60704 457.4208l-45.77792 45.77792-45.85984-45.77792-137.41568-137.41056-45.77792-45.87008 45.77792-45.7728 152.61696-152.61696a327.44448 327.44448 0 0 0-83.90656-10.99264c-86.48704 0-167.81824 33.66912-228.9664 94.90944C316.96896 248.89856 287.68256 383.13472 331.5712 501.57056l14.42816 38.90688-29.37344 29.36832-208.09728 208.19456c-18.37568 18.37568-28.51328 42.76736-28.51328 68.70528 0 25.93792 10.13248 50.3296 28.51328 68.7104a96.41472 96.41472 0 0 0 68.70528 28.50816m0 64.76288a161.67936 161.67936 0 0 1-114.57024-47.41632c-63.21152-63.29856-63.21152-165.84704 0-229.05344L270.848 524.07296c-51.18976-138.01984-21.30432-299.31008 89.57952-410.27072C436.352 37.9648 535.808 0 635.25888 0c68.4544 0 136.81664 17.95072 197.53472 53.77024l-220.38016 220.37504 137.41568 137.41568 220.38528-220.38016c88.02816 149.0944 68.0192 344.30976-60.12416 472.3712-75.83744 75.83232-175.37536 113.79712-274.83136 113.79712a389.6064 389.6064 0 0 1-135.35232-24.2176l-208.18944 208.18432c-31.60576 31.60064-73.088 47.4112-114.4832 47.4112z" p-id="2822"/>
|
t="1669105013009"
|
||||||
|
className="icon"
|
||||||
|
viewBox="0 0 1024 1024"
|
||||||
|
version="1.1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
p-id="2821"
|
||||||
|
width="1rem"
|
||||||
|
height="1rem"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M177.23392 943.96416c25.93792 0 50.3296-10.13248 68.70528-28.50816l208.18432-208.18944 29.36832-29.36832 38.90688 14.51008a323.70688 323.70688 0 0 0 112.85504 20.18304c86.48704 0 167.90528-33.664 229.05344-94.90432 83.4816-83.39456 113.4592-203.37152 83.99872-312.96512L795.60704 457.4208l-45.77792 45.77792-45.85984-45.77792-137.41568-137.41056-45.77792-45.87008 45.77792-45.7728 152.61696-152.61696a327.44448 327.44448 0 0 0-83.90656-10.99264c-86.48704 0-167.81824 33.66912-228.9664 94.90944C316.96896 248.89856 287.68256 383.13472 331.5712 501.57056l14.42816 38.90688-29.37344 29.36832-208.09728 208.19456c-18.37568 18.37568-28.51328 42.76736-28.51328 68.70528 0 25.93792 10.13248 50.3296 28.51328 68.7104a96.41472 96.41472 0 0 0 68.70528 28.50816m0 64.76288a161.67936 161.67936 0 0 1-114.57024-47.41632c-63.21152-63.29856-63.21152-165.84704 0-229.05344L270.848 524.07296c-51.18976-138.01984-21.30432-299.31008 89.57952-410.27072C436.352 37.9648 535.808 0 635.25888 0c68.4544 0 136.81664 17.95072 197.53472 53.77024l-220.38016 220.37504 137.41568 137.41568 220.38528-220.38016c88.02816 149.0944 68.0192 344.30976-60.12416 472.3712-75.83744 75.83232-175.37536 113.79712-274.83136 113.79712a389.6064 389.6064 0 0 1-135.35232-24.2176l-208.18944 208.18432c-31.60576 31.60064-73.088 47.4112-114.4832 47.4112z"
|
||||||
|
p-id="2822"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,23 +15,23 @@
|
||||||
|
|
||||||
export default function Select() {
|
export default function Select() {
|
||||||
return (
|
return (
|
||||||
<svg width='1rem' height='1rem' viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'>
|
<svg width="1rem" height="1rem" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g fill='none' fill-rule='evenodd'>
|
<g fill="none" fill-rule="evenodd">
|
||||||
<g stroke='currentColor'>
|
<g stroke="currentColor">
|
||||||
<path
|
<path
|
||||||
stroke-width='.291'
|
stroke-width=".291"
|
||||||
fill='currentColor'
|
fill="currentColor"
|
||||||
fill-rule='nonzero'
|
fill-rule="nonzero"
|
||||||
stroke-linecap='round'
|
stroke-linecap="round"
|
||||||
stroke-linejoin='round'
|
stroke-linejoin="round"
|
||||||
d='M6 6l3.014 9 2.508-3.533L15 8.791z'
|
d="M6 6l3.014 9 2.508-3.533L15 8.791z"
|
||||||
></path>
|
></path>
|
||||||
<path stroke-width='2' d='M10.417 10.417l2.87 2.87L15 15'></path>
|
<path stroke-width="2" d="M10.417 10.417l2.87 2.87L15 15"></path>
|
||||||
</g>
|
</g>
|
||||||
<path
|
<path
|
||||||
d='M12.188 0A2.812 2.812 0 0 1 15 2.813V5h-1V2.857A1.857 1.857 0 0 0 12.143 1H2.857A1.857 1.857 0 0 0 1 2.857v9.286C1 13.169 1.831 14 2.857 14H5v1H2.812A2.812 2.812 0 0 1 0 12.187V2.813A2.812 2.812 0 0 1 2.813 0h9.374z'
|
d="M12.188 0A2.812 2.812 0 0 1 15 2.813V5h-1V2.857A1.857 1.857 0 0 0 12.143 1H2.857A1.857 1.857 0 0 0 1 2.857v9.286C1 13.169 1.831 14 2.857 14H5v1H2.812A2.812 2.812 0 0 1 0 12.187V2.813A2.812 2.812 0 0 1 2.813 0h9.374z"
|
||||||
fill='currentColor'
|
fill="currentColor"
|
||||||
fill-rule='nonzero'
|
fill-rule="nonzero"
|
||||||
></path>
|
></path>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface IArrow {
|
interface IArrow {
|
||||||
director: 'right' | 'down'
|
director: 'right' | 'down';
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Triangle({ director }: IArrow) {
|
export default function Triangle({ director }: IArrow) {
|
||||||
|
@ -25,8 +25,8 @@ export default function Triangle({ director }: IArrow) {
|
||||||
d = 'm0 2h16 l-8 12 z';
|
d = 'm0 2h16 l-8 12 z';
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='8px' height='8px'>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="8px" height="8px">
|
||||||
<path d={d} fill='currentColor' />
|
<path d={d} fill="currentColor" />
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,15 +27,15 @@ export function Checkbox({ value }) {
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
verticalAlign: 'sub',
|
verticalAlign: 'sub',
|
||||||
marginBottom: '0.1rem'
|
marginBottom: '0.1rem',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
backgroundColor: value? 'black' : 'white',
|
backgroundColor: value ? 'black' : 'white',
|
||||||
position: 'relative'
|
position: 'relative',
|
||||||
}}
|
}}
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createContext } from "openinula";
|
import { createContext } from 'openinula';
|
||||||
|
|
||||||
const PickElementContext = createContext(null);
|
const PickElementContext = createContext(null);
|
||||||
PickElementContext.displayName = 'PickElementContext';
|
PickElementContext.displayName = 'PickElementContext';
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {createContext} from 'openinula';
|
import { createContext } from 'openinula';
|
||||||
|
|
||||||
const ViewSourceContext = createContext(null);
|
const ViewSourceContext = createContext(null);
|
||||||
ViewSourceContext.displayName = 'ViewSourceContext';
|
ViewSourceContext.displayName = 'ViewSourceContext';
|
||||||
|
|
|
@ -31,11 +31,7 @@ export function injectSrc(src) {
|
||||||
script.remove();
|
script.remove();
|
||||||
};
|
};
|
||||||
|
|
||||||
ifNullThrows(
|
ifNullThrows(document.head || document.getElementsByName('head')[0] || document.documentElement).appendChild(script);
|
||||||
document.head
|
|
||||||
|| document.getElementsByName('head')[0]
|
|
||||||
|| document.documentElement
|
|
||||||
).appendChild(script);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function injectCode(code) {
|
export function injectCode(code) {
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
* 同时也无法在运行时打断点,需要适当的日志辅助开发和定位问题
|
* 同时也无法在运行时打断点,需要适当的日志辅助开发和定位问题
|
||||||
*/
|
*/
|
||||||
interface LoggerType {
|
interface LoggerType {
|
||||||
error: typeof console.error,
|
error: typeof console.error;
|
||||||
info: typeof console.info,
|
info: typeof console.info;
|
||||||
log: typeof console.log,
|
log: typeof console.log;
|
||||||
warn: typeof console.warn
|
warn: typeof console.warn;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createLogger(id: string): LoggerType {
|
export function createLogger(id: string): LoggerType {
|
||||||
|
|
|
@ -34,7 +34,7 @@ export function packagePayload(payload: PayloadType, from: string, inulaX?: bool
|
||||||
return {
|
return {
|
||||||
type: devTools,
|
type: devTools,
|
||||||
payload,
|
payload,
|
||||||
from
|
from,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,28 +26,12 @@ function handleBuildDir() {
|
||||||
if (!isBuildExist) {
|
if (!isBuildExist) {
|
||||||
fs.mkdirSync(staticDir);
|
fs.mkdirSync(staticDir);
|
||||||
}
|
}
|
||||||
|
fs.copyFileSync(path.join(__dirname, 'src', 'panel', 'panel.html'), path.join(staticDir, 'panel.html'));
|
||||||
|
fs.copyFileSync(path.join(__dirname, 'src', 'panelX', 'panel.html'), path.join(staticDir, 'panelX.html'));
|
||||||
|
fs.copyFileSync(path.join(__dirname, 'src', 'main', 'main.html'), path.join(staticDir, 'main.html'));
|
||||||
|
fs.copyFileSync(path.join(__dirname, 'src', 'manifest.json'), path.join(staticDir, 'manifest.json'));
|
||||||
fs.copyFileSync(
|
fs.copyFileSync(
|
||||||
path.join(__dirname, 'src', 'panel', 'panel.html'),
|
path.join(__dirname, '../inula/build/umd', 'inula.development.js'),
|
||||||
path.join(staticDir, 'panel.html')
|
|
||||||
);
|
|
||||||
fs.copyFileSync(
|
|
||||||
path.join(__dirname, 'src', 'panelX', 'panel.html'),
|
|
||||||
path.join(staticDir, 'panelX.html')
|
|
||||||
);
|
|
||||||
fs.copyFileSync(
|
|
||||||
path.join(__dirname, 'src', 'main', 'main.html'),
|
|
||||||
path.join(staticDir, 'main.html')
|
|
||||||
);
|
|
||||||
fs.copyFileSync(
|
|
||||||
path.join(__dirname, 'src', 'manifest.json'),
|
|
||||||
path.join(staticDir, 'manifest.json')
|
|
||||||
);
|
|
||||||
fs.copyFileSync(
|
|
||||||
path.join(
|
|
||||||
__dirname,
|
|
||||||
'../inula/build/umd',
|
|
||||||
'inula.development.js'
|
|
||||||
),
|
|
||||||
path.join(staticDir, 'inula.development.js')
|
path.join(staticDir, 'inula.development.js')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +49,7 @@ const config = {
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, './build'),
|
path: path.resolve(__dirname, './build'),
|
||||||
filename: '[name].js'
|
filename: '[name].js',
|
||||||
},
|
},
|
||||||
mode: 'development',
|
mode: 'development',
|
||||||
devtool: 'inline-source-map',
|
devtool: 'inline-source-map',
|
||||||
|
|
|
@ -24,7 +24,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, './dist'),
|
path: path.resolve(__dirname, './dist'),
|
||||||
filename: '[name].js'
|
filename: '[name].js',
|
||||||
},
|
},
|
||||||
mode: 'development',
|
mode: 'development',
|
||||||
devtool: 'source-map',
|
devtool: 'source-map',
|
||||||
|
@ -73,5 +73,5 @@ module.exports = {
|
||||||
open: 'panel.html',
|
open: 'panel.html',
|
||||||
port: 9000,
|
port: 9000,
|
||||||
magicHtml: true,
|
magicHtml: true,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
["@babel/preset-env", {
|
||||||
|
"targets": {
|
||||||
|
"node": "current"
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"@babel/preset-typescript",
|
||||||
|
"@babel/preset-react"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"@babel/plugin-syntax-jsx",
|
||||||
|
[
|
||||||
|
"@babel/plugin-transform-react-jsx",
|
||||||
|
{
|
||||||
|
"runtime": "automatic",
|
||||||
|
"importSource": "openinula"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
["@babel/plugin-proposal-class-properties", { "loose": true }],
|
||||||
|
["@babel/plugin-proposal-private-methods", { "loose": true }],
|
||||||
|
["@babel/plugin-proposal-private-property-in-object", { "loose": true }],
|
||||||
|
"@babel/plugin-transform-object-assign",
|
||||||
|
"@babel/plugin-transform-object-super",
|
||||||
|
["@babel/plugin-proposal-object-rest-spread", { "loose": true, "useBuiltIns": true }],
|
||||||
|
["@babel/plugin-transform-template-literals", { "loose": true }],
|
||||||
|
"@babel/plugin-transform-arrow-functions",
|
||||||
|
"@babel/plugin-transform-literals",
|
||||||
|
"@babel/plugin-transform-for-of",
|
||||||
|
"@babel/plugin-transform-block-scoped-functions",
|
||||||
|
"@babel/plugin-transform-classes",
|
||||||
|
"@babel/plugin-transform-shorthand-properties",
|
||||||
|
"@babel/plugin-transform-computed-properties",
|
||||||
|
"@babel/plugin-transform-parameters",
|
||||||
|
["@babel/plugin-transform-spread", { "loose": true, "useBuiltIns": true }],
|
||||||
|
["@babel/plugin-transform-block-scoping", { "throwIfClosureRequired": false }],
|
||||||
|
["@babel/plugin-transform-destructuring", { "loose": true, "useBuiltIns": true }],
|
||||||
|
"@babel/plugin-transform-runtime",
|
||||||
|
"@babel/plugin-proposal-nullish-coalescing-operator",
|
||||||
|
"@babel/plugin-proposal-optional-chaining"
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,74 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
|
||||||
*
|
|
||||||
* openInula is licensed under Mulan PSL v2.
|
|
||||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
* You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
*
|
|
||||||
* http://license.coscl.org.cn/MulanPSL2
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
||||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
||||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the Mulan PSL v2 for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
extends: [
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:@typescript-eslint/eslint-recommended',
|
|
||||||
'plugin:@typescript-eslint/recommended',
|
|
||||||
'prettier',
|
|
||||||
],
|
|
||||||
root: true,
|
|
||||||
|
|
||||||
plugins: ['jest', 'no-for-of-loops', 'no-function-declare-after-return', 'react', '@typescript-eslint'],
|
|
||||||
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
parserOptions: {
|
|
||||||
ecmaVersion: 8,
|
|
||||||
sourceType: 'module',
|
|
||||||
ecmaFeatures: {
|
|
||||||
jsx: true,
|
|
||||||
modules: true,
|
|
||||||
experimentalObjectRestSpread: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
env: {
|
|
||||||
browser: true,
|
|
||||||
jest: true,
|
|
||||||
node: true,
|
|
||||||
es6: true,
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
||||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
||||||
'@typescript-eslint/no-empty-function': 'off',
|
|
||||||
semi: ['warn', 'always'],
|
|
||||||
quotes: ['warn', 'single'],
|
|
||||||
'accessor-pairs': 'off',
|
|
||||||
'brace-style': ['error', '1tbs'],
|
|
||||||
'func-style': ['warn', 'declaration', { allowArrowFunctions: true }],
|
|
||||||
'max-lines-per-function': 'off',
|
|
||||||
'object-curly-newline': 'off',
|
|
||||||
// 尾随逗号
|
|
||||||
'comma-dangle': ['error', 'only-multiline'],
|
|
||||||
|
|
||||||
'no-constant-condition': 'off',
|
|
||||||
'no-for-of-loops/no-for-of-loops': 'error',
|
|
||||||
'no-function-declare-after-return/no-function-declare-after-return': 'error',
|
|
||||||
},
|
|
||||||
globals: {
|
|
||||||
isDev: true,
|
|
||||||
isTest: true,
|
|
||||||
},
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: ['scripts/tests/**/*.js'],
|
|
||||||
globals: {
|
|
||||||
container: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
|
||||||
*
|
|
||||||
* openInula is licensed under Mulan PSL v2.
|
|
||||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
* You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
*
|
|
||||||
* http://license.coscl.org.cn/MulanPSL2
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
||||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
||||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the Mulan PSL v2 for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
printWidth: 120, // 一行120字符数,如果超过会进行换行
|
|
||||||
tabWidth: 2, // tab等2个空格
|
|
||||||
useTabs: false, // 用空格缩进行
|
|
||||||
semi: true, // 行尾使用分号
|
|
||||||
singleQuote: true, // 字符串使用单引号
|
|
||||||
quoteProps: 'as-needed', // 仅在需要时在对象属性添加引号
|
|
||||||
jsxSingleQuote: false, // 在JSX中使用双引号
|
|
||||||
trailingComma: 'es5', // 使用尾逗号(对象、数组等)
|
|
||||||
bracketSpacing: true, // 对象的括号间增加空格
|
|
||||||
bracketSameLine: false, // 将多行JSX元素的>放在最后一行的末尾
|
|
||||||
arrowParens: 'avoid', // 在唯一的arrow函数参数周围省略括号
|
|
||||||
vueIndentScriptAndStyle: false, // 不缩进Vue文件中的<script>和<style>标记内的代码
|
|
||||||
endOfLine: 'lf', // 仅限换行(\n)
|
|
||||||
};
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import dts from 'rollup-plugin-dts';
|
||||||
|
|
||||||
|
function deleteFolder(filePath) {
|
||||||
|
if (fs.existsSync(filePath)) {
|
||||||
|
if (fs.lstatSync(filePath).isDirectory()) {
|
||||||
|
const files = fs.readdirSync(filePath);
|
||||||
|
files.forEach(file => {
|
||||||
|
const nextFilePath = path.join(filePath, file);
|
||||||
|
const states = fs.lstatSync(nextFilePath);
|
||||||
|
if (states.isDirectory()) {
|
||||||
|
deleteFolder(nextFilePath);
|
||||||
|
} else {
|
||||||
|
fs.unlinkSync(nextFilePath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fs.rmdirSync(filePath);
|
||||||
|
} else if (fs.lstatSync(filePath).isFile()) {
|
||||||
|
fs.unlinkSync(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param folders {string[]}
|
||||||
|
* @returns {{buildEnd(): void, name: string}}
|
||||||
|
*/
|
||||||
|
export function cleanUp(folders) {
|
||||||
|
return {
|
||||||
|
name: 'clean-up',
|
||||||
|
buildEnd() {
|
||||||
|
folders.forEach(f => deleteFolder(f));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildTypeConfig() {
|
||||||
|
return {
|
||||||
|
input: './build/@types/index.d.ts',
|
||||||
|
output: {
|
||||||
|
file: './build/@types/index.d.ts',
|
||||||
|
format: 'es',
|
||||||
|
},
|
||||||
|
plugins: [dts(), cleanUp(['./build/@types/example', './build/@types/src'])],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default [buildTypeConfig()];
|
|
@ -13,44 +13,49 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Inula, { useState } from 'openinula';
|
import { useState } from 'openinula';
|
||||||
import { IntlProvider } from "../index";
|
import { IntlProvider } from '../index';
|
||||||
import zh from "./locale/zh";
|
import zh from './locale/zh';
|
||||||
import en from "./locale/en";
|
import en from './locale/en';
|
||||||
import Example1 from "./components/Example1";
|
import Example1 from './components/Example1';
|
||||||
import Example2 from "./components/Example2";
|
import Example2 from './components/Example2';
|
||||||
import Example3 from "./components/Example3";
|
import Example3 from './components/Example3';
|
||||||
import Example4 from "./components/Example4";
|
import Example4 from './components/Example4';
|
||||||
import Example5 from "./components/Example5";
|
import Example5 from './components/Example5';
|
||||||
import Example6 from "./components/Example6";
|
import Example6 from './components/Example6';
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const [locale, setLocale] = useState('zh');
|
const [locale, setLocale] = useState('zh');
|
||||||
const handleChange = () => {
|
const handleChange = () => {
|
||||||
locale === 'zh' ? setLocale('en') : setLocale('zh');
|
locale === 'zh' ? setLocale('en') : setLocale('zh');
|
||||||
};
|
};
|
||||||
const message = locale === 'zh' ? zh : en
|
const message = locale === 'zh' ? zh : en;
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<IntlProvider locale={locale} messages={locale === 'zh' ? zh : en}>
|
<IntlProvider locale={locale} messages={locale === 'zh' ? zh : en}>
|
||||||
<header>Inula-Intl API Test Demo</header>
|
<header>Inula-Intl API Test Demo</header>
|
||||||
|
<div className="container">
|
||||||
<div className='container'>
|
<Example1 />
|
||||||
<Example1/>
|
<Example2 />
|
||||||
<Example2/>
|
<Example3 locale={locale} setLocale={setLocale} />
|
||||||
<Example3/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className='container'>
|
<div className="container">
|
||||||
<Example4 locale={locale} messages={message}/>
|
{/*<Example4 locale={locale} messages={message} />*/}
|
||||||
<Example5/>
|
<Example5 />
|
||||||
<Example6 locale={{ locale }} messages={message}/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className='button'>
|
<div className="button">
|
||||||
<button onClick={handleChange}>切换语言</button>
|
<button onClick={handleChange}>切换语言</button>
|
||||||
</div>
|
</div>
|
||||||
</IntlProvider>
|
</IntlProvider>
|
||||||
|
<div className="container">
|
||||||
|
<Example4 locale={locale} messages={message} />
|
||||||
|
</div>
|
||||||
|
<div className="container">
|
||||||
|
<Example6 locale={{ locale }} messages={message} />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default App
|
export default App;
|
||||||
|
|
|
@ -13,16 +13,16 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Inula from "openinula";
|
import { useIntl } from '../../index';
|
||||||
import { useIntl } from "../../index";
|
|
||||||
|
|
||||||
const Example1 = () => {
|
const Example1 = () => {
|
||||||
const { i18n } = useIntl();
|
const i18n = useIntl();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<h2>useIntl方式测试Demo</h2>
|
<h2>useIntl方式测试Demo</h2>
|
||||||
<pre>{i18n.formatMessage({ id: 'text1' })}</pre>
|
<pre>{i18n.formatMessage({ id: 'text1' })}</pre>
|
||||||
|
<pre>{i18n.$t({ id: 'text1' })}</pre>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,16 +12,17 @@
|
||||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
import Inula from "openinula";
|
import { FormattedMessage } from '../../index';
|
||||||
import { FormattedMessage } from "../../index";
|
|
||||||
|
|
||||||
const Example2= () => {
|
|
||||||
|
|
||||||
|
const Example2 = () => {
|
||||||
return (
|
return (
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<h2>FormattedMessage方式测试Demo</h2>
|
<h2>FormattedMessage方式测试Demo</h2>
|
||||||
<pre>
|
<pre>
|
||||||
<FormattedMessage id='text2'/>
|
<FormattedMessage id="text2" />
|
||||||
|
</pre>
|
||||||
|
<pre>
|
||||||
|
<FormattedMessage id="text5" values={{ testComponent1: <b>123</b>, testComponent2: <b>456</b> }} />
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -13,24 +13,26 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Inula from 'openinula';
|
import { FormattedMessage } from '../../index';
|
||||||
import { FormattedMessage } from "../../index";
|
|
||||||
|
|
||||||
const Example3 = (props) => {
|
const Example3 = props => {
|
||||||
const { locale, setLocale } = props;
|
const { locale, setLocale } = props;
|
||||||
return (
|
return (
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<h2>FormattedMessage方式测试Demo</h2>
|
<h2>FormattedMessage方式测试Demo</h2>
|
||||||
<pre>
|
<pre>
|
||||||
<button className="testButton" onClick={() => {
|
<button
|
||||||
setLocale(locale === 'zh' ? 'en' : 'zh')
|
className="testButton"
|
||||||
}}>
|
onClick={() => {
|
||||||
<FormattedMessage id={'button'}/>
|
setLocale(locale === 'zh' ? 'en' : 'zh');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FormattedMessage id={'button'} />
|
||||||
</button>
|
</button>
|
||||||
<br/>
|
<br />
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default Example3;
|
export default Example3;
|
||||||
|
|
|
@ -13,10 +13,9 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Inula from "openinula";
|
import { createIntl } from '../../index';
|
||||||
import { createIntl } from "../../index";
|
|
||||||
|
|
||||||
const Example4 = (props) => {
|
const Example4 = props => {
|
||||||
// 受渲染时机影响,createIntl方式需控制时序,否则慢一拍
|
// 受渲染时机影响,createIntl方式需控制时序,否则慢一拍
|
||||||
const intl = createIntl({ ...props });
|
const intl = createIntl({ ...props });
|
||||||
const msg = intl.formatMessage({ id: 'text3' });
|
const msg = intl.formatMessage({ id: 'text3' });
|
||||||
|
|
|
@ -13,23 +13,16 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Inula, { Component } from 'openinula';
|
|
||||||
import { injectIntl } from '../../index';
|
import { injectIntl } from '../../index';
|
||||||
|
|
||||||
class Example5 extends Component<any, any, any> {
|
const Example5 = ({ intl }) => {
|
||||||
public constructor(props: any, context) {
|
// 使用intl.formatMessage来获取国际化消息
|
||||||
super(props, context);
|
console.log(intl + '------------intl-------------');
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { intl } = this.props as any;
|
|
||||||
return (
|
return (
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<h2>injectIntl方式测试Demo</h2>
|
<h2>injectIntl方式测试Demo</h2>
|
||||||
<pre>{intl.formatMessage({ id: 'text4' })}</pre>
|
<pre>{intl.formatMessage({ id: 'text4' })}</pre>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
export default injectIntl(Example5);
|
export default injectIntl(Example5);
|
||||||
|
|
|
@ -13,25 +13,20 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Inula from "openinula";
|
import { createIntl, createIntlCache, RawIntlProvider } from '../../index';
|
||||||
import { createIntl, createIntlCache, RawIntlProvider } from "../../index";
|
import Example6Child from './Example6Child';
|
||||||
import Example6Child from "./Example6Child";
|
|
||||||
|
|
||||||
const Example6 = (props: any) => {
|
const Example6 = (props: any) => {
|
||||||
|
|
||||||
const { locale, messages } = props;
|
const { locale, messages } = props;
|
||||||
|
|
||||||
const cache = createIntlCache();
|
const cache = createIntlCache();
|
||||||
let i18n = createIntl(
|
const i18n = createIntl({ locale: locale, messages: messages }, cache);
|
||||||
{ locale: locale, messages: messages },
|
|
||||||
cache
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RawIntlProvider value={i18n}>
|
<RawIntlProvider value={i18n}>
|
||||||
<Example6Child/>
|
<Example6Child />
|
||||||
</RawIntlProvider>
|
</RawIntlProvider>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default Example6;
|
export default Example6;
|
||||||
|
|
|
@ -13,11 +13,10 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useIntl } from "../../index";
|
import { useIntl } from '../../index';
|
||||||
|
|
||||||
const Example6Child = (props: any) => {
|
const Example6Child = () => {
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
const {formatMessage} = useIntl();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card">
|
<div className="card">
|
||||||
|
@ -25,6 +24,6 @@ const Example6Child = (props: any) => {
|
||||||
<pre>{formatMessage({ id: 'text4' })}</pre>
|
<pre>{formatMessage({ id: 'text4' })}</pre>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default Example6Child;
|
export default Example6Child;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue