Typescript、NodeJS、ExpressアプリをHerokuにデプロイする方法

HankCa

完全な情報が見つからなかったので、これに関するハウツーを提供したかったのです。Stackoverflowのドキュメントではこれが最も適切だと思いました。ただし、廃止されました*-)-廃止されたドキュメント(*)。

代わりに、これをStackOverflow Q&Aとして記述します。

Typescript、NodeJS、ExpressアプリをHerokuにデプロイする方法

HankCa

何をする必要があるかを説明するREADMEを含むプロジェクト(https://gitlab.com/OehmSmith_Examples/herokumoviesを作成しました。ここでそれを再現します。StackOverflowの優れたプラクティスとして、この投稿の最後にすべてのコードのコピーも提供します。

チュートリアル-TypescriptNodeJSExpressアプリをHerokuにデプロイする

このチュートリアルは、https://amenallah.com/node-js-typescript-jest-express-starter/からベースアプリとして機能します私はそのサイトや作者とは何の関係もありません。シンプルで機能するので選びました。これは、優れたOOTypescriptコードの例でもあります。

typescriptをインストールする

ほとんどのチュートリアルまたはhttps://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.htmlの公式ドキュメントでさえ、typescriptをグローバルにインストールすると述べています

 > npm install -g typescript

Herokuにはtypescriptのグローバルインストールがないため、ローカルに保持する必要があります。サンプルプロジェクトはこれを実行します。

 > npm i -D nodemon rimraf typescript ts-node ts-jest jest @types/jest @types/node

@ types / node

@types/node古いバージョンに固定している場合は、次のようなエラーが表示されます。

~/AppData/Roaming/nvm/v11.15.0/node_modules/typescript/lib/lib.es2015.iterable.d.ts:41:6 - error TS2300: Duplicate identifier 'IteratorResult'.

41 type IteratorResult<T, TReturn = any> = IteratorYieldResult<T> | IteratorReturnResult<TReturn>;
        ~~~~~~~~~~~~~~

  node_modules/@types/node/index.d.ts:170:11
    170 interface IteratorResult<T> { }
                  ~~~~~~~~~~~~~~
    'IteratorResult' was also declared here.

node_modules/@types/node/index.d.ts:170:11 - error TS2300: Duplicate identifier 'IteratorResult'.

170 interface IteratorResult<T> { }
              ~~~~~~~~~~~~~~

~/AppData/Roaming/nvm/v11.15.0/node_modules/typescript/lib/lib.es2015.iterable.d.ts:41:6
    41 type IteratorResult<T, TReturn = any> = IteratorYieldResult<T> | IteratorReturnResult<TReturn>;
            ~~~~~~~~~~~~~~
    'IteratorResult' was also declared here.


Found 2 errors.

TypeScriptから:重複した識別子 'IteratorResult'そしてそれに従ってあなたはあなたのバージョンを更新する必要があります@types/nodeこれは、古いコードで作業していて、この議論を含めたいと思ったときに私が直面した問題でした。

クラウドサービスのポートを更新します

index.ts元のコードはポート5000をハードコードしているため、代わりにを次のように変更します。

app.listen(process.env.PORT, () => {
    console.log(`server started on port ${process.env.PORT}`)
});

これを可能にするために、コンパイルされたタイプスクリプトからHerokuと同じように実行できるようにnpm scripts、を追加するなど、PORTをに追加しましたstart:dev

    "start:dev": "PORT=5000 node dist/index.js",
    "dev": "PORT=5000 nodemon --exec ts-node src/index.ts --watch src",

または、.envファイルで設定できます。

PORT=5000

NPMの依存関係

Herokuは開発依存関係をインストールしません(他のクラウドプロバイダーもインストールしません)。したがって、いくつかの依存関係をメインブロックに移動する必要があります。たとえば、NestJSアプリケーションにはこれらが開発依存関係としてあり、移動する必要があります。

 @nestjs/cli

ダミーデータ

このコンストラクターをMoviesApi.tsに追加しました

constructor() {
    // setup some dummy data
    movies.push({
        name: 'Pirates of the caribbean',
        rating: 8.5
    })
    movies.push({
        name: 'Star Wars: A new hope',
        rating: 8.7
    })
}

Heroku

Herokuにデプロイします

  1. アカウントをまだお持ちでない場合はアカウントを設定し、Herokuでアプリを作成します
  2. ターミナルで:

    heroku login
    heroku create moviesheroku // this needs to be unique
    
  3. 返されたgiturlをリモートとして追加する必要がある場合があります(で確認してくださいgit remote -v)。

    git remote add heroku <git url>
    
  4. ビルドパックを検索または検索します(次のステップでは、使用するビルドパックをすでに指定しています)。

  5. ビルドパックを追加します。

    heroku buildpacks:add zidizei/typescript
    heroku buildpacks:add heroku/nodejs
    
  6. ビルドパックを確認します。

    heroku buildpacks
    
  7. ローカルリポジトリにコミットする

    git init  // if not already done
    git add --all
    git ci -m "Initial commit.  Test project all setup and should be ready to 'serve' but not yet ready to deploy to heroku"
    
  8. で実行

    npm dev # OR
    npm run start:dev # It depends on your npm scripts
    
  9. postmanなどでテストするか、コマンドラインからこれを実行します。

    curl http://localhost:5000/movies
    
  10. それが発生することをテストする npm run build

  11. npmスクリプトを更新して、npm installHerokuに)をインストールした後、実行する前にビルドするようにします。npm run start

    "postinstall": "npm run build"  # Depends on your npm scripts
    
  12. ローカルリポジトリにコミットします。

    git add --all
    git ci -m "Now it should deploy, build and run on heroku"
    
  13. herokuにデプロイします。ビルドして起動する必要があります。

    git push heroku master
    
  14. テスト(アプリheroku createmoviesheroku-それに応じて調整すると仮定

    curl https://moviesheroku.herokuapp.com/movies
    

バリエーション

Procfile

ProcfileこのアプリについてHerokuに伝えることは指定していません幸い、これがnode + npmアプリであると判断して、独自のデフォルトを作成します。ただし、これを明示的に定義することができ、複数のアプリなどがある場合は、このアクションを実行する必要があります。以下を含むProcfileを追加できます(これがデフォルトです)。

web: npm start

ノードとNPMのバージョン

Herokuは、デフォルトでこれらの最新バージョンの1つを使用します。次のpackage.jsonように、ファイルのトップレベルでバージョンを明示的に設定できます。

 "engines": {
     "node": "10.x",
     "npm": "6.x"
 },

ただし、npmバージョンを指定しない場合、Herokuはノードのバージョンに適切なデフォルトを使用します。

結論

私はこれをほんの数時間で行った。私が解決する必要があった主な問題は、typescriptがグローバルではなくローカルでなければならないということです。そしてビルドパック。PORTも問題ですが、すべてのクラウドプロバイダーがを使用する必要があるため、process.env.PORTこれは私には明らかでした。

Azureは悪夢であり、数日かかりましたが、それは主に、私がWindowsサーバーの使用を主張していた職場が原因でした。長い話と私はそれには入りません。

AWSはとても複雑でした。1日試しても、作業中のインスタンスを取得できませんでした。ただし、再試行する必要があります。私が試していたアプリはhttps://tsed.io/ライブラリを使用していましたSimple Node / Typescript / Expressアプリは非常に簡単に動作するはずです。

(*)-2年以上前に起こったことを考えると、ドキュメントの廃止は少し意外でしたが、私が使用したものではなかったと思います。そして、私はいつもQ&Aがドキュメント化のための最も簡単な場所だと思っていました。

コード

.gitignore

    node_modules
    dist
    coverage

.jest.config.js

    module.exports = {
        preset: 'ts-jest',
        testEnvironment: 'node'
    };

package.json

    {
      "name": "movies",
      "version": "1.0.0",
      "description": "Example from https://amenallah.com/node-js-typescript-jest-express-starter/ but then modify and / or show steps for how to deploy this Typescript NodeJS Express RESTful app to Heroku.",
      "main": "index.js",
      "scripts": {
        "build": "rimraf dist && tsc",
        "postinstall": "npm run build",
        "start": "node dist/index.js",
        "start:dev": "PORT=5000 node dist/index.js",
        "dev": "PORT=5000 nodemon --exec ts-node src/index.ts --watch src",
        "test": "jest --watch",
        "coverage": "jest --coverage"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "@types/express": "^4.17.2",
        "@types/jest": "^24.0.25",
        "@types/node": "^13.1.2",
        "jest": "^24.9.0",
        "nodemon": "^2.0.2",
        "rimraf": "^3.0.0",
        "ts-jest": "^24.2.0",
        "ts-node": "^8.5.4",
        "typescript": "^3.7.4"
      },
      "dependencies": {
        "body-parser": "^1.19.0",
        "express": "^4.17.1"
      }
    }

tsconfig.json

    {
      "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "outDir": "dist",
        "sourceMap": false,
        "allowSyntheticDefaultImports": true,
        "baseUrl": ".",
        "paths": {
          "*": [
            "node_modules/",
          ],
          "typings/*": [
            "src/typings/*"
          ]
        },
      },
      "include": [
        "src/**/*.ts"
      ],
      "exclude": [
        "src/test/**/*.spec.ts"
      ]
    }

src/api/MoviesApi.ts

    import IResource from "typings/IResource";

    let movies: object[] = []

    export default class MoviesApi implements IResource {
        constructor() {
            // setup some dummy data
            movies.push({
                name: 'Pirates of the caribbean',
                rating: 8.5
            })
            movies.push({
                name: 'Star Wars: A new hope',
                rating: 8.7
            })
        }

        create(data: any): any {
            movies.push(data)
            return data
        }

        findMany(): any[] {
            return movies;
        }
    }

src/test/api/Movies.spec.ts

    import IResource from '../typings/IResource'
    import MoviesApi from '../api/MoviesApi'

    const moviesApi: IResource = new MoviesApi()

    describe('Movies API', () => {
        it('should create a new movie', () => {
            const movieData: object = {
                name: 'Pirates of the caribbean',
                rating: 8.5
            };

            const movie: object = moviesApi.create(movieData);

            expect(movie).toEqual(movieData)
        })
    });

src/typings/IResource/index.d.ts

    export default interface IResource {
        create(data: any): any
        findMany(): any[]
    }

src/index.ts

    import * as express from 'express'
    import * as bodyParser from 'body-parser'

    import MoviesApi from './api/MoviesApi'

    const app = express();
    const moviesApi = new MoviesApi();

    app.use(bodyParser.json());

    app.post('/movies', (req: express.Request, res: express.Response) => {
        res.json(moviesApi.create(req.body))
    });

    app.get('/movies', (req: express.Request, res: express.Response) => {
        res.json(moviesApi.findMany())
    });

    app.listen(process.env.PORT, () => {
        console.log(`server started on port ${process.env.PORT}`)
    });

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

NodeJSアプリをHerokuにデプロイする

分類Dev

SpringBootアプリプロジェクトをHerokuにデプロイする方法

分類Dev

NodeJsアプリをAzureWebアプリにデプロイする方法

分類Dev

nodejsとvuejsをherokuにデプロイする方法

分類Dev

reactJSアプリケーションをHerokuにデプロイする方法

分類Dev

Heroku:デプロイ時にPythonアプリを自動起動する方法は?

分類Dev

Scala HTTP4SアプリをHerokuにデプロイする方法は?

分類Dev

Kotlin アプリケーションを Heroku にデプロイする方法は?

分類Dev

Angular 2アプリ(Angular cli)をherokuにデプロイする

分類Dev

Node.jsアプリをherokuにデプロイする

分類Dev

HerokuにDjangoAPI + Reactアプリをデプロイする

分類Dev

Spring MVCWebアプリをherokuにデプロイする

分類Dev

SpringBootアプリをHerokuにデプロイする際のSQLSyntaxErrorException

分類Dev

CodeIgniterPhpアプリをherokuにデプロイする

分類Dev

HerokuにDjango1.7アプリをデプロイする

分類Dev

Laravel-Herokuにアプリをデプロイする

分類Dev

Twilioを既存のHerokuアプリにデプロイする

分類Dev

Heroku に React アプリをデプロイする

分類Dev

Angular-Universalアプリをherokuにデプロイする

分類Dev

Typescript Node.jsアプリをHerokuにデプロイするにはどうすればよいですか?

分類Dev

nodejsアプリケーションをGoogleCloudにデプロイする方法は?

分類Dev

nodejsアプリを共有サーバーにデプロイする方法

分類Dev

React + NodeJS + Express + MySQLアプリをHerokuにデプロイする場合は、サーバーのみをデプロイし、Reactはデプロイしません

分類Dev

HerokuにhttpサーバーなしでnodeJSアプリをデプロイする

分類Dev

nodejsアプリをGoogleCloudPlatformにデプロイする

分類Dev

VSCodeからAzureにNodeJSアプリをデプロイする

分類Dev

JenkinsがNodeJSアプリをAzureにデプロイする

分類Dev

macchiato clojurescriptアプリをHeroku無料アカウントにデプロイする方法は?

分類Dev

`dep`を使用して、内部パッケージを持つGoアプリをHerokuにデプロイする方法

Related 関連記事

  1. 1

    NodeJSアプリをHerokuにデプロイする

  2. 2

    SpringBootアプリプロジェクトをHerokuにデプロイする方法

  3. 3

    NodeJsアプリをAzureWebアプリにデプロイする方法

  4. 4

    nodejsとvuejsをherokuにデプロイする方法

  5. 5

    reactJSアプリケーションをHerokuにデプロイする方法

  6. 6

    Heroku:デプロイ時にPythonアプリを自動起動する方法は?

  7. 7

    Scala HTTP4SアプリをHerokuにデプロイする方法は?

  8. 8

    Kotlin アプリケーションを Heroku にデプロイする方法は?

  9. 9

    Angular 2アプリ(Angular cli)をherokuにデプロイする

  10. 10

    Node.jsアプリをherokuにデプロイする

  11. 11

    HerokuにDjangoAPI + Reactアプリをデプロイする

  12. 12

    Spring MVCWebアプリをherokuにデプロイする

  13. 13

    SpringBootアプリをHerokuにデプロイする際のSQLSyntaxErrorException

  14. 14

    CodeIgniterPhpアプリをherokuにデプロイする

  15. 15

    HerokuにDjango1.7アプリをデプロイする

  16. 16

    Laravel-Herokuにアプリをデプロイする

  17. 17

    Twilioを既存のHerokuアプリにデプロイする

  18. 18

    Heroku に React アプリをデプロイする

  19. 19

    Angular-Universalアプリをherokuにデプロイする

  20. 20

    Typescript Node.jsアプリをHerokuにデプロイするにはどうすればよいですか?

  21. 21

    nodejsアプリケーションをGoogleCloudにデプロイする方法は?

  22. 22

    nodejsアプリを共有サーバーにデプロイする方法

  23. 23

    React + NodeJS + Express + MySQLアプリをHerokuにデプロイする場合は、サーバーのみをデプロイし、Reactはデプロイしません

  24. 24

    HerokuにhttpサーバーなしでnodeJSアプリをデプロイする

  25. 25

    nodejsアプリをGoogleCloudPlatformにデプロイする

  26. 26

    VSCodeからAzureにNodeJSアプリをデプロイする

  27. 27

    JenkinsがNodeJSアプリをAzureにデプロイする

  28. 28

    macchiato clojurescriptアプリをHeroku無料アカウントにデプロイする方法は?

  29. 29

    `dep`を使用して、内部パッケージを持つGoアプリをHerokuにデプロイする方法

ホットタグ

アーカイブ