npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

create-vue-ssr

v1.1.7

Published

A CLI to scaffold vue-ssr projects

Readme

create-vue-ssr

一个用于快速搭建 Vue SSR (服务端渲染) 项目的 CLI 工具。

特性

  • 🚀 快速创建 Vue SSR 项目
  • ⚡ 基于 Vite 构建工具
  • 🎯 TypeScript 支持
  • 📦 内置 Vue Router 和 Pinia 状态管理
  • 🔧 开发环境热重载
  • 📱 现代化的项目结构

使用方法

创建新项目

npm create vue-ssr
pnpm create vue-ssr

运行命令后,会提示你输入项目名称,然后自动创建项目目录并复制模板文件。

启动开发服务器

cd your-project-name
pnpm install
pnpm run dev

构建生产版本

pnpm run build
pnpm run start

项目结构

生成的项目包含以下结构:

your-project/
├── src/
│   ├── components/          # 组件目录
│   ├── views/              # 页面组件
│   ├── router/             # 路由配置
│   ├── stores/             # Pinia 状态管理
│   ├── hooks/              # 自定义 hooks
│   ├── utils/              # 工具函数
│   ├── App.vue             # 根组件
│   ├── main.ts             # 客户端入口
│   ├── entry-client.ts     # 客户端 SSR 入口
│   ├── entry-server.ts     # 服务端 SSR 入口
│   └── index.html          # HTML 模板
├── server/                 # Express 服务器
├── vite.config.ts          # Vite 配置
├── tsconfig.json           # TypeScript 配置
├── nodemon.json            # Nodemon 配置
└── package.json

技术栈

  • Vue 3 - 渐进式 JavaScript 框架
  • Vite - 下一代前端构建工具
  • TypeScript - JavaScript 的超集
  • Vue Router - Vue.js 官方路由管理器
  • Pinia - Vue 的状态管理库
  • Express - Node.js Web 应用框架
  • Axios - HTTP 客户端

可用脚本

在生成的项目中,你可以运行以下命令:

  • pnpm run dev - 启动开发服务器
  • pnpm run build - 构建生产版本
  • pnpm run start - 启动生产服务器
  • pnpm run type-check - TypeScript 类型检查

SSR 特性

  • 服务端渲染 - 提供更好的 SEO 和首屏加载性能
  • 客户端激活 - 无缝的客户端交互体验
  • 数据预取 - 支持服务端数据预取
  • 状态同步 - 服务端和客户端状态自动同步

数据获取

useAsyncData

useAsyncData 是一个强大的组合式函数,用于在 SSR 环境中处理异步数据获取。它支持服务端预取、客户端激活、缓存等功能。

基本用法

<script setup lang="ts">
import { useAsyncData } from '@/hooks/async-data'
import { $fetch } from '@/utils/fetch'

// 基本用法
const { data, pending, refresh, reset } = useAsyncData('user-info', async () => {
  return await $fetch('/api/user/info')
})
</script>

<template>
  <div>
    <div v-if="pending">加载中...</div>
    <div v-else-if="data">
      <h2>{{ data.name }}</h2>
      <p>{{ data.email }}</p>
    </div>
    <button @click="refresh">刷新数据</button>
  </div>
</template>

高级选项

const { data, pending, refresh } = useAsyncData('posts', async () => {
  return await $fetch('/api/posts')
}, {
  // 默认值
  default: () => [],
  
  // 是否在服务端执行
  server: true,
  
  // 是否缓存结果
  cache: true,
  
  // 数据转换
  transform: (data) => data.map(item => ({ ...item, formatted: true })),
  
  // 只选择特定字段
  pick: ['id', 'title', 'content'],
  
  // 监听响应式数据变化
  watch: [searchQuery, currentPage],
  
  // 处理完成后的回调
  onAfterHandle: ({ handleSuccess, serverContext }) => {
    if (!handleSuccess) {
      console.error('数据获取失败')
    }
  }
})

批量数据获取

// 同时获取多个数据源
const [userResult, postsResult, settingsResult] = useAsyncData(
  {
    key: 'user',
    handler: () => $fetch('/api/user'),
    options: { cache: true }
  },
  {
    key: 'posts',
    handler: () => $fetch('/api/posts'),
    options: { default: () => [] }
  },
  {
    key: 'settings',
    handler: () => $fetch('/api/settings'),
    options: { server: false } // 仅在客户端执行
  }
)

$fetch 工具函数

$fetch 是基于 Axios 封装的 HTTP 客户端,提供了统一的错误处理和响应格式。

基本用法

import { $fetch } from '@/utils/fetch'

// GET 请求
const result = await $fetch('/api/users', {
  method: 'get',
  data: { page: 1, limit: 10 }
})

// POST 请求
const result = await $fetch('/api/users', {
  method: 'post',
  data: { name: 'John', email: '[email protected]' }
})

// 处理响应
if (result.isSuccess) {
  console.log('数据:', result.data)
} else {
  console.error('错误:', result.msg)
}

高级选项

// 文件上传
const uploadResult = await $fetch('/api/upload', {
  method: 'post',
  upload: true,
  data: {
    file: fileInput.files[0],
    description: '文件描述'
  },
  onUploadPercent: (percent) => {
    console.log(`上传进度: ${percent}%`)
  }
})

// 下载文件
const blobResult = await $fetch('/api/download/file.pdf', {
  method: 'get',
  responseType: 'blob'
})

// 自定义请求头
const result = await $fetch('/api/protected', {
  headers: {
    'Authorization': `Bearer ${token}`,
    'X-Custom-Header': 'value'
  }
})

// 禁用缓存
const result = await $fetch('/api/real-time-data', {
  cache: false
})

响应格式

interface FetchResult {
  isSuccess: boolean    // 请求是否成功
  code: number | string // 状态码
  msg?: string         // 消息
  data?: any          // 响应数据
  $response?: any     // 原始响应对象
}

实际应用示例

用户列表页面

<script setup lang="ts">
import { ref } from 'vue'
import { useAsyncData } from '@/hooks/async-data'
import { $fetch } from '@/utils/fetch'

const searchQuery = ref('')
const currentPage = ref(1)

// 获取用户列表,支持搜索和分页
const { data: users, pending, refresh } = useAsyncData('users', async () => {
  return await $fetch('/api/users', {
    method: 'get',
    data: {
      search: searchQuery.value,
      page: currentPage.value,
      limit: 10
    }
  })
}, {
  default: () => ({ list: [], total: 0 }),
  watch: [searchQuery, currentPage],
  transform: (data) => ({
    list: data.list || [],
    total: data.total || 0
  })
})

// 删除用户
const deleteUser = async (id: number) => {
  const result = await $fetch(`/api/users/${id}`, {
    method: 'delete'
  })
  
  if (result.isSuccess) {
    await refresh() // 刷新列表
  }
}
</script>

<template>
  <div>
    <input v-model="searchQuery" placeholder="搜索用户..." />
    
    <div v-if="pending">加载中...</div>
    
    <div v-else>
      <div v-for="user in users.list" :key="user.id">
        <h3>{{ user.name }}</h3>
        <p>{{ user.email }}</p>
        <button @click="deleteUser(user.id)">删除</button>
      </div>
      
      <div>总计: {{ users.total }} 用户</div>
    </div>
  </div>
</template>

最佳实践

  1. 使用唯一的 key:确保每个 useAsyncData 调用都有唯一的 key
  2. 合理使用缓存:对于不经常变化的数据启用缓存
  3. 错误处理:始终检查 isSuccess 状态
  4. 加载状态:使用 pending 提供良好的用户体验
  5. 数据转换:使用 transform 选项处理服务端数据格式
  6. 监听依赖:使用 watch 选项自动刷新数据

注意事项

  • 在开发环境中,重复的 key 会产生警告
  • server: false 的请求只在客户端执行
  • 使用 cache: false 可以禁用特定请求的缓存
  • 文件上传时设置 upload: true 会自动处理 FormData

开发

如果你想为这个项目贡献代码:

git clone https://github.com/tianchangNorth/create-vue-ssr.git
cd create-vue-ssr
pnpm install

许可证

MIT

作者

tianchang


如果你觉得这个工具有用,请给个 ⭐ 支持一下!