nsgm-cli 1.0.27 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/.babelrc +13 -0
  2. package/LICENSE +201 -201
  3. package/README.md +161 -162
  4. package/client/layout/index.tsx +245 -0
  5. package/client/redux/reducers.ts +5 -0
  6. package/{generation/client → client}/redux/store.ts +50 -44
  7. package/{generation/client → client}/redux/template/manage/actions.ts +190 -190
  8. package/{generation/client → client}/redux/template/manage/reducers.ts +118 -118
  9. package/{generation/client → client}/redux/template/manage/types.ts +24 -24
  10. package/client/service/template/manage.ts +97 -0
  11. package/{generation/client → client}/styled/common.ts +27 -28
  12. package/client/styled/layout/index.ts +26 -0
  13. package/{generation/client → client}/styled/template/manage.ts +51 -51
  14. package/client/utils/common.ts +86 -0
  15. package/client/utils/cookie.ts +52 -0
  16. package/{generation/client → client}/utils/fetch.ts +25 -25
  17. package/client/utils/menu.tsx +27 -0
  18. package/generation/.DS_Store +0 -0
  19. package/generation/.babelrc +3 -2
  20. package/generation/README.md +19 -18
  21. package/generation/app.js +2 -2
  22. package/generation/client/redux/reducers.ts +5 -5
  23. package/generation/client/utils/menu.tsx +27 -26
  24. package/generation/gitignore +5 -4
  25. package/generation/mysql.config.js +13 -12
  26. package/generation/next.config.js +6 -6
  27. package/generation/package.json +25 -20
  28. package/generation/project.config.js +12 -12
  29. package/generation/server/rest.js +20 -20
  30. package/generation/server/utils/common.js +7 -0
  31. package/generation/tsconfig.json +30 -29
  32. package/index.js +10 -10
  33. package/lib/args.d.ts +6 -6
  34. package/lib/args.js +47 -47
  35. package/lib/generate.d.ts +3 -3
  36. package/lib/generate.js +735 -590
  37. package/lib/index.d.ts +2 -2
  38. package/lib/index.js +259 -182
  39. package/lib/server/db.d.ts +5 -5
  40. package/lib/server/db.js +110 -47
  41. package/lib/server/graphql.d.ts +7 -7
  42. package/lib/server/graphql.js +119 -119
  43. package/lib/server/plugins/date.d.ts +5 -5
  44. package/lib/server/plugins/date.js +16 -16
  45. package/lib/tsconfig.build.tsbuildinfo +1 -0
  46. package/mysql.config.js +14 -14
  47. package/next-env.d.ts +6 -0
  48. package/next.config.js +194 -174
  49. package/package.json +125 -113
  50. package/{generation/pages → pages}/_app.tsx +44 -44
  51. package/{generation/pages → pages}/_document.tsx +4 -2
  52. package/pages/index.tsx +68 -0
  53. package/{generation/pages → pages}/template/manage.tsx +278 -280
  54. package/project.config.js +14 -14
  55. package/public/slbhealthcheck.html +10 -0
  56. package/scripts/shutdown.sh +10 -0
  57. package/scripts/startup.sh +35 -0
  58. package/{generation/server → server}/apis/template.js +17 -18
  59. package/{generation/server → server}/modules/template/resolver.js +29 -35
  60. package/{generation/server → server}/modules/template/schema.js +33 -33
  61. package/server/rest.js +20 -0
  62. package/{generation/server → server}/sql/template.sql +8 -8
  63. package/server/utils/common.js +7 -0
  64. package/generation/client/layout/index.tsx +0 -223
  65. package/generation/client/service/template/manage.ts +0 -74
  66. package/generation/client/styled/layout/index.ts +0 -14
  67. package/generation/client/utils/common.ts +0 -45
  68. package/generation/next-env.d.ts +0 -2
  69. package/generation/pages/index.tsx +0 -55
  70. /package/{generation/public → public}/images/zhizuotu_1.png +0 -0
package/README.md CHANGED
@@ -1,162 +1,161 @@
1
- # NSGM CLI
2
- - 技术栈: [Next](https://github.com/vercel/next.js), [Styled-components](https://github.com/styled-components/styled-components), [Graphql](https://graphql.org/), [Mysql](https://www.mysql.com/) (命名取首字母 NSGM)
3
- - 全栈架构,代码模板生成,快速开发
4
- - 数据库采用 Mysql, 配置见 mysql.config.js
5
- - 项目配置见 project.config.js
6
- - Next 框架配置见 next.config.js
7
- - [Demo 网站](https://nsgm.erisl.top/)
8
-
9
- ## 命令
10
- - nsgm init 初始化项目
11
- - nsgm upgrade 升级项目基础文件
12
- - nsgm create 创建模板页面
13
- - nsgm delete 删除模板页面
14
- - nsgm dev 开发模式
15
- - nsgm start 生产模式
16
- - nsgm build 编译
17
- - nsgm export 导出静态页面
18
-
19
- ## 参数
20
- - dictionary: 在 export/init 的时候使用, 默认 webapp, 譬如: nsgm init|export dictionary=webapp 或者 nsgm init|export webapp
21
- - controller: 在 create/delete 的时候使用, 必须有。譬如:nsgm create|delete math
22
- - action: 在 create/delete 的时候使用, 默认 manage, 跟在 controller 后面, 譬如 nsgm create|delete math test
23
-
24
-
25
- ## 根目录新增 next.config.js
26
- ```
27
- const { nextConfig } = require('nsgm-cli')
28
- const projectConfig = require('./project.config')
29
-
30
- const { version, prefix, protocol, host, port } = projectConfig
31
-
32
- module.exports = (phase, defaultConfig) => {
33
- let configObj = nextConfig(phase, defaultConfig, {
34
- version, prefix, protocol, host, port
35
- })
36
-
37
- return configObj
38
- }
39
- ```
40
-
41
- ## 根目录新增 mysql.config.js
42
- ```
43
- const { mysqlConfig } = require('nsgm-cli')
44
- const { mysqlOptions } = mysqlConfig
45
- const { user, password, host, port, database } = mysqlOptions
46
-
47
- module.exports = {
48
- mysqlOptions: {
49
- user,
50
- password,
51
- host,
52
- port,
53
- database
54
- }
55
- }
56
- ```
57
-
58
- ## 根目录新增 project.config.js
59
- ```
60
- const { projectConfig } = require('nsgm-cli')
61
- const pkg = require('./package.json')
62
-
63
- const { prefix, protocol, host, port } = projectConfig
64
- const { version } = pkg
65
-
66
- module.exports = {
67
- version,
68
- prefix,
69
- protocol,
70
- host,
71
- port
72
- }
73
- ```
74
-
75
- ## 根目录新增 server
76
- - apis 存放 Rest Api
77
- - modules 存放 graphql 的 resolver 和 schema
78
- - plugins 存放 graphql plugin
79
- - *.js 举例: test.js => 用于响应 /test/*, ${prefix}/test/* 请求
80
-
81
- ```
82
- const express = require('express')
83
- const moment = require('moment')
84
-
85
- const router = express.Router()
86
-
87
- router.use((req, res, next) => {
88
- const fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl
89
- console.log(moment().format('YYYY-MM-DD HH:mm:ss') + ' ' + fullUrl)
90
- next()
91
- })
92
-
93
- router.get('/*', (req, res) => {
94
- res.statusCode = 200
95
- res.json({ name: 'TEST' })
96
- })
97
-
98
- module.exports = router
99
- ```
100
-
101
- - apis/hello.js
102
- ```
103
- const express = require('express')
104
- const router = express.Router()
105
-
106
- router.get('/*', (req, res) => {
107
- res.statusCode = 200
108
- res.json({ name: 'Hello' })
109
- })
110
-
111
- module.exports = router
112
- ```
113
-
114
- - modules/link/schema.js
115
- ```
116
- module.exports = {
117
- query: `
118
- link: String
119
- `,
120
- mutation: `
121
- linkUpdate(link: Date): String
122
- `,
123
- subscription: ``,
124
- type: ``
125
- }
126
- ```
127
-
128
- - modules/link/resolver.js
129
- ```
130
- let localLink = ''
131
-
132
- module.exports = {
133
- link: () => {
134
- return localLink
135
- },
136
- linkUpdate: ({ link }) =>{
137
- console.log('link', link)
138
- localLink = link
139
- return localLink
140
- }
141
- }
142
- ```
143
-
144
- - plugins/date.js
145
- ```
146
- const moment = require('moment')
147
- const { Kind } = require('graphql/language')
148
- const { GraphQLScalarType } = require('graphql')
149
-
150
- const customScalarDate = new GraphQLScalarType({
151
- name: 'Date',
152
- description: 'Date custom scalar type',
153
- parseValue: value => moment(value).valueOf(),
154
- serialize: value => moment(value).format('YYYY-MM-DD HH:mm:ss:SSS'),
155
- parseLiteral: ast => (ast.kind === Kind.INT)
156
- ? parseInt(ast.value, 10)
157
- : null
158
- })
159
-
160
- module.exports = { Date: customScalarDate }
161
- ```
162
-
1
+ # NSGM CLI
2
+ - 技术栈: [Next](https://github.com/vercel/next.js), [Styled-components](https://github.com/styled-components/styled-components), [Graphql](https://graphql.org/), [Mysql](https://www.mysql.com/)
3
+ - 全栈架构,代码模板生成,快速开发
4
+ - 数据库采用 Mysql, 配置见 mysql.config.js
5
+ - 项目配置见 project.config.js
6
+ - Next 框架配置见 next.config.js
7
+ - [DEMO UAT 链接](https://nsgm.erisl.top/)
8
+ ## 命令
9
+ - nsgm init 初始化项目
10
+ - nsgm upgrade 升级项目基础文件
11
+ - nsgm create 创建模板页面
12
+ - nsgm delete 删除模板页面
13
+ - nsgm dev 开发模式
14
+ - nsgm start 生产模式
15
+ - nsgm build 编译
16
+ - nsgm export 导出静态页面
17
+
18
+ ## 参数
19
+ - dictionary: 在 export/init 的时候使用, 默认 webapp, 譬如: nsgm init|export dictionary=webapp 或者 nsgm init|export webapp
20
+ - controller: 在 create/delete 的时候使用, 必须有。譬如:nsgm create|delete math
21
+ - action: 在 create/delete 的时候使用, 默认 manage, 跟在 controller 后面, 譬如 nsgm create|delete math test
22
+
23
+ ## 根目录新增 next.config.js
24
+ ```
25
+ const { nextConfig } = require('nsgm-cli')
26
+ const projectConfig = require('./project.config')
27
+
28
+ const { version, prefix, protocol, host } = projectConfig
29
+
30
+ module.exports = (phase, defaultConfig) => {
31
+ let configObj = nextConfig(phase, defaultConfig, {
32
+ version, prefix, protocol, host
33
+ })
34
+
35
+ return configObj
36
+ }
37
+ ```
38
+
39
+ ## 根目录新增 mysql.config.js
40
+ ```
41
+ const { mysqlConfig } = require('nsgm-cli')
42
+ const { mysqlOptions, mysqlDBCluster } = mysqlConfig
43
+ const { user, password, host, port, database } = mysqlOptions
44
+
45
+ module.exports = {
46
+ mysqlOptions: {
47
+ user,
48
+ password,
49
+ host,
50
+ port,
51
+ database
52
+ },
53
+ mysqlDBCluster
54
+ }
55
+ ```
56
+
57
+ ## 根目录新增 project.config.js
58
+ ```
59
+ const { projectConfig } = require('nsgm-cli')
60
+ const pkg = require('./package.json')
61
+
62
+ const { prefix, protocol, host, port } = projectConfig
63
+ const { version } = pkg
64
+
65
+ module.exports = {
66
+ version,
67
+ prefix,
68
+ protocol,
69
+ host,
70
+ port
71
+ }
72
+ ```
73
+
74
+ ## 根目录新增 server
75
+ - apis 存放 Rest Api
76
+ - modules 存放 graphql resolver 和 schema
77
+ - plugins 存放 graphql 的 plugin
78
+ - *.js 举例: test.js => 用于响应 /test/*, ${prefix}/test/* 请求
79
+
80
+ ```
81
+ const express = require('express')
82
+ const moment = require('moment')
83
+
84
+ const router = express.Router()
85
+
86
+ router.use((req, res, next) => {
87
+ const fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl
88
+ console.log(moment().format('YYYY-MM-DD HH:mm:ss') + ' ' + fullUrl)
89
+ next()
90
+ })
91
+
92
+ router.get('/*', (req, res) => {
93
+ res.statusCode = 200
94
+ res.json({ name: 'TEST' })
95
+ })
96
+
97
+ module.exports = router
98
+ ```
99
+
100
+ - apis/hello.js
101
+ ```
102
+ const express = require('express')
103
+ const router = express.Router()
104
+
105
+ router.get('/*', (req, res) => {
106
+ res.statusCode = 200
107
+ res.json({ name: 'Hello' })
108
+ })
109
+
110
+ module.exports = router
111
+ ```
112
+
113
+ - modules/link/schema.js
114
+ ```
115
+ module.exports = {
116
+ query: `
117
+ link: String
118
+ `,
119
+ mutation: `
120
+ linkUpdate(link: Date): String
121
+ `,
122
+ subscription: ``,
123
+ type: ``
124
+ }
125
+ ```
126
+
127
+ - modules/link/resolver.js
128
+ ```
129
+ let localLink = ''
130
+
131
+ module.exports = {
132
+ link: () => {
133
+ return localLink
134
+ },
135
+ linkUpdate: ({ link }) =>{
136
+ console.log('link', link)
137
+ localLink = link
138
+ return localLink
139
+ }
140
+ }
141
+ ```
142
+
143
+ - plugins/date.js
144
+ ```
145
+ const moment = require('moment')
146
+ const { Kind } = require('graphql/language')
147
+ const { GraphQLScalarType } = require('graphql')
148
+
149
+ const customScalarDate = new GraphQLScalarType({
150
+ name: 'Date',
151
+ description: 'Date custom scalar type',
152
+ parseValue: value => moment(value).valueOf(),
153
+ serialize: value => moment(value).format('YYYY-MM-DD HH:mm:ss:SSS'),
154
+ parseLiteral: ast => (ast.kind === Kind.INT)
155
+ ? parseInt(ast.value, 10)
156
+ : null
157
+ })
158
+
159
+ module.exports = { Date: customScalarDate }
160
+ ```
161
+
@@ -0,0 +1,245 @@
1
+ import React, { useEffect, useState } from 'react'
2
+ import { Layout, Menu, Breadcrumb, Image, Select } from 'antd'
3
+ import { Container } from '../styled/layout'
4
+ import { useRouter } from 'next/router'
5
+ import _ from 'lodash'
6
+ import menuConfig from '../utils/menu'
7
+ import getConfig from 'next/config'
8
+ import { ItemType, SubMenuType } from 'antd/lib/menu/hooks/useItems'
9
+
10
+ const { Option } = Select
11
+ const { SubMenu } = Menu
12
+ const { Header, Content, Sider } = Layout
13
+
14
+ const nextConfig = getConfig()
15
+ const { publicRuntimeConfig } = nextConfig
16
+ const { prefix } = publicRuntimeConfig
17
+
18
+ const getLocationKey = () => {
19
+ let result = {
20
+ topMenu: '1',
21
+ slideMenu: '0'
22
+ }
23
+
24
+ if (typeof window !== 'undefined') {
25
+ const locationHref = window.location.href
26
+
27
+ let locationHrefArr = locationHref.split('?')
28
+ if (locationHrefArr.length > 0) {
29
+ locationHrefArr = locationHrefArr[0].split('//')
30
+
31
+ if (locationHrefArr.length > 1) {
32
+ let locationStr = locationHrefArr[1]
33
+ const locationIndex = locationStr.indexOf('/')
34
+ locationStr = locationStr.substring(locationIndex)
35
+
36
+ if (prefix && locationStr.indexOf(prefix) !== -1) {
37
+ locationStr = locationStr.split(prefix)[1]
38
+ }
39
+
40
+ // console.log('locationStr', locationStr)
41
+
42
+ _.each(menuConfig, (item, index) => {
43
+ const { key, url, subMenus } = item
44
+
45
+ if (subMenus) {
46
+ _.each(subMenus, (subItem, subIndex) => {
47
+ const { key: subKey, url: subUrl } = subItem
48
+
49
+ if (locationStr === subUrl.split('?')[0]) {
50
+ const subKeyArr = subKey.split('_')
51
+ const subKeyArrLen = subKeyArr.length
52
+
53
+ if (subKeyArrLen > 0) result.topMenu = subKeyArr[0]
54
+
55
+ if (subKeyArrLen > 1) result.slideMenu = subKeyArr[1]
56
+
57
+ return false
58
+ }
59
+ })
60
+ } else {
61
+ if (url && locationStr === url.split('?')[0]) {
62
+ result.topMenu = key
63
+ return false
64
+ }
65
+ }
66
+ })
67
+ }
68
+ }
69
+ }
70
+ // console.log('result', result)
71
+ return result
72
+ }
73
+
74
+ const routerPush = (router: any, url: string) => {
75
+ // console.log('routerPush', url)
76
+ if (router && url) {
77
+ if (prefix && url.indexOf(prefix) === -1) {
78
+ url = prefix + url
79
+ }
80
+ router.push(url)
81
+ }
82
+ }
83
+
84
+ const LayoutComponent = ({ user, children }) => {
85
+ const router = useRouter()
86
+ const [topMenuKey, setTopMenuKey] = useState('1')
87
+ const [sliderMenuKey, setSliderMenuKey] = useState('1')
88
+
89
+ // console.log('topMenuKey: ' + topMenuKey, ', sliderMenuKey: ' + sliderMenuKey, user)
90
+
91
+ useEffect(() => {
92
+ const { topMenu, slideMenu } = getLocationKey()
93
+ setTopMenuKey(topMenu)
94
+ setSliderMenuKey(slideMenu)
95
+ }, [])
96
+
97
+ const menuItems:any = []
98
+ const menuItemsVertical:any = []
99
+
100
+ _.each(menuConfig, (item, index) => {
101
+ const { key, text, url, icon, subMenus } = item
102
+
103
+ if (key) {
104
+ const menuObj:ItemType = {
105
+ label: text,
106
+ key,
107
+ onClick: () => {
108
+ routerPush(router, url)
109
+ setTopMenuKey(key)
110
+
111
+ if (subMenus) {
112
+ setSliderMenuKey('1')
113
+ } else {
114
+ setSliderMenuKey('0')
115
+ }
116
+ }
117
+ }
118
+
119
+ menuItems.push(menuObj)
120
+ }
121
+
122
+ if (subMenus) {
123
+ const subMenusChildren:any = []
124
+
125
+ _.each(subMenus, (subItem, subIndex) => {
126
+ const { key: subKey, text: subText, url: subUrl } = subItem
127
+
128
+ const subMenusChildrenObj:ItemType = {
129
+ key: 'slider_' + subKey,
130
+ label: subText,
131
+ onClick: ()=>{
132
+ routerPush(router, subUrl)
133
+
134
+ const subKeyArr = subKey.split('_')
135
+ const subKeyArrLen = subKeyArr.length
136
+
137
+ // console.log(subKeyArr, subKeyArrLen)
138
+
139
+ if (subKeyArrLen >= 1) setTopMenuKey(subKeyArr[0])
140
+ if (subKeyArrLen >= 2) setSliderMenuKey(subKeyArr[1])
141
+ }
142
+ }
143
+
144
+ subMenusChildren.push(subMenusChildrenObj)
145
+ })
146
+
147
+ const subMenuObjVertical:SubMenuType = {
148
+ key: 'slider_' + key,
149
+ icon,
150
+ label: text,
151
+ onTitleClick: () => {
152
+ setTopMenuKey(key)
153
+ setSliderMenuKey('1')
154
+ },
155
+ children: subMenusChildren
156
+ }
157
+
158
+ menuItemsVertical.push(subMenuObjVertical)
159
+ } else {
160
+ if (key) {
161
+ const menuObjVertical:ItemType = {
162
+ label: text,
163
+ icon,
164
+ key: 'slider_' + key + '_0',
165
+ onClick: () => {
166
+ routerPush(router, url)
167
+ setTopMenuKey(key)
168
+ setSliderMenuKey('0')
169
+ }
170
+ }
171
+
172
+ menuItemsVertical.push(menuObjVertical)
173
+ }
174
+ }
175
+ })
176
+
177
+ return (
178
+ <Layout>
179
+ <Container>
180
+ <Header className="header">
181
+ <div className="logo">
182
+ <Image width={100} src={prefix + "/images/zhizuotu_1.png"} preview={false} />
183
+ </div>
184
+ <Menu theme="dark" mode="horizontal" defaultSelectedKeys={['1']} selectedKeys={[topMenuKey]} items={menuItems} />
185
+ <div className="user">
186
+ <div>Welcome</div>
187
+ </div>
188
+ </Header>
189
+ <Layout>
190
+ <Sider width={200} className="site-layout-background">
191
+ <Menu
192
+ mode="inline"
193
+ defaultSelectedKeys={['slider_1_0']}
194
+ defaultOpenKeys={['slider_1']}
195
+ selectedKeys={['slider_' + topMenuKey + '_' + sliderMenuKey]}
196
+ openKeys={['slider_' + topMenuKey]}
197
+ style={{ height: '100%', borderRight: 0 }}
198
+ items={menuItemsVertical}
199
+ />
200
+ </Sider>
201
+ <Layout style={{ padding: '0 24px 24px' }}>
202
+ <Breadcrumb style={{ margin: '16px 0' }}>
203
+ {_.map(menuConfig, (item, index) => {
204
+ const { key, text, subMenus } = item
205
+
206
+ if (subMenus) {
207
+ // console.log('subMenus', subMenus)
208
+
209
+ let subContent:any = []
210
+ _.each(subMenus, (subItem, subIndex) => {
211
+ const { key: subKey, text: subText } = subItem
212
+ // console.log('subKey', subKey, key, topMenuKey, sliderMenuKey)
213
+
214
+ if (subKey === topMenuKey + '_' + sliderMenuKey) {
215
+ subContent.push(<Breadcrumb.Item key={'breadcrumb' + subIndex}>{text}</Breadcrumb.Item>)
216
+ subContent.push(<Breadcrumb.Item key={'breadcrumb' + subIndex}>{subText}</Breadcrumb.Item>)
217
+ return false
218
+ }
219
+ })
220
+ return subContent
221
+ } else {
222
+ if (key && key === topMenuKey) {
223
+ return <Breadcrumb.Item key={'breadcrumb' + index}>{text}</Breadcrumb.Item>
224
+ }
225
+ }
226
+ })}
227
+ </Breadcrumb>
228
+ <Content
229
+ className="site-layout-background"
230
+ style={{
231
+ padding: 24,
232
+ margin: 0,
233
+ minHeight: 280
234
+ }}
235
+ >
236
+ {children}
237
+ </Content>
238
+ </Layout>
239
+ </Layout>
240
+ </Container>
241
+ </Layout>
242
+ )
243
+ }
244
+
245
+ export default LayoutComponent
@@ -0,0 +1,5 @@
1
+ import { templateManageReducer } from './template/manage/reducers'
2
+
3
+ export default {
4
+ templateManage: templateManageReducer,
5
+ }
@@ -1,44 +1,50 @@
1
- import { useMemo } from 'react'
2
- import { createStore, applyMiddleware, combineReducers } from 'redux'
3
- import { composeWithDevTools } from 'redux-devtools-extension'
4
- import thunkMiddleware from 'redux-thunk'
5
- import reducers from './reducers'
6
- import _ from 'lodash'
7
-
8
- let store:any
9
-
10
- const reducersKeysLen = _.keys(reducers).length
11
- const combineReducer = combineReducers((reducersKeysLen === 0) ? {} : { ...reducers })
12
-
13
- export type RootState = ReturnType<typeof combineReducer>
14
-
15
- function initStore(initialState:any) {
16
- return createStore(
17
- combineReducer,
18
- initialState,
19
- composeWithDevTools(applyMiddleware(thunkMiddleware))
20
- )
21
- }
22
-
23
- export const initializeStore = (preloadedState:any) => {
24
- let _store = store ?? initStore(preloadedState)
25
-
26
- if (preloadedState && store) {
27
- _store = initStore({
28
- ...store.getState(),
29
- ...preloadedState
30
- })
31
- store = undefined
32
- }
33
-
34
- if (typeof window === 'undefined') return _store
35
-
36
- if (!store) store = _store
37
-
38
- return _store
39
- }
40
-
41
- export function useStore(initialState:any) {
42
- const memoStore = useMemo(() => initializeStore(initialState), [initialState])
43
- return memoStore
44
- }
1
+ import { useMemo } from 'react'
2
+ import { combineReducers } from 'redux'
3
+ import { configureStore } from '@reduxjs/toolkit'
4
+ import thunkMiddleware from 'redux-thunk'
5
+ import reducers from './reducers'
6
+ import _ from 'lodash'
7
+
8
+ let store:any
9
+
10
+ const reducersKeysLen = _.keys(reducers).length
11
+
12
+ let combineReducer:any = function(){}
13
+
14
+ if(reducersKeysLen > 0){
15
+ combineReducer = combineReducers({ ...reducers })
16
+ }
17
+
18
+ export type RootState = ReturnType<typeof combineReducer>
19
+
20
+ function initStore(initialState:any) {
21
+ return configureStore({
22
+ reducer: combineReducer,
23
+ preloadedState: initialState,
24
+ devTools: true,
25
+ middleware: [thunkMiddleware]
26
+ })
27
+ }
28
+
29
+ export const initializeStore = (preloadedState:any) => {
30
+ let _store = store ?? initStore(preloadedState)
31
+
32
+ if (preloadedState && store) {
33
+ _store = initStore({
34
+ ...store.getState(),
35
+ ...preloadedState
36
+ })
37
+ store = undefined
38
+ }
39
+
40
+ if (typeof window === 'undefined') return _store
41
+
42
+ if (!store) store = _store
43
+
44
+ return _store
45
+ }
46
+
47
+ export function useStore(initialState:any) {
48
+ const store = useMemo(() => initializeStore(initialState), [initialState])
49
+ return store
50
+ }