Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/pmb0/nestjs-tsx-views
Server-side JSX/TSX rendering for your NestJS application
https://github.com/pmb0/nestjs-tsx-views
Last synced: 15 days ago
JSON representation
Server-side JSX/TSX rendering for your NestJS application
- Host: GitHub
- URL: https://github.com/pmb0/nestjs-tsx-views
- Owner: pmb0
- License: mit
- Created: 2020-12-13T13:41:39.000Z (about 4 years ago)
- Default Branch: master
- Last Pushed: 2024-12-11T12:07:41.000Z (about 1 month ago)
- Last Synced: 2024-12-13T23:40:10.085Z (28 days ago)
- Language: TypeScript
- Homepage:
- Size: 1.37 MB
- Stars: 26
- Watchers: 3
- Forks: 0
- Open Issues: 14
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Example
Controller:
```ts
import { Controller, Get, Render } from "@nestjs/common";
import { MyViewProps } from "./views/my-view";@Controller()
export class AppController {
@Get()
@Render("my-view")
index(): MyViewProps {
return { name: "world" };
}
}
````views/my-view.tsx`:
```tsx
import React, { ReactElement } from "react";
import { MainLayout } from "./layouts/main";export interface MyViewProps {
name: string;
title: string;
}const MyView = ({ name, ...props }: MyViewProps): ReactElement => (
Hello {name}
);export default MyView;
```# Highlights
- Fast, since the JSX/TSX files do not have to be transpiled on-the-fly with every request
- Separate NestJS modules can use their own views directories (see [multi module example](https://github.com/pmb0/nestjs-tsx-views/blob/master/example/multiple-modules))
- Works with compiled files (`.js` / `node`) and uncompiled files (`.tsx` / `ts-node`, `ts-jest`, ...)
- Provides React contexts
- Supports execution of GraphQL queries from JSX components# Table of contents
- [Example](#example)
- [Usage](#usage)
- [Synchronous configuration](#synchronous-configuration)
- [Asynchronous configuration](#asynchronous-configuration)
- [React Context](#react-context)
- [GraphQL](#graphql)
- [Configuration](#configuration)
- [License](#license)# Usage
```sh
$ npm install --save nestjs-tsx-views
```Import the module with `TsxViewsModule.register(...)` or `TsxViewsModule.registerAsync(...)`.
## Synchronous configuration
Use `TsxViewsModule.register()`. Available options are described in the [TsxViewsModuleOptions interface](#configuration).
```ts
@Module({
imports: [
TsxViewsModule.register({
viewsDirectory: resolve(__dirname, "./views"),
prettify: true,
forRoutes: [AppController],
}),
],
})
export class MyModule {}
```## Asynchronous configuration
If you want to use retrieve you [TSX views options](#configuration) dynamically, use `TsxViewsModule.registerAsync()`. Use `useFactory` and `inject` to import your dependencies. Example using the `ConfigService`:
```ts
@Module({
imports: [
TsxViewsModule.registerAsync({
useFactory: (config: ConfigService) => ({
viewsDirectory: resolve(__dirname, './views'),
prettify: config.get('PRETTIFY_HTML'
)
forRoutes: [AppController],
}),
inject: [ConfigService],
}),
],
})
export class MyModule {}
```## React Context
1. Define a React context:
```tsx
import { createContext } from 'react'export interface MyContextProps {
name: string
}export const MyContext = createContext
```2. Set the context in your controller (or provider):
```ts
@Controller()
export class AppController {
constructor(private readonly ssr: TsxViewsService) {}@Get()
@Render("my-view")
index() {
this.#ssr.addContext(MyContext, { name: "My context data" });return {};
}
}
```3. Use it somewhere in your component:
```tsx
import { useContext } from "react";
import { MyContext } from "./my-context";export function MyComponent() {
const { name } = useContext(MyContext);
return Hallo, {name}!;
}
```## GraphQL
This module supports the execution of GraphQL queries from the TSX template. For this purpose `graphql`, `@apollo/client` and `cross-fetch` have to be installed separately:
```sh
$ npm install --save @apollo/client cross-fetch graphql
```See `example/graphql/app.module.ts` for a working example of how to configure the NestJS module. View example:
```ts
// example/graphql/views/my-view.tsxexport interface Film {
id: string;
title: string;
releaseDate: string;
}export interface AllFilms {
allFilms: {
films: Film[];
};
}const MY_QUERY = gql`
query AllFilms {
allFilms {
films {
id
title
releaseDate
}
}
}
`;export interface MyViewProps {
name: string;
title: string;
}const MyView = (props: MyViewProps): ReactElement => {
const { data, error } = useQuery(MY_QUERY);if (error) {
throw error;
}return (
Films:
{data?.allFilms.films.map((film) => (
{film.title} ({new Date(film.releaseDate).getFullYear()})
))}
);
};
export default MyView;
```
## Configuration
nestjs-tsx-views can be configured with the following options:
```ts
export interface TsxViewsModuleOptions extends ReactViewsOptions {
/**
* The directory where your views (`.tsx` files) are stored. Must be
* specified.
*/
viewsDirectory: string;
/**
* [Doctype](https://developer.mozilla.org/en-US/docs/Glossary/Doctype) to
* be used. */
doctype?: string;
/**
* If activated, the generated HTML string is formatted using
* [prettier](https://github.com/prettier/prettier)
*/
prettify?: boolean;
/**
* With this optional function the rendered HTML document can be modified. For
* this purpose a function must be defined which gets the HTML `string` as
* argument. The function returns a modified version of the HTML string as
* `string`.
*/
transform?: (html: string) => string | Promise;
/**
* Excludes routes from the currently processed middleware.
*
* @param {(string | RouteInfo)[]} routes
* @returns {MiddlewareConfigProxy}
*/
exclude?: (string | RouteInfo)[];
/**
* Attaches passed either routes or controllers to the currently configured middleware.
* If you pass a class, Nest would attach middleware to every path defined within this controller.
*
* @param {(string | Type | RouteInfo)[]} routes
* @returns {MiddlewareConsumer}
*/
forRoutes?: (string | Type | RouteInfo)[];
}
```
# License
nestjs-tsx-views is distributed under the MIT license. [See LICENSE](./LICENSE) for details.