20200225のReactに関する記事は2件です。

Reactのステート管理ツールまとめ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerコンテナだけで完結するフロントエンド環境を構築するぞ!( VSCode Remote Development )

この記事は何?

VSCodeの拡張機能であるRemote Developmentを使えば、Dockerコンテナ内のソースコードを直接書き換えることができます。
これを使えば、わざわざホスト側のソースコードを書き換えてVolumeを使って、変更をコンテナ内部にマウントするなんてことをしなくて済みます。

この記事では、この拡張を使ってDockerコンテナ内だけで完結するフロントエンド( React + Webpack + TypeScript )の環境構築を行います。

詳しい解説や使い方は、以下の素晴らしい記事を参照ください。

Dockerで立ち上げた開発環境をVS Codeで開く!
VS Code Remote Development で Docker 開発環境を利用する
Visual Studio CodeのRemote DevelopmentとDockerで快適な開発環境をゲット

環境構築

Docker Imageの作成

作業がしやすいように、Dockerfileを定義して、自分好みの環境を作っておきます。こちらは、各自でカスタマイズして使いやすくしてください。もしDockerHubなどに既にイメージがある場合は、こちらの工程は不要です。

Dockerfile
# こちらのイメージには node と npm と yarn が入っています
FROM node:lts-alpine

# git と curl をインストール
# alpine版は apt-get ではなく、apkを使います
RUN apk update && apk add --virtual=module curl git

WORKDIR /usr/src/app

Dockerfileが出来たら、それを元にイメージを作成します。

$> docker build -t <任意のイメージ名前> <DockerfileのあるPATH>
example
$> docker build -t frontend .
  • -t : イメージの名前を設定します。イメージ名には大文字はダメみたいです。

処理が完了したら、ちゃんと作成されているか確認してみましょう。
例では、frontendという名前で作成しました。

$> docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE  
frontend            latest              dfcs99e             now                 106MB 
node                lts-alpine          927s12c             now                 88.1MB

ちゃんと作成されていますね。それでは次に行きましょう。

Docker Volumesの作成

volumesを作成します。理由は、volumesを設定しておかないとデータの永続化で出来ないので、誤ってDockerコンテナを削除してしまうと、作業内容が消えてしまいます。なので、volumesを作ってそこにデータを入れて永続化します。

volumesは、dockerが管理するものと任意のフォルダーに管理する方法がありますが、この記事ではdockerが管理する方法をとっています。

$> docker volume create <任意の名前>
example
$> docker volume create ReactAppVolume

こちらもちゃんと作成できているか、確認してみましょう

$> docker volume ls
DRIVER              VOLUME NAME
local               ReactAppVolume

例では、ReactAppVolumeという名前で作成しましたが、ちゃんと作成されていますね。
それでは次に行きましょう。

Docker Containerの作成

実際に作業するコンテナを作成します。こちらのコンテナは基本的にはdocker rmなどはしないようしましょう。volumesを設定してあるので、消しても大丈夫だとは思いますが。。。

$> docker run -d --name <任意の名前> -v <作成したVolume名>:<マウントしたいPATH> <イメージ名> sleep infinity
example
$> docker run -d --name SampleReactApp -v ReactAppVolume:/usr/src/app frontend sleep infinity
  • -d : バックグランドで実行
  • -v : 設定されたPATHにvolumesを設定します
  • --name : dockerコンテナに任意の名前を付けれます
  • sleep infinity : コンテナが起動したときに実行するコマンド。( これをやらないとすぐにコンテナが落ちてしまうため )

※ 本来であれば-pオプションでポート開放する必要があると思いますが、指定しなくても筆者の環境では動いたので、書いていません。
もし一通りやって、http://locahost:8080にアクセスしても404 Not Foundが出た場合は、-p 8080:8080を追加してください。

すでにVolumeがある場合

こちらは、間違ってコンテナを削除してしまった時や、コンテナを複製したい場合に使います。

$> docker run -d --name <任意のコンテナ名> --mount source=<Volume名>,target=<マウントしたいPATH> <イメージ名> sleep infinity
example
$> docker run -d --name SampleReactApp --mount source=ReactAppVolume,target=/usr/src/app frontend sleep infinity
  • --mount : volumeの内容を、指定したtargetのPATHにマウントします

作成したコンテナをVSCodeで開く

コンテナが停止してないとちゃんと動かないことがあったので、停止しておきましょう。
※ コンテナが停止していても、Remote Developmentがちゃんと検知してくれますし、開くときに勝手に起動してくれますので、大丈夫です。

$> docker stop <作成したコンテナ名> or <コンテナID>
example
$> docker stop SampleReactApp

コンテナが停止出来たら、次はVSCodeを開きます。この時Remote Developmentがインストール済みである事を想定しています。インストールをしていない人は、インストールしましょう。

※「 ワークスペースに有効にする 」だと正常に動作しないので、ちゃんと全体にインストールしましょう

そうするとアイコンが追加されて、それをクリックするとDockerコンテナ一覧が表示される画面が表示されます。

その画面が表示されたら、コンテナをVSCodeで開くアイコンがあるので、それをクリックするとコンテナをVSCodeで開くことができます。

今回の例では、イメージ名 : frontendコンテナ名 : SampleReactAppとしていますので、frontend(SampleReactApp)の項目を開きます。

vscode_remote_develop.PNG

DockerコンテナをVSCodeで開けたら後は、環境構築していくだけです。

React + Webpack + TypeScriptの環境構築

※この節のコマンドの実行は、全てDockerコンテナ内で行っています。また、この記事ではyarnを使っています。

まずは、package.jsonの作成です。

package.jsonを生成
/usr/src/app# yarn init
yarn init v1.22.0
question name (app): 
question version (1.0.0): 
question description: 
question entry point (index.js): 
question repository url: 
question author: 
question license (MIT): 
question private: 
success Saved package.json

生成されたpackage.jsonに、npm scripsを定義してましょう。

package.json
{
  "name": "app",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "start": "set NODE_ENV=development & webpack-dev-server",
    "build": "set NODE_ENV=production & webpack"
  }
}

yarn startとコマンドを打てば、サーバが立ち上がってReactの実行結果を確認することができます。
yarn buildとコマンドを打つと、distフォルダーにビルドファイルが出力されます。

※まだこの段階では、コマンドを実行してもエラーになります。

次に、必要なモジュールのインストールを行います。

buildに必要なモジュールをインストール
/usr/src/app# yarn add -D webpack webpack-cli webpack-dev-server html-webpack-plugin clean-webpack-plugin typescript ts-loader @types/react @types/react-dom
  • -D : --save-devの略。package.jsonにdevDependenciesのモジュールとして書かれます。
  • webpack・webpack-cli : Reactをビルドするのに必要なBundler。
  • webpack-dev-server : Reactの表示内容を確認するためのサーバーを立ててくれます。
  • html-webpack-plugin : webpackで、HTMLも出力してくれるプラグイン。
  • clean-webpack-plugin : 古いビルドファイルを削除してくれるプラグイン。
  • typescript : javascriptに型を無理くり付けた言語
  • ts-loader : webpacktypescriptをコンパイルするのに使います。
  • @types/react・@types/react-dom : typescriptreact書くのに必要な型定義ファイル

次は、Reactのインストール

reactをインストール
/usr/src/app# yarn add react react-dom

次にwebpack.config.jsを定義します。こちらは必要最低限の構成になっています。

webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

const mode =
  process.env.NODE_ENV === "production" ? "production" : "development";

const isDev = process.env.NODE_ENV === "development";

const outputPath = path.resolve("src/index.tsx");

module.exports = {
  entry: outputPath,

  mode,

  devtool: isDev ? "source-map" : "none",

  target: "web",

  output: {
    path: path.resolve(__dirname, "dist"),
    publicPath: "/",
    filename: isDev ? "bundle.[hash].js" : "bundle.js"
  },

  resolve: {
    extensions: [".js", ".ts", ".tsx"],
  },

  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/,
        use: "ts-loader"
      }
    ]
  },

  devServer: {
    contentBase: outputPath,
    historyApiFallback: true,
    port: 8080,
    hot: true,
    host:"0.0.0.0"
  },

  plugins: [
    new HtmlWebpackPlugin({
      title: "SampleReactApp"
    }),

    new CleanWebpackPlugin(),
  ]
};

次は、typescriptのコンパイル設定ファイルを定義。こちらは、結構適当です。

tsconfig.json
{
  "compilerOptions": {
    "outDir": "./dist/",
    "sourceMap": true,          // mapファイル出力してー
    "module": "ESNext",         // importを使えるようにしてー
    "noImplicitAny": true,      // 定義無しだと勝手にAny?ダメだ!ゆ゛る゛さ゛ん゛!
    "target": "es5",            // ES5にコンパイルしてー
    "jsx": "react",             // react使うよー
    "strict": true,             // strictモード使うよー
    "moduleResolution": "node", // node_modulesを使えるようにするよー 
    "lib": [
      "dom",   // 多分、必須
      "es2019" // 好きなesのバージョンでいいんじゃない?しらんけど。
    ]
  },
  "include": [
    "./src/**/*.ts",
    "./src/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

設定ファイルが書き終わったら、次はReactのソースコードを書いてきます。

src/index.tsx
import * as React from "react"
import { render } from "react-dom"

const App : React.SFC = () => (
  <div className="app">
    <h1>Hello React!</h1>
  </div>
)

const root = document.createElement("div")

root.id = "root"

document.body.appendChild(root)

render(<App />, root)

WebpackDevServerを立ち上げる

ここまで出来たら、yarn startを実行するとサーバーが立ち上がるので、http://localhost:8080にアクセスすると、Hello React!と書かれたページが表示されていると思います。

サーバーを起動
/usr/src/app# yarn start
yarn run v1.22.0
$ webpack-dev-server
ℹ 「wds」: Project is running at http://0.0.0.0:8080/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /usr/src/app/src/index.tsx
ℹ 「wds」: 404s will fallback to /index.html
ℹ 「wdm」: Hash: 31e9b9d394452c9a83d5
Version: webpack 4.41.6
Time: 2499ms
Built at: 2020-02-25 5:03:20
     Asset       Size  Chunks             Chunk Names
 bundle.js   1.41 MiB    main  [emitted]  main
index.html  186 bytes          [emitted]  
Entrypoint main = bundle.js

...

これで終わりです!お疲れさまでした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む