nsbp-cli 0.2.44 → 0.2.46
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.
- package/README.md +1 -1
- package/package.json +1 -1
- package/templates/basic/.env.development +1 -0
- package/templates/basic/.env.example +9 -0
- package/templates/basic/.env.production +8 -0
- package/templates/basic/Makefile +17 -17
- package/templates/basic/{docker/docker-compose.dev.yml → docker-compose.dev.yml} +3 -3
- package/templates/basic/{docker/docker-compose.yml → docker-compose.yml} +2 -2
- package/templates/basic/gitignore +1 -0
- package/templates/basic/src/client/index.tsx +4 -4
- package/templates/basic/src/containers/Home.tsx +18 -14
- package/templates/basic/src/server/index.ts +3 -0
- package/templates/basic/src/server/utils.tsx +3 -5
package/README.md
CHANGED
|
@@ -147,7 +147,7 @@ node ./bin/nsbp.js --help # Test CLI locally
|
|
|
147
147
|
|
|
148
148
|
- **Package Name**: `nsbp-cli`
|
|
149
149
|
- **Bin Command**: `nsbp` (install globally and run `nsbp --help`)
|
|
150
|
-
- **Version**: `0.2.
|
|
150
|
+
- **Version**: `0.2.46`
|
|
151
151
|
- **Dependencies**: chalk, commander, fs-extra, inquirer
|
|
152
152
|
- **Package Manager**: Uses pnpm (also compatible with npm)
|
|
153
153
|
- **Node Version**: >=16.0.0
|
package/package.json
CHANGED
|
@@ -14,6 +14,14 @@ ENABLE_RATE_LIMIT=0
|
|
|
14
14
|
# Docker 镜像标签(可选)
|
|
15
15
|
# DOCKER_IMAGE_TAG=latest
|
|
16
16
|
|
|
17
|
+
# Docker 主机端口映射(可选,默认值见下方说明)
|
|
18
|
+
# 生产环境主机端口(默认:8081)
|
|
19
|
+
HOST_PORT=8081
|
|
20
|
+
# 开发环境主机端口(默认:3001)
|
|
21
|
+
HOST_PORT_DEV=3001
|
|
22
|
+
# 调试端口(开发环境使用,默认:9229)
|
|
23
|
+
DEBUG_PORT=9229
|
|
24
|
+
|
|
17
25
|
# ==================== 调试配置 ====================
|
|
18
26
|
# 启用详细日志(开发时有用)
|
|
19
27
|
# DEBUG=nsbp:*
|
|
@@ -31,3 +39,4 @@ ENABLE_RATE_LIMIT=0
|
|
|
31
39
|
# 2. 敏感信息(密钥、密码)请放在 .env.local 中
|
|
32
40
|
# 3. .env.local 不会被提交到 Git,适合存放敏感信息
|
|
33
41
|
# 4. 优先级:.env.local > .env > 默认值
|
|
42
|
+
# 5. 修改端口后需要重启 Docker 容器:docker-compose down && docker-compose up -d
|
|
@@ -15,3 +15,11 @@ ENABLE_RATE_LIMIT=1
|
|
|
15
15
|
# ==================== 其他配置 ====================
|
|
16
16
|
# 时区
|
|
17
17
|
TZ=Asia/Shanghai
|
|
18
|
+
|
|
19
|
+
# Docker 主机端口映射(可选,默认值见下方说明)
|
|
20
|
+
# 生产环境主机端口(默认:8081)
|
|
21
|
+
HOST_PORT=8091
|
|
22
|
+
# 开发环境主机端口(默认:3001)
|
|
23
|
+
HOST_PORT_DEV=3001
|
|
24
|
+
# 调试端口(开发环境使用,默认:9229)
|
|
25
|
+
DEBUG_PORT=9229
|
package/templates/basic/Makefile
CHANGED
|
@@ -19,57 +19,57 @@ help: ## Show this help message
|
|
|
19
19
|
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
|
20
20
|
|
|
21
21
|
build: ## Build Docker images for production
|
|
22
|
-
$(COMPOSE)
|
|
22
|
+
$(COMPOSE) build
|
|
23
23
|
|
|
24
24
|
build-dev: ## Build Docker images for development
|
|
25
|
-
$(COMPOSE) -f docker
|
|
25
|
+
$(COMPOSE) -f docker-compose.dev.yml build
|
|
26
26
|
|
|
27
27
|
dev: ## Start development environment (removes orphan containers)
|
|
28
|
-
$(COMPOSE) -f docker
|
|
28
|
+
$(COMPOSE) -f docker-compose.dev.yml up --build --remove-orphans
|
|
29
29
|
|
|
30
30
|
prod: ## Start production environment (removes orphan containers)
|
|
31
|
-
$(COMPOSE)
|
|
31
|
+
$(COMPOSE) up -d --remove-orphans
|
|
32
32
|
|
|
33
33
|
down: ## Stop and remove containers (including orphan containers)
|
|
34
34
|
@echo "Stopping production containers..."
|
|
35
|
-
@$(COMPOSE)
|
|
35
|
+
@$(COMPOSE) down --remove-orphans || echo "Warning: Failed to stop production containers"
|
|
36
36
|
@echo "Stopping development containers..."
|
|
37
|
-
@$(COMPOSE) -f docker
|
|
37
|
+
@$(COMPOSE) -f docker-compose.dev.yml down --remove-orphans || echo "Warning: Failed to stop development containers"
|
|
38
38
|
@echo "Cleaning up any remaining nsbp containers..."
|
|
39
39
|
@docker ps -a --filter "name=nsbp-" --format "{{.Names}}" | xargs -r docker stop
|
|
40
40
|
@docker ps -a --filter "name=nsbp-" --format "{{.Names}}" | xargs -r docker rm
|
|
41
41
|
@echo "Cleanup complete!"
|
|
42
42
|
|
|
43
43
|
clean: ## Stop containers, remove images and volumes (including orphan containers)
|
|
44
|
-
$(COMPOSE)
|
|
45
|
-
$(COMPOSE) -f docker
|
|
44
|
+
$(COMPOSE) down -v --rmi all --remove-orphans
|
|
45
|
+
$(COMPOSE) -f docker-compose.dev.yml down -v --rmi all --remove-orphans
|
|
46
46
|
|
|
47
47
|
logs: ## View logs
|
|
48
|
-
$(COMPOSE)
|
|
48
|
+
$(COMPOSE) logs -f
|
|
49
49
|
|
|
50
50
|
logs-dev: ## View development logs
|
|
51
|
-
$(COMPOSE) -f docker
|
|
51
|
+
$(COMPOSE) -f docker-compose.dev.yml logs -f
|
|
52
52
|
|
|
53
53
|
restart: ## Restart production containers
|
|
54
|
-
$(COMPOSE)
|
|
54
|
+
$(COMPOSE) restart
|
|
55
55
|
|
|
56
56
|
restart-dev: ## Restart development containers
|
|
57
|
-
$(COMPOSE) -f docker
|
|
57
|
+
$(COMPOSE) -f docker-compose.dev.yml restart
|
|
58
58
|
|
|
59
59
|
rebuild: ## Rebuild and restart production containers (removes orphan containers)
|
|
60
|
-
$(COMPOSE)
|
|
60
|
+
$(COMPOSE) up -d --build --remove-orphans
|
|
61
61
|
|
|
62
62
|
rebuild-dev: ## Rebuild and restart development containers (removes orphan containers)
|
|
63
|
-
$(COMPOSE) -f docker
|
|
63
|
+
$(COMPOSE) -f docker-compose.dev.yml up -d --build --remove-orphans
|
|
64
64
|
|
|
65
65
|
shell: ## Open shell in production container
|
|
66
|
-
$(COMPOSE)
|
|
66
|
+
$(COMPOSE) exec app sh
|
|
67
67
|
|
|
68
68
|
shell-dev: ## Open shell in development container
|
|
69
|
-
$(COMPOSE) -f docker
|
|
69
|
+
$(COMPOSE) -f docker-compose.dev.yml exec app sh
|
|
70
70
|
|
|
71
71
|
test: ## Run tests (if configured)
|
|
72
|
-
$(COMPOSE)
|
|
72
|
+
$(COMPOSE) exec app $(PM) test
|
|
73
73
|
|
|
74
74
|
env-dev: ## Set up development environment
|
|
75
75
|
@if [ -f .env.development ]; then \
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
services:
|
|
5
5
|
app:
|
|
6
6
|
build:
|
|
7
|
-
context:
|
|
7
|
+
context: .
|
|
8
8
|
dockerfile: docker/Dockerfile.dev
|
|
9
9
|
container_name: nsbp-app-dev
|
|
10
10
|
ports:
|
|
11
|
-
- "3001
|
|
12
|
-
- "9229:9229" # Node.js debug port
|
|
11
|
+
- "${HOST_PORT_DEV:-3001}:${PORT:-3001}"
|
|
12
|
+
- "${DEBUG_PORT:-9229}:9229" # Node.js debug port
|
|
13
13
|
environment:
|
|
14
14
|
- NODE_ENV=${NODE_ENV:-development}
|
|
15
15
|
- PORT=${PORT:-3001}
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
services:
|
|
5
5
|
app:
|
|
6
6
|
build:
|
|
7
|
-
context:
|
|
7
|
+
context: .
|
|
8
8
|
dockerfile: docker/Dockerfile
|
|
9
9
|
container_name: nsbp-app
|
|
10
10
|
ports:
|
|
11
|
-
- "
|
|
11
|
+
- "${HOST_PORT:-8081}:${PORT:-3001}"
|
|
12
12
|
environment:
|
|
13
13
|
- NODE_ENV=${NODE_ENV:-production}
|
|
14
14
|
- PORT=${PORT:-3001}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useMemo } from 'react'
|
|
2
2
|
import { hydrateRoot } from 'react-dom/client'
|
|
3
3
|
import { BrowserRouter, Routes, Route } from 'react-router-dom'
|
|
4
4
|
import routers from '@/Routers'
|
|
@@ -9,13 +9,13 @@ import Theme from '@components/Theme'
|
|
|
9
9
|
import { loadableReady } from '@loadable/component'
|
|
10
10
|
|
|
11
11
|
const App = () => {
|
|
12
|
-
//
|
|
13
|
-
const
|
|
12
|
+
// 使用 useMemo 确保 store 只创建一次,避免每次渲染都创建新 store
|
|
13
|
+
const store = useMemo(() => {
|
|
14
14
|
if (isSEO() && window?.context?.state) {
|
|
15
15
|
return getStore(window.context.state)
|
|
16
16
|
}
|
|
17
17
|
return getStore()
|
|
18
|
-
})
|
|
18
|
+
}, []) // 空依赖数组,只执行一次
|
|
19
19
|
|
|
20
20
|
return (
|
|
21
21
|
<Theme>
|
|
@@ -107,13 +107,30 @@ const Home: React.FC = () => {
|
|
|
107
107
|
const [isLoaded, setIsLoaded] = useState(false)
|
|
108
108
|
|
|
109
109
|
useEffect(() => {
|
|
110
|
-
//
|
|
110
|
+
// 客户端模拟页面加载动画
|
|
111
111
|
const timer = setTimeout(() => {
|
|
112
112
|
setIsLoaded(true)
|
|
113
113
|
}, 500)
|
|
114
114
|
return () => clearTimeout(timer)
|
|
115
115
|
}, [])
|
|
116
116
|
|
|
117
|
+
// 客户端处理页面加载器的淡出和移除
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
if (!isLoaded) return
|
|
120
|
+
|
|
121
|
+
const removeLoader = () => {
|
|
122
|
+
const loader = document.getElementById('pageLoader')
|
|
123
|
+
if (loader) {
|
|
124
|
+
loader.classList.add('fade-out')
|
|
125
|
+
setTimeout(() => loader.remove(), 500)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 延迟移除加载器
|
|
130
|
+
const removeTimer = setTimeout(removeLoader, 300)
|
|
131
|
+
return () => clearTimeout(removeTimer)
|
|
132
|
+
}, [isLoaded])
|
|
133
|
+
|
|
117
134
|
return (
|
|
118
135
|
<GlobalStyle>
|
|
119
136
|
{!isLoaded && (
|
|
@@ -121,19 +138,6 @@ const Home: React.FC = () => {
|
|
|
121
138
|
<div className="loader-spinner"></div>
|
|
122
139
|
</div>
|
|
123
140
|
)}
|
|
124
|
-
<script
|
|
125
|
-
dangerouslySetInnerHTML={{
|
|
126
|
-
__html: `
|
|
127
|
-
setTimeout(() => {
|
|
128
|
-
const loader = document.getElementById('pageLoader');
|
|
129
|
-
if (loader) {
|
|
130
|
-
loader.classList.add('fade-out');
|
|
131
|
-
setTimeout(() => loader.remove(), 500);
|
|
132
|
-
}
|
|
133
|
-
}, 800);
|
|
134
|
-
`
|
|
135
|
-
}}
|
|
136
|
-
/>
|
|
137
141
|
<Helmet>
|
|
138
142
|
<title>Nsbp.js - 轻量级 React SSR 框架</title>
|
|
139
143
|
<meta
|
|
@@ -46,11 +46,9 @@ export const render = (req: any, res: any) => {
|
|
|
46
46
|
|
|
47
47
|
const queryDispatch = (callback: any) => {
|
|
48
48
|
return (dispatch: any) => {
|
|
49
|
-
setTimeout
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
callback && callback()
|
|
53
|
-
}, 0)
|
|
49
|
+
// 直接同步执行,避免 setTimeout 导致的竞态条件
|
|
50
|
+
dispatch({ type: REQUEST_QUERY, query })
|
|
51
|
+
callback && callback()
|
|
54
52
|
}
|
|
55
53
|
}
|
|
56
54
|
|