You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在fastify-cli创建的TypeScript项目中显式覆盖服务器端口?

解决Fastify-CLI创建的TypeScript项目中PORT环境变量不生效的问题

问题背景

我用fastify-cli创建了TypeScript项目,app.ts以插件形式初始化,代码如下:

import './pre-start'; 
import { join } from 'path';
import AutoLoad, {AutoloadPluginOptions} from '@fastify/autoload';
import { FastifyPluginAsync } from 'fastify';

export type AppOptions = {
  // Place your custom options for app below here.
} & Partial<AutoloadPluginOptions>;


// Pass --options via CLI arguments in command to enable these options.
const options: AppOptions = {
}

const app: FastifyPluginAsync<AppOptions> = async (
    fastify,
    opts
): Promise<void> => {
  // Place here your custom code!

  // Do not touch the following lines

  // This loads all plugins defined in plugins
  // those should be support plugins that are reused
  // through your application
  void fastify.register(AutoLoad, {
    dir: join(__dirname, 'plugins'),
    options: opts
  })

  // This loads all plugins defined in routes
  // define your routes in one of these
  void fastify.register(AutoLoad, {
    dir: join(__dirname, 'routes'),
    options: opts
  })

};

export default app;
export { app, options }

该文件没有服务器监听逻辑,无法在代码中显式指定端口。我沿用Express项目的习惯,通过./pre-start.ts用dotenv加载对应环境的.env文件(development.env、test.env、production.env):

import path from 'path';
import dotenv from 'dotenv';
import commandLineArgs from 'command-line-args';
 
const options = commandLineArgs([
  {
    name: 'env',
    alias: 'e',
    defaultValue: 'development',
    type: String,
  },
]);
 

const result2 = dotenv.config({
  path: path.join(__dirname, `../env/${String(options.env)}.env`),
});
 
if (result2.error) {
  throw result2.error;
}

虽然在app.ts作用域内能读到正确的PORT环境变量,但启动项目时Fastify仍使用默认的3000端口,完全忽略该配置。当前npm命令配置如下:

{
  "scripts": {
    "test": "npm run build:ts && tsc -p test/tsconfig.json && tap --ts \"test/**/*.test.ts\"",
    "start": "npm run build:ts && fastify start -l info dist/app.js",
    "build:ts": "tsc",
    "watch:ts": "tsc -w",
    "dev": "npm run build:ts && concurrently -k -p \"[{name}]\" -n \"TypeScript,App\" -c \"yellow.bold,cyan.bold\" \"npm:watch:ts\" \"npm:dev:start\"",
    "dev:start": "fastify start --ignore-watch=.ts$ -w -l info -P dist/app.js"
  },
}

解决方案

方案一:在启动命令中直接指定端口

fastify-cli的start命令支持通过--port(或缩写-p)参数指定端口,可将环境变量直接嵌入npm脚本:
修改package.json的scripts:

{
  "start": "npm run build:ts && fastify start -l info -p $PORT dist/app.js",
  "dev:start": "fastify start --ignore-watch=.ts$ -w -l info -P -p $PORT dist/app.js"
}

跨平台兼容说明:Windows环境需改用%PORT%,若要同时支持Windows和类Unix系统,可先安装cross-env依赖:

npm install cross-env --save-dev

再修改脚本:

{
  "start": "cross-env npm run build:ts && fastify start -l info -p $PORT dist/app.js",
  "dev:start": "cross-env fastify start --ignore-watch=.ts$ -w -l info -P -p $PORT dist/app.js"
}

方案二:修改app.ts的options配置注入端口

fastify-cli启动时会读取app.ts导出的options对象,可在此直接传入PORT环境变量:
修改app.ts中的options对象:

const options: AppOptions = {
  port: Number(process.env.PORT) || 3000
}

这样fastify-cli启动时会自动使用该端口配置,无需修改命令行参数。

方案三:绕过fastify-cli,手动创建启动文件

若想完全掌控启动流程,可新建server.ts文件,手动初始化Fastify并监听端口:

import './pre-start';
import fastify from 'fastify';
import app from './app';

const server = fastify({
  logger: { level: 'info' }
});

async function start() {
  try {
    await server.register(app);
    const port = Number(process.env.PORT) || 3000;
    await server.listen({ port });
    console.log(`Server running on port ${port}`);
  } catch (err) {
    server.log.error(err);
    process.exit(1);
  }
}

start();

然后修改package.json的scripts,直接运行该文件:

{
  "start": "npm run build:ts && node dist/server.js",
  "dev:start": "nodemon dist/server.js"
}

这种方式更贴近Express的启动模式,完全由开发者控制服务器的初始化和监听逻辑。


内容的提问来源于stack exchange,提问作者Ian Gopfert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 09:10:37