JSPM

@edgeone/is-spa

0.0.3
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1401
  • Score
    100M100P100Q106107F
  • License MIT

Detect whether a frontend project is SPA, MPA, Hybrid, or SSG. Determine if Nginx/CDN fallback to index.html is needed.

Package Exports

  • @edgeone/is-spa

Readme

is-spa-project

检测前端项目是否为 SPA(单页应用),判断部署时是否需要配置 Nginx/CDN **回源兜底到 index.html**。

支持源码检测构建产物检测两种模式,覆盖 React、Vue、Angular、Svelte、Next.js、Nuxt、SvelteKit、Remix、React Router 等主流框架。

快速开始

const { needsFallback } = require('is-spa-project')

// 传入任意目录,自动判断
needsFallback('./my-project')       // true — 需要配置兜底
needsFallback('./my-project/dist')  // true
needsFallback('./my-nuxt-app')      // false — 不需要兜底

安装

npm install is-spa-project

API

needsFallback(dir, options?): boolean

推荐使用。 判断是否需要配置回源兜底。

const { needsFallback } = require('is-spa-project')

// 自动模式(默认)— 自动判断源码/产物
needsFallback('./cra-spa')          // true
needsFallback('./cra-spa/build')    // true
needsFallback('./nuxt-app')         // false

// 强制源码检测
needsFallback('./my-project', { mode: 'source' })

// 强制构建产物检测
needsFallback('./my-project/dist', { mode: 'dist' })

options.mode

说明
'auto'(默认) 自动判断目录是源码还是构建产物
'source' 强制源码检测(分析 package.json、配置文件)
'dist' 强制构建产物检测(分析 HTML 和 JS 文件)

autoDetect(dir): DetectionResult

自动识别目录类型,返回完整检测结果。

const { autoDetect } = require('is-spa-project')

const result = autoDetect('./my-project')
console.log(result.mode)       // 'source' | 'dist'
console.log(result.type)       // 'spa' | 'mpa' | 'hybrid' | 'ssg' | 'unknown'
console.log(result.confidence) // 'high' | 'medium' | 'low'
console.log(result.reason)     // 人类可读的判定原因

detect(projectRoot): DetectionResult

源码检测模式。分析 package.json、配置文件、入口文件。

detectBuildOutput(distDir): DetectionResult

构建产物检测模式。分析 HTML 文件和 JS bundle 中的路由代码。

isSpa(projectRoot): boolean

源码检测简化版,等价于 detect().type === 'spa' || 'hybrid'

CLI

# 自动模式(自动判断源码/产物)
npx is-spa ./my-project
npx is-spa ./my-project/dist

# 强制构建产物模式
npx is-spa ./my-project/dist --dist

# JSON 输出
npx is-spa ./my-project --json
npx is-spa ./my-project/dist --dist --json

检测结果类型

类型 含义 需要兜底? 部署配置
spa 构建产物只有单个 index.html ✅ 需要 try_files $uri $uri/ /index.html
hybrid SPA 主体 + 独立辅助页面 ✅ 需要 主入口需要兜底
mpa 多个独立 HTML 入口 ❌ 不需要 每个路由有对应文件
ssg SSR/SSG 框架,每个路由有对应 HTML ❌ 不需要 框架构建工具自动处理
unknown 无法判定 ❌ 不需要

支持的框架和路由库

框架检测(快速路径)

框架 依赖 默认判定 可切换为 SPA?
Create React App react-scripts spa
Angular CLI @angular/cli spa
Next.js next ssg
Nuxt nuxt ssg ❌(generate 自动处理)
Gatsby gatsby ssg
React Router (Framework) @react-router/dev ssg ssr: false → spa
SvelteKit @sveltejs/kit ssg fallback → spa
Remix @remix-run/react ssg ssr: false → spa

路由库检测

路由库 生态
vue-router Vue
react-router-dom / react-router React
@tanstack/react-router React
wouter React
@angular/router Angular
svelte-routing Svelte
svelte-spa-router Svelte
page (page.js) Vanilla JS
navigo Vanilla JS
universal-router Vanilla JS

检测原理

源码检测

package.json → 匹配已知框架?→ 框架快速路径(可能读取配置文件)
                    ↓ 否
              检测路由库依赖 + 入口文件数量 + router 使用 → 综合判定

构建产物检测

根目录有 index.html?
├── 没有 → unknown(不存在回源目标)
└── 有 → 扫描 HTML + JS → 判定
信号 SPA SSG MPA
应用 HTML 数 1 多个 多个
HTML body 空壳 有预渲染内容 有各自内容
JS 含路由代码
多 HTML 共享 JS

needsFallback 自动检测

传入目录 → 判断是源码还是产物
├── 有 package.json(含 dependencies)或 src/ → 源码检测
└── 否则 → 产物检测
主模式结果 unknown(low) → 回退另一种模式(仅采纳 high 置信度)

测试

npm test            # 源码检测(24 个测试项目)
npm run test:dist   # 构建产物检测(24 个测试项目)
npm run test:all    # 全部运行

测试覆盖 24 个项目:CRA、Vite+React、Vite+Vue、Angular、Vue CLI(SPA/MPA/Hybrid)、Next.js、Nuxt(SSG/SPA)、SvelteKit(SSG/SPA)、Remix(SSR/SPA)、React Router Framework(SPA)、TanStack Router、wouter、svelte-routing、svelte-spa-router、page.js、navigo、universal-router、原生 HTML(单页/多页)。

License

MIT