スキップしてメイン コンテンツに移動

[Nest.js] Show static files

Intro

I wanted to use Nest.js and WebRTC(node-webrtc).
NestJS - A progressive Node.js framework
Documentation | NestJS - A progressive Node.js framework

And because I wanted to try with simple page(not use JavaScript frameworks), I added static HTML, CSS, JavaScript into a Nest.js project.

Prepare

Install

First, I installed @nestjs/cli.
First steps | NestJS - A progressive Node.js framework

As same as last time, I couldn't do global install because I had used Volta.
But I could installed by volta.
volta install @nestjs/cli

Create project

nest new nest-web-rtc-sample
volta pin node@12

Run

npm start
After doing "npm start", I could getting "Hello World!" from http://localhost:3000.

Add static files

I could add static files by two ways.

@nestjs/serve-static

First one of them was using "serve-static".
Serve Static | NestJS - A progressive Node.js framework

npm install --save @nestjs/serve-static

And I needed adding a module into app.module.ts

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, '..', 'client'),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Add static files

And I added static files.
L nest-web-rtc-sample
    L client
        L css
            L style.css
        L img
            L car.png
        L js
            L main.bundle.js
        L node_modules
        L ts
            L main.ts
            L rtc-sample.ts
        L index.html
        L hello.html
        L package.json
        L package-lock.json
        L tsconfig.json
        L webpack.config.js
    L {Nest.js project files}

style.css


#main-title{
    font-weight: bold;
    color: blue;
}

main.ts


import { RtcSample } from "./rtc-sample";

function init(){
    const sample = new RtcSample();
    sample.getMessage();
}
init();

rtc-sample.ts


export class RtcSample{
    public getMessage() {
        return fetch('/', {
            method: "GET",
            mode: "cors"
        })
        .then(res => res.text())
        .then(v => console.log(v));
    }
}

index.html


<!DOCTYPE html>
<html>
    <head>
        <title>Index page</title>
        <script src="/js/main.bundle.js"></script>
        <link rel="stylesheet" type="text/css" href="/css/style.css" />
    </head>
    <body>
        <div id="main-title">Index page</div>
        <img src="/img/car.png">
    </body>
</html>

hello.html


<!DOCTYPE html>
<html>
    <head>
        <title>Hello World</title>
        <script src="/js/main.bundle.js"></script>
        <link rel="stylesheet" type="text/css" href="/css/style.css" />
    </head>
    <body>
        <div id="main-title">Hello World!</div>
        <img src="/img/car.png">
    </body>
</html>

pacakage.json


{
    "dependencies": {
        "ts-loader": "^7.0.1",
        "tsc": "^1.20150623.0",
        "typescript": "^3.8.3",
        "webpack": "^4.43.0",
        "webpack-cli": "^3.3.11"
    }
}

webpack.config.js


var path = require('path');

module.exports = {
    mode: 'development',
    entry: {
        'main': './ts/main.ts',
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            }
        ]
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.js']
    },
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, './js'),
        library: 'Page',
        libraryTarget: 'umd'
    }
}

Exclude client files from tsconfig.json of Nest.js

I had to exclude TypeScript files of client from tsconfig.json of Nest.js, or they were also transpiled by building the Nest.js project.

tsconfig.json


{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true
  },
  "exclude": ["node_modules", "dist", "client"]
}

tsconfig.build.json


{
  "extends": "./tsconfig.json",
  "exclude": ["node_modules", "test", "dist", "**/*spec.ts", "client"]
}


Access index.html

I could see index.html when I access http://localhost:3000/client.
Only "index.html" were able to be shown.
If there was no files what was named "index.html", an exception would be thrown.

Other html files?

I couldn't use other html files(ex. hello.html)?

No. I could access hello.html by http://localhost:3000/hello.html.
Of cource, I could access index.html by http://localhost:3000/index.html.

To tell the truth, I could access index.html in all paths under the http://localhost:3000 except the paths what were routed by controller or static files.


useStaticAssets

Another one was "useStaticAssets".
MVC | NestJS - A progressive Node.js framework

This way didn't require any other packages.
But I needed changing main.ts of Nest.js.

main.ts


import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(
    AppModule,
  );
  app.useStaticAssets(join(__dirname, '..', 'client'));
  await app.listen(3000);
}
bootstrap();


And I added static files as same as using "serve-static".

According to the document, if I used template engine such as hbs, I should use this way.

Access static files

I could access index.html by http://localhost:3000/index.html.
And the index.html was also routed root URL.

So when I used "useStaticAssets", I couldn't get "Hello World!" from http://localhost:3000.

sendFile

I also could publish files by "sendFile".

app.controller.ts


import { Controller, Get, Res } from '@nestjs/common';
import { AppService } from './app.service';
import { join } from 'path';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}
...
  @Get('/api/file')
  getFile(@Res() res) {
    return res.sendFile(join(__dirname, '..', 'client/hello.html'));
  }
}


When I wanted to pass the controller to publish HTML, I should choose this.

__dirname was changed?

When I use "serve-static", after I restarted the project some times, __dirname values of app.module.ts was changed and I couldn't access static files.

After I set "incremental" of tsconfig.json false and delete "dist" folder, and restarted, I could access again.

Though, there might be other better way.

コメント

このブログの人気の投稿

[Angular][ASP.NET Core] Upload chunked files

Intro I wanted to send files to Web application (made by ASP.NET Core). If the file size had been small, I didn't need do any special things. But when I tried to send a large file, the error was occurred by ASP.NET Core's limitation. Though I could change the settings, but I didn't want to do that, because I hadn't known the file sizes what would been actually using. So I splitted the data into chunks first, and sent them. After receiving all chunks, I merged them into one file. There might be some libraries or APIs (ex. Stream API) what did them automatically, but I couldn't find them. What I did [ASP.NET Core] Make CORS enabled [Angular] Split a large file into chunks [Angular][ASP.NET Core] Send and receive data as form data [ASP.NET Core] Merge chunks into one file [ASP.NET Core] Make CORS enabled Because the client side application(Angular) and the server side application(ASP.NET Core) had been separated, I had to make CORS(Cross-Origin Requests)

[Nest.js] Use WebSocket with ws

Intro Until last time , I had used node-web-rtc to try WebRTC. But because the example was a little complicated for I understood the core functions of using WebRTC. So I look for other frameworks or libraries. PeerJS is a famous library for WebRTC. peers/peerjs: Peer-to-peer data in the browser. - GitHub peers/peerjs-server: Server for PeerJS - GitHub PeerJS - Simple peer-to-peer with WebRTC A problem is I don't know how to integrate to the Nest.js project. I couldn't find examples. So I don't choose at least this time. What shall I choose? According MDN, WebRTC doesn't specify strictly what technology is used on server application for connecting two devices. Signaling and video calling - Web APIs | MDN But in many examples include MDN's one use WebSocket. samples-server/s/webrtc-from-chat at master · mdn/samples-server · GitHub So I try WebSocket in the Nest.js project. Use WebSocket in a Nest.js project Nest.js has a function for using We