使用NestJS发布NextJS
前言:NextJS是实现React SSR的框架,NestJS是NodeJS平台的MVC框架。 或者说:NextJS渲染React,NestJS则是实现MVC的WebServer。
相比较Koa而言,NestJS更好地实现了模块化(module)和路由,以及其他功能,如graphql、redis、mysql的集成、微服务等等。
本文将会说明如何使用NestJS承载NextJS,做到React的SSR
安装依赖项
npm i -g @nestjs/cli
cd [项目文件夹]
nest new my-app
npm install next react react-dom --save
code .
cd src
/* 建立相关文件*/
nest g module view
nest g controller view
nest g service view
更新.prettierrc
view.service.ts
import { Injectable, OnModuleInit } from '@nestjs/common';
import createServer from 'next';
import { NextServer } from 'next/dist/server/next';
import { Request, Response } from 'express';
@Injectable()
export class ViewService implements OnModuleInit {
private server: NextServer;
async onModuleInit(): Promise<void> {
try {
this.server = createServer({
dev: true,
dir: './src/client',
});
await this.server.prepare();
} catch (error) {
console.error(error);
}
}
handler(req: Request, res: Response) {
return this.server.getRequestHandler()(req, res);
}
}
view.controller.ts
import { Controller, Get, Res, Req } from '@nestjs/common';
import { Request, Response } from 'express';
import { parse } from 'url';
import { ViewService } from './view.service';
@Controller('/')
export class ViewController {
constructor(private viewService: ViewService) {}
@Get('home')
public async showHome(@Req() req: Request, @Res() res: Response) {
await this.viewService.handler(req, res);
}
@Get('_next*')
public async assets(@Req() req: Request, @Res() res: Response) {
await this.viewService.handler(req, res);
}
@Get('favicon.ico')
public async favicon(@Req() req: Request, @Res() res: Response) {
await this.viewService.handler(req, res);
}
}
view.module.ts
import { Module } from '@nestjs/common';
import { ViewController } from './view.controller';
import { ViewService } from './view.service';
@Module({
imports: [],
providers: [ViewService],
controllers: [ViewController],
})
export class ViewModule {}
新建src/client/pages/home.tsx
import React from 'react';
import { NextPage } from 'next';
const Home: NextPage = () => {
return <h1>Hello from NextJS! - Home</h1>;
};
export default Home;
启用jsx synthax语法, 在tsconfig.json文件中加入:
"jsx": "react",
为client项目添加配置
src->client
touch .eslintrc.js
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'src/client/tsconfig.json',
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'prettier/@typescript-eslint',
'plugin:prettier/recommended',
],
root: true,
env: {
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': ['warn', { 'argsIgnorePattern': '^_' }]
},
};
nest-cli.json
"sourceRoot": "src/server"
nest-cli 在该文件夹下定位 main.ts 文件作为入口,所以需要在src/server下添加main.js
import { NestFactory } from '@nestjs/core';
import { ViewModule } from './modules/view/view.module';
async function bootstrap() {
const app = await NestFactory.create(ViewModule);
await app.listen(3000);
}
bootstrap();
一切准备就绪后, npm run start
参考:https://github.com/kyle-mccarthy/nest-next
https://medium.com/geekculture/nestjs-react-next-js-in-one-mvc-repo-for-rapid-prototyping-faed42a194ca
https://github.com/thisismydesign/nestjs-starter
最后是源码链接