Agent Skillsnixopus/nixopus › node-deploy

node-deploy

GitHub

提供 Node.js/JS/TS 项目的构建与部署指南,涵盖版本检测、包管理器识别、环境变量配置及主流框架的构建启动逻辑。

api/skills/node-deploy/SKILL.md nixopus/nixopus

Trigger Scenarios

检测到 package.json 文件 需要部署 Node.js 应用 涉及 Node.js 环境配置

Install

npx skills add nixopus/nixopus --skill node-deploy -g -y
More Options

Non-standard path

npx skills add https://github.com/nixopus/nixopus/tree/master/api/skills/node-deploy -g -y

Use without installing

npx skills use nixopus/nixopus@node-deploy

指定 Agent (Claude Code)

npx skills add nixopus/nixopus --skill node-deploy -a claude-code -g -y

安装 repo 全部 skill

npx skills add nixopus/nixopus --all -g -y

预览 repo 内 skill

npx skills add nixopus/nixopus --list

SKILL.md

Frontmatter
{
    "name": "node-deploy",
    "metadata": {
        "version": "1.0"
    },
    "description": "Build and deploy Node.js applications — version detection, package managers, framework-specific builds, monorepo support, and Dockerfile patterns. Use when deploying a Node.js, JavaScript, or TypeScript project, or when package.json is detected in the repository."
}

Node.js Deployment

Detection

Project is Node.js if package.json exists in the root directory.

Versions

Node.js version priority:

  1. .node-version or .nvmrc file
  2. engines.node field in package.json
  3. mise.toml or .tool-versions
  4. Defaults to 22

Bun

If Bun is detected as the package manager:

  1. engines.bun field in package.json
  2. .bun-version file
  3. mise.toml or .tool-versions
  4. Defaults to latest

When Bun is the primary runtime, Node.js must still be installed if:

  • The project uses Corepack (packageManager field exists in package.json)
  • Build tools require Node (Astro, Vite, or native addon compilation via node-gyp)
  • Any package.json script explicitly invokes node

Package Managers

Detect in order:

  1. packageManager field in package.json → use Corepack to install exact version (e.g. pnpm@9.1.0)
  2. Lock files:
Lock file Package manager
package-lock.json npm
yarn.lock Yarn (check .yarnrc.yml to distinguish Yarn Berry from Classic)
pnpm-lock.yaml pnpm
bun.lockb or bun.lock Bun
  1. engines fieldengines.pnpm → pnpm, engines.bun → Bun, engines.yarn → Yarn
  2. Default: npm

Install Commands

Package manager With lockfile Without lockfile
npm npm ci npm install
yarn (classic) yarn install --frozen-lockfile yarn install
yarn (berry) yarn install --immutable yarn install
pnpm pnpm install --frozen-lockfile pnpm install
bun bun install --frozen-lockfile bun install

Runtime Variables

Set NODE_ENV=production for the runtime stage. During the build, keep NPM_CONFIG_PRODUCTION=false and YARN_PRODUCTION=false so dev dependencies remain available for compilation. Disable update notifications with NPM_CONFIG_UPDATE_NOTIFIER=false and NPM_CONFIG_FUND=false. Set CI=true to enable CI-appropriate behavior in tooling.

Build & Start

Start Command Resolution

  1. start script in package.json
  2. main or module field in package.json (run with node)
  3. server.js, index.js, or index.ts in root (run with node)

Build Command Resolution

  1. build script in package.json${packageManager} run build
  2. If no build script → skip build step

Output Directory

Framework Output directory
NestJS dist
Next.js (SSR) .next
Next.js (export) out
Nuxt .output
SvelteKit build
Remix build
Astro dist
Vite dist
Angular dist/${projectName}
React (CRA) build
React Router build/client
Default dist

Port Detection

  1. Environment filesPORT=<number> from .env, .env.example, .env.production
  2. package.json scripts — scan start, dev, serve for -p <port>, --port <port>, PORT=<port>
  3. Framework confignext.config.* or vite.config.* for port: <number>
  4. Framework defaults:
Framework Default port
Express 3000
Fastify 3000
NestJS 3000
Hono 3000
Next.js 3000
Nuxt 3000
Remix 3000
SvelteKit 5173
Astro 4321
Vite 5173
React 3000
Vue 8080
  1. Final default: 3000

Framework Detection

From package.json dependencies (merge dependencies + devDependencies). First match wins.

Package pattern Framework Category
express Express Backend
fastify Fastify Backend
@nestjs/core NestJS Backend
hono Hono Backend
next Next.js FullStack
nuxt Nuxt FullStack
@sveltejs/kit SvelteKit FullStack
@remix-run/node or @remix-run/react Remix FullStack
astro Astro Static
vite (without a higher framework) Vite Frontend
react + react-dom (without Next/Remix) React Frontend
vue (without Nuxt) Vue Frontend

Config file fallback:

Config file Framework
nest-cli.json NestJS
next.config.js, next.config.mjs, next.config.ts Next.js
nuxt.config.js, nuxt.config.ts Nuxt
svelte.config.js SvelteKit
remix.config.js Remix
astro.config.mjs, astro.config.js Astro
vite.config.ts, vite.config.js Vite
vue.config.js Vue
angular.json Angular

Framework-Specific Behavior

Next.js

  • Check next.config.* for output: "standalone" → standalone build (smaller image, includes node_modules subset)
  • output: "export" → static site, no server needed
  • Cache .next/cache between builds
  • app/ directory → React Server Components

Nuxt

  • Default start: node .output/server/index.mjs
  • Cache node_modules/.cache

Astro

  • If output is not "server" → static site
  • Cache node_modules/.astro

Monorepo Support

Detection Signals

  • workspaces field in root package.json
  • pnpm-workspace.yaml
  • Build orchestrators: turbo.json, nx.json, lerna.json, rush.json
  • Conventional directories: apps/, packages/, services/

Workspace Package Resolution

  • pnpm: Parse pnpm-workspace.yamlpackages: list
  • npm / yarn / bun: Parse workspaces field in root package.json

Build Steps

  1. Detect workspace configurations automatically
  2. Install all workspace dependencies (copy all package.json files + root lock file)
  3. Respect workspace dependency links
  4. Cache workspace node_modules
  5. Build the target workspace package

Optimizing the Install Layer

Always copy:

  • package.json (root + workspace packages if monorepo)
  • Lock file
  • pnpm-workspace.yaml (if pnpm monorepo)
  • .npmrc (if exists — contains registry config)

Framework-specific install files (copy if they exist, they trigger postinstall):

  • prisma/schema.prisma — Prisma generates client on postinstall
  • .env files needed at build time (e.g. Next.js NEXT_PUBLIC_*)

If package.json defines preinstall or postinstall scripts that depend on source files, copy the entire source before install to avoid broken hooks.

Static Sites

Framework Detection Default output dir
CRA react-scripts in deps build
Vite vite.config.js/ts or build script contains vite build dist
Angular angular.json dist/${projectName}
Astro astro.config.* and output is not "server" dist
Next.js (export) output: "export" in config out
React Router react-router.config.* (ssr: false for SPA) build/client

Serve with Caddy/nginx. SPA fallback, cache headers for hashed assets, gzip/brotli.

Environment Variable Semantics

Build-Time vs Runtime

Framework Build-time prefix Runtime access
Next.js NEXT_PUBLIC_* process.env.* (server only)
Nuxt NUXT_PUBLIC_* process.env.* via useRuntimeConfig()
Vite VITE_* not available at runtime (build-only)
SvelteKit PUBLIC_* $env/static/public (build-only)
Astro PUBLIC_* import.meta.env.* (build-only)
CRA REACT_APP_* not available at runtime (build-only)

Build-time env vars must be available during Docker build step (via ARG + ENV).

System Dependencies

Package Required system packages
Puppeteer Chromium, xvfb, font libraries, Chrome system deps
Playwright Chromium headless shell, system packages
sharp libvips and build tools
bcrypt python3, make, g++
canvas libcairo2-dev, libjpeg-dev, libpango1.0-dev, libgif-dev, build-essential

Dev Dependency Pruning

After build, remove dev dependencies to reduce image size:

  • npm: npm prune --omit=dev
  • yarn: yarn install --production or set NODE_ENV=production during install
  • pnpm: pnpm prune --prod
  • bun: bun install --production

Skip pruning if the start command references a dev dependency (ts-node, tsx, nodemon).

Caching

Framework Cache directory
NestJS node_modules/.cache
Next.js .next/cache
Nuxt node_modules/.cache
SvelteKit node_modules/.cache
Remix .cache
React Router .react-router
Astro node_modules/.astro
Vite node_modules/.vite
Default node_modules/.cache

Dockerfile Patterns

Simple Node.js Server (Express, Fastify, NestJS, Hono)

FROM node:<version>-slim AS base

FROM base AS deps
WORKDIR /app
COPY package.json <lockfile> ./
RUN <install-command>

FROM base AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN <build-command>

FROM base AS runtime
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/package.json ./
EXPOSE <port>
CMD ["node", "dist/index.js"]

Next.js Standalone

FROM node:<version>-slim AS base

FROM base AS deps
WORKDIR /app
COPY package.json <lockfile> ./
RUN <install-command>

FROM base AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN <build-command>

FROM base AS runtime
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app/.next/standalone ./
COPY --from=build /app/.next/static ./.next/static
COPY --from=build /app/public ./public
EXPOSE 3000
CMD ["node", "server.js"]

Static Site (Vite, CRA, Astro static)

FROM node:<version>-slim AS build
WORKDIR /app
COPY package.json <lockfile> ./
RUN <install-command>
COPY . .
RUN <build-command>

FROM caddy:alpine AS runtime
COPY --from=build /app/<output-dir> /srv
COPY Caddyfile /etc/caddy/Caddyfile
EXPOSE 80

Gotchas

  • Yarn Berry (v2+) uses Plug'n'Play by default — node_modules won't exist unless nodeLinker: node-modules is set in .yarnrc.yml
  • npm ci deletes node_modules before installing — copy package.json + lockfile first, install, then copy source for proper layer caching
  • Next.js output: "standalone" must be set in config BEFORE running the build — the build step generates the standalone directory
  • Prisma runs prisma generate on postinstallprisma/schema.prisma must be copied before npm install
  • pnpm with --shamefully-hoist may be needed for packages expecting a flat node_modules layout
  • Bun --frozen-lockfile is the correct flag (not --ci like npm)
  • SvelteKit and Astro dev servers use different ports (5173, 4321) than production — ensure EXPOSE matches the production port

Version History

  • cf05d97 Current 2026-08-20 14:52

Same Skill Collection

api/skills/api-catalog/SKILL.md
api/skills/caddyfile-generation/SKILL.md
api/skills/compose-setup/SKILL.md
api/skills/container-resource-tuning/SKILL.md
api/skills/cpp-deploy/SKILL.md
api/skills/database-migration/SKILL.md
api/skills/deno-deploy/SKILL.md
api/skills/deploy-delegation/SKILL.md
api/skills/deploy-flow/SKILL.md
api/skills/deployment-analysis/SKILL.md
api/skills/diagnostic-workflow/SKILL.md
api/skills/dockerfile-generation/SKILL.md
api/skills/dockerignore-generation/SKILL.md
api/skills/domain-attachment/SKILL.md
api/skills/domain-tls-routing/SKILL.md
api/skills/dotnet-deploy/SKILL.md
api/skills/elixir-deploy/SKILL.md
api/skills/failure-diagnosis/SKILL.md
api/skills/github-onboarding/SKILL.md
api/skills/github-workflow/SKILL.md
api/skills/gleam-deploy/SKILL.md
api/skills/go-deploy/SKILL.md
api/skills/incident-response/SKILL.md
api/skills/java-deploy/SKILL.md
api/skills/machine-ops/SKILL.md
api/skills/mcp-integrations/SKILL.md
api/skills/monorepo-strategy/SKILL.md
api/skills/nixopus-docs/SKILL.md
api/skills/onboarding/SKILL.md
api/skills/php-deploy/SKILL.md
api/skills/post-deploy-verification/SKILL.md
api/skills/pre-deploy-checklist/SKILL.md
api/skills/python-deploy/SKILL.md
api/skills/rollback-strategy/SKILL.md
api/skills/ruby-deploy/SKILL.md
api/skills/rust-deploy/SKILL.md
api/skills/self-heal/SKILL.md
api/skills/shell-deploy/SKILL.md
api/skills/static-deploy/SKILL.md

Metadata

Files
0
Version
cf05d97
Hash
a5914c33
Indexed
2026-08-20 14:52

- 위키
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-29 23:16
浙ICP备14020137号-1 $방문자$