nsbp-cli 0.2.43 → 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 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.43`
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nsbp-cli",
3
- "version": "0.2.43",
3
+ "version": "0.2.46",
4
4
  "description": "CLI tool for creating NSBP (Node React SSR by Webpack) projects",
5
5
  "main": "index.js",
6
6
  "homepage": "https://nsbp.erishen.cn/",
@@ -11,3 +11,4 @@ ENABLE_RATE_LIMIT=0
11
11
  # ==================== 调试配置 ====================
12
12
  # 启用详细日志便于调试
13
13
  # DEBUG=nsbp:*
14
+
@@ -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
@@ -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) -f docker/docker-compose.yml build
22
+ $(COMPOSE) build
23
23
 
24
24
  build-dev: ## Build Docker images for development
25
- $(COMPOSE) -f docker/docker-compose.dev.yml build
25
+ $(COMPOSE) -f docker-compose.dev.yml build
26
26
 
27
27
  dev: ## Start development environment (removes orphan containers)
28
- $(COMPOSE) -f docker/docker-compose.dev.yml up --build --remove-orphans
28
+ $(COMPOSE) -f docker-compose.dev.yml up --build --remove-orphans
29
29
 
30
30
  prod: ## Start production environment (removes orphan containers)
31
- $(COMPOSE) -f docker/docker-compose.yml up -d --remove-orphans
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) -f docker/docker-compose.yml down --remove-orphans || echo "Warning: Failed to stop production containers"
35
+ @$(COMPOSE) down --remove-orphans || echo "Warning: Failed to stop production containers"
36
36
  @echo "Stopping development containers..."
37
- @$(COMPOSE) -f docker/docker-compose.dev.yml down --remove-orphans || echo "Warning: Failed to stop development containers"
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) -f docker/docker-compose.yml down -v --rmi all --remove-orphans
45
- $(COMPOSE) -f docker/docker-compose.dev.yml down -v --rmi all --remove-orphans
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) -f docker/docker-compose.yml logs -f
48
+ $(COMPOSE) logs -f
49
49
 
50
50
  logs-dev: ## View development logs
51
- $(COMPOSE) -f docker/docker-compose.dev.yml logs -f
51
+ $(COMPOSE) -f docker-compose.dev.yml logs -f
52
52
 
53
53
  restart: ## Restart production containers
54
- $(COMPOSE) -f docker/docker-compose.yml restart
54
+ $(COMPOSE) restart
55
55
 
56
56
  restart-dev: ## Restart development containers
57
- $(COMPOSE) -f docker/docker-compose.dev.yml restart
57
+ $(COMPOSE) -f docker-compose.dev.yml restart
58
58
 
59
59
  rebuild: ## Rebuild and restart production containers (removes orphan containers)
60
- $(COMPOSE) -f docker/docker-compose.yml up -d --build --remove-orphans
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/docker-compose.dev.yml up -d --build --remove-orphans
63
+ $(COMPOSE) -f docker-compose.dev.yml up -d --build --remove-orphans
64
64
 
65
65
  shell: ## Open shell in production container
66
- $(COMPOSE) -f docker/docker-compose.yml exec app sh
66
+ $(COMPOSE) exec app sh
67
67
 
68
68
  shell-dev: ## Open shell in development container
69
- $(COMPOSE) -f docker/docker-compose.dev.yml exec app sh
69
+ $(COMPOSE) -f docker-compose.dev.yml exec app sh
70
70
 
71
71
  test: ## Run tests (if configured)
72
- $(COMPOSE) -f docker/docker-compose.yml exec app $(PM) test
72
+ $(COMPOSE) exec app $(PM) test
73
73
 
74
74
  env-dev: ## Set up development environment
75
75
  @if [ -f .env.development ]; then \
@@ -9,9 +9,12 @@ WORKDIR /app
9
9
  # Copy package files
10
10
  COPY package*.json ./
11
11
 
12
+ # Configure npm and pnpm to use Chinese mirror registry for faster downloads in China
13
+ RUN npm config set registry https://registry.npmmirror.com
14
+
12
15
  # Install pnpm and dependencies (including devDependencies for building)
13
16
  # Set HUSKY=0 to disable husky in Docker environment
14
- RUN npm install -g pnpm && HUSKY=0 pnpm install
17
+ RUN npm install -g pnpm && pnpm config set registry https://registry.npmmirror.com && HUSKY=0 pnpm install
15
18
 
16
19
  # Copy source code
17
20
  COPY . .
@@ -35,9 +38,12 @@ WORKDIR /app
35
38
  # Copy package files
36
39
  COPY package*.json ./
37
40
 
41
+ # Configure npm and pnpm to use Chinese mirror registry for faster downloads in China
42
+ RUN npm config set registry https://registry.npmmirror.com
43
+
38
44
  # Install pnpm and only production dependencies
39
45
  # Use --ignore-scripts to disable prepare script (husky is in devDependencies)
40
- RUN npm install -g pnpm && pnpm install --prod --ignore-scripts && pnpm store prune
46
+ RUN npm install -g pnpm && pnpm config set registry https://registry.npmmirror.com && pnpm install --prod --ignore-scripts && pnpm store prune
41
47
 
42
48
  # Copy build artifacts from builder stage
43
49
  COPY --from=builder /app/build ./build
@@ -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: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
- - "8091:3001"
11
+ - "${HOST_PORT:-8081}:${PORT:-3001}"
12
12
  environment:
13
13
  - NODE_ENV=${NODE_ENV:-production}
14
14
  - PORT=${PORT:-3001}
@@ -22,6 +22,7 @@ public/*.json
22
22
  .env.*.local
23
23
  .env.development
24
24
  .env.production
25
+ !docker/.env
25
26
 
26
27
  # Logs
27
28
  logs
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from '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
- // 优先使用服务端预取的状态初始化 store
13
- const [store, setStore] = useState(() => {
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
@@ -7,6 +7,9 @@ import { useCurrentFlag, outPhotoDicPath } from '@utils/config'
7
7
 
8
8
  const app = express()
9
9
 
10
+ // 0. Trust proxy - Important for HTTPS reverse proxy (nginx)
11
+ app.set('trust proxy', true)
12
+
10
13
  // 1. Security headers (helmet)
11
14
  app.use(
12
15
  helmet({
@@ -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
- dispatch({ type: REQUEST_QUERY, query })
51
-
52
- callback && callback()
53
- }, 0)
49
+ // 直接同步执行,避免 setTimeout 导致的竞态条件
50
+ dispatch({ type: REQUEST_QUERY, query })
51
+ callback && callback()
54
52
  }
55
53
  }
56
54