当部署到vercel时,Nestjs Swagger css未加载

xiozqbni  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(526)

Nestjs swagger ui在部署到vercel时不加载样式,但在本地运行良好

控制台和网络请求

我添加了具有以下配置的vercel.json并将其部署到vercel。

{
  "version": 2,
  "builds": [
    {
      "src": "src/main.ts",
      "use": "@vercel/node"
    }
  ],
  "routes": [
    {
      "src": "/(.*)",
      "dest": "src/main.ts",
      "methods": ["GET", "POST", "PUT", "PATCH", "DELETE"]
    }
  ]
}

main.ts

const swaggerConfig = new DocumentBuilder()
  .setTitle('Tansfun')
  .setDescription('API for Tansfun')
  .setVersion('1.0')

  .addBearerAuth(
    {
      type: 'http',
      scheme: 'bearer',
      bearerFormat: 'APIKey',
      name: 'APIKey',
      description: 'Enter API Key',
      in: 'header',
    },
    'APIKey-auth', 
  )
  .build();

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const document = SwaggerModule.createDocument(app, swaggerConfig);
  app.useGlobalPipes(new ValidationPipe());

  SwaggerModule.setup('api', app, document);

  await app.listen(port);
}
bootstrap();

我用的是@nestjs/swagger v6

kqlmhetl

kqlmhetl1#

我最近遇到了这个问题。幸运的是,我找到了一个工作的工作解决方案,解决方案有点hacky tho
第一个解决方案
是让你的API的swagger JSON文件托管它,并使用它与swagger ui资源管理器

  • 使用nestjs静态提供swagger JSON文件
  • 获取vercel服务器上swagger JSON文件的路径
  • 使用它与一个昂首阔步的ui资源管理器

如何实现解决方案1

步骤

  • 在本地计算机/开发计算机上,将NODE_ENV变量设置为development

在**.env文件中**

NODE_ENV="development"
  • 在项目根目录中创建一个静态文件夹。例如:"昂首阔步-静"
  • 静态提供swagger-static文件夹的内容,此处是serving static files with nestjs上文档的链接

在您的app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'swagger-static'),
      serveRoot: process.env.NODE_ENV === 'development' ? '/' : '/swagger',
    }),
   ],
   controllers: [AppController],
   providers: [AppService],
 })

export class AppModule {}
  • 每次应用程序开始开发时,您都需要生成API的swagger json,并将其存储在一个swagger.json文件中,该文件位于prjects根目录下的swagger-static文件夹中。

issue on github讨论了如何为您的API生成swagger JSON文件,并提供了解决方案
下面是如何生成swagger.json文件的代码片段
在您的main.ts

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { resolve } from 'path';
import { writeFileSync } from 'fs';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const options = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const document = SwaggerModule.createDocument(app, options);
  SwaggerModule.setup('/swagger', app, document);

  await app.listen(process.env.PORT || 3000);

  // get the swagger json file (if app is running in development mode)
  if (process.env.NODE_ENV === 'development') {
    const pathToSwaggerStaticFolder = resolve(process.cwd(), 'swagger-static');

    // write swagger json file
    const pathToSwaggerJson = resolve(
      pathToSwaggerStaticFolder,
      'swagger.json',
    );
    const swaggerJson = JSON.stringify(document, null, 2);
    writeFileSync(pathToSwaggerJson, swaggerJson);
    console.log(`Swagger JSON file written to: '/swagger-static/swagger.json'`);
  }
}

bootstrap();
  • 现在,每当您的应用程序在开发阶段启动时,**带有生成的
  • 生产中,它将在您的vercel域中提供,例如:https://yourprojectname.vercel.app/swagger/swagger.json
  • 将更改推送到vercel,并使用服务器上swagger.json文件的路径测试API
  • 例如:进入swagger用户界面浏览器页面https://petstore.swagger.io/?_ga=2.160760958.2144886769.1670328433-858019792.1670328433#/。在该页面上,在浏览器输入中输入swagger.json文件的路径,然后单击“浏览”。现在,swagger文档将被加载

第二个解决方案(推荐)

在开发中获取丢失的swagger文件,并在vercel上静态手动提供这些文件(您的生产服务)

如何实现解决方案2

步骤

  • 在本地计算机/开发计算机上,将NODE_ENV变量设置为development

在**.env文件中**

NODE_ENV="development"
  • 在项目根目录中创建一个静态文件夹。例如:"昂首阔步-静"
  • 静态提供swagger-static文件夹的内容,此处是serving static files with nestjs上文档的链接

在您的app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'swagger-static'),
      serveRoot: process.env.NODE_ENV === 'development' ? '/' : '/swagger',
    }),
   ],
   controllers: [AppController],
   providers: [AppService],
 })

export class AppModule {}
  • 每次你的应用程序开始开发时,你都会调用http来获取生产服务器上丢失的swagger用户界面资源。
  • 应用启动后,在主.ts文件中检查应用是否处于开发阶段,获取缺少的swagger资源,然后将其存储在根目录的swagger-static文件夹
import { NestFactory } from '@nestjs/core';
 import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
 import { AppModule } from './app.module';
 // core
 import { resolve } from 'path';
 import { writeFileSync, createWriteStream } from 'fs';
 import { get } from 'http';

 async function bootstrap() {
   const app = await NestFactory.create(AppModule);

   const options = new DocumentBuilder()
     .setTitle('Cats example')
     .setDescription('The cats API description')
     .setVersion('1.0')
     .addTag('cats')
     .build();
   const document = SwaggerModule.createDocument(app, options);
   SwaggerModule.setup('/swagger', app, document);

   await app.listen(process.env.PORT || 3000);

   // get the swagger json file (if app is running in development mode)
   if (process.env.NODE_ENV === 'development') {

     // write swagger ui files
     get(
       `${serverUrl}/swagger/swagger-ui-bundle.js`, function 
       (response) {
         response.pipe(createWriteStream('swagger-static/swagger-ui-bundle.js'));
         console.log(
     `Swagger UI bundle file written to: '/swagger-static/swagger-ui-bundle.js'`,
   );
     });

     get(`${serverUrl}/swagger/swagger-ui-init.js`, function (response) {
       response.pipe(createWriteStream('swagger-static/swagger-ui-init.js'));
       console.log(
     `Swagger UI init file written to: '/swagger-static/swagger-ui-init.js'`,
   );
     });

     get(
   `${serverUrl}/swagger/swagger-ui-standalone-preset.js`,
   function (response) {
       response.pipe(
       createWriteStream('swagger-static/swagger-ui-standalone-preset.js'),
     );
       console.log(
       `Swagger UI standalone preset file written to: '/swagger-static/swagger-ui-standalone-preset.js'`,
     );
     });

     get(`${serverUrl}/swagger/swagger-ui.css`, function (response) {
       response.pipe(createWriteStream('swagger-static/swagger-ui.css'));
       console.log(
     `Swagger UI css file written to: '/swagger-static/swagger-ui.css'`,
   );
     });

   }
 }

 bootstrap();
  • 现在,每当您的应用程序开始开发时,缺少的swagger将在本地获取并存储在swagger-static文件夹
  • 在生产文件丢失时,将根据您的vercel服务器的请求提供服务
  • 把你的变化推到vercel上,测试你的昂首阔步。现在一切都应该正常了

相关问题