1. 開発環境の構築
JavaScript 開発環境を構築するためには、以下の手順を実行してください。
1.1. バージョンマネージャー
バージョンマネージャーを使用することで、異なるバージョンの Node.js を簡単に切り替えることができます。以下の手順でバージョンマネージャーをセットアップしてください。
1.1.1. バージョンマネージャーのセットアップ
-
NVM をインストールします。NVM は、Node.js のバージョンを管理するためのツールです。以下のコマンドを実行して、NVM をインストールしてください。
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
-
npm をインストールします。npm は、Node.js のパッケージマネージャーです。以下のコマンドを実行して、npm をインストールしてください。
nvm list
nvm install 16.10.1
npm -v
-
yarn をインストールします。yarn は、npm の代替となるパッケージマネージャーです。以下のコマンドを実行して、yarn をインストールしてください。
npm install -g yarn
yarn -v
-
ターミナルを再起動します。
1.1.2. トランスパイラ
トランスパイラを使用することで、ES6 以降の構文を ES5 に変換することができます。以下の手順でトランスパイラをセットアップしてください。
1.1.3. トランスパイラのセットアップ
-
package.json ファイルを作成します。以下のコマンドを実行して、package.json ファイルを作成してください。
npm init -y
-y オプションを指定することで、package.json ファイルの内容をデフォルト値で作成することができます。
-
Babel をインストールします。Babel は、トランスパイラの一つです。以下のコマンドを実行して、Babel をインストールしてください。
npm install --save-dev @babel/core @babel/cli @babel/preset-env
--save-dev オプションを指定することで、package.json ファイルの devDependencies にパッケージを追加することができます。
-
.babelrc ファイルを作成します。以下のコマンドを実行して、.babelrc ファイルを作成してください。
touch .babelrc
-
.babelrc ファイルに以下の内容を記述してください。
{
"presets": ["@babel/preset-env"]
}
1.1.4. トランスパイラの設定
-
package.json ファイルを開き、以下の内容を追加してください。
{
"scripts": {
"build": "babel src -d dist"
}
}
scripts には、npm コマンドを登録することができます。今回は、build コマンドを登録しています。build コマンドは、src ディレクトリの JavaScript ファイルをトランスパイルして、dist ディレクトリに出力するコマンドです。
1.1.5. トランスパイラの実行
-
src ディレクトリを作成して、index.js ファイルを作成します。
// テンプレートリテラル
const name = 'John Doe';
const message = `Hello, ${name}!`;
// アロー関数
const add = (x, y) => x + y;
// デフォルトパラメーター
function greet(name = 'World') {
console.log(`Hello, ${name}!`);
}
// 分割代入
const person = {
firstName: 'John',
lastName: 'Doe'
};
const { firstName, lastName } = person;
// スプレッド演算子
const arr = [1, 2, 3];
const arrCopy = [...arr];
// クラス
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
-
以下のコマンドを実行して、トランスパイルを実行してください。
npm run build
-
ES6 以降の構文が ES5 に変換されていることを確認してください。
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
// テンプレートリテラル
var name = 'John Doe';
var message = "Hello, ".concat(name, "!");
// アロー関数
var add = function add(x, y) {
return x + y;
};
// デフォルトパラメーター
function greet() {
var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'World';
console.log("Hello, ".concat(name, "!"));
}
// 分割代入
var person = {
firstName: 'John',
lastName: 'Doe'
};
var firstName = person.firstName,
lastName = person.lastName;
// スプレッド演算子
var arr = [1, 2, 3];
var arrCopy = [].concat(arr);
// クラス
var Person = /*#__PURE__*/function () {
function Person(firstName, lastName) {
_classCallCheck(this, Person);
this.firstName = firstName;
this.lastName = lastName;
}
_createClass(Person, [{
key: "getFullName",
value: function getFullName() {
return "".concat(this.firstName, " ").concat(this.lastName);
}
}]);
return Person;
}();
1.2. モジュールバンドラー
モジュールバンドラーを使用することで、複数の JavaScript ファイルを一つのファイルにまとめることができます。以下の手順でモジュールバンドラーをセットアップしてください。
1.2.1. モジュールバンドラーのセットアップ
-
Webpack をインストールします。Webpack は、モジュールバンドラーの一つです。以下のコマンドを実行して、Webpack をインストールしてください。
npm install --save-dev webpack webpack-cli
npx webpack --version
npx コマンドは、npm パッケージを実行するためのコマンドです。npx コマンドを使用することで、ローカルにインストールされている npm パッケージを実行することができます。
-
webpack.config.js ファイルを作成します。以下のコマンドを実行して、webpack.config.js ファイルを作成してください。
touch webpack.config.js
-
webpack.config.js ファイルに以下の内容を記述してください。
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: __dirname + '/dist',
filename: 'bundle.js',
},
};
-
package.json ファイルに以下の内容に変更してください。
{
"scripts": {
"build": "webpack"
}
}
1.2.2. モジュールバンドラーの実行
-
./src/sample_es5.js ファイルを作成してください。
function greeting(name) {
return 'Hello ' + name;
}
module.exports = greeting;
-
./src/index.js ファイルを変更してください。
var greeting = require('./sample_es5');
console.log(greeting('ES5'));
-
以下のコマンドを実行して、モジュールバンドラーを実行してください。
npm run build
-
./dist/bundle.js ファイルが作成されていることを確認してください。
-
./dist/bundle.js ファイルを実行してください。
node ./dist/bundle.js
1.2.3. モジュールバンドラーの設定
-
./src/sample_es6.js ファイルを作成してください。
class Greeting {
constructor(name) {
this.name = name;
}
say() {
console.log(`Hello ${this.name}`);
}
}
export default Greeting;
-
./src/index.js ファイルを変更してください。
var greeting = require('./sample_es5');
console.log(greeting('ES5'));
var greet = require('./sample_es6');
var g = new greet.default('ES6');
g.say();
-
以下のコマンドを実行して、モジュールバンドラーを実行してください。
npm run build
-
./dist/bundle.js ファイルが作成されていることを確認してください。
-
./dist/bundle.js ファイルを実行してください。
node ./dist/bundle.js
-
現状では ES6 のコードをそのまま出力しています。ES5 に変換するためには、babel-loader を使用します。 パッケージをインストールして webpack.config.js に以下のコードを変更してください。
npm install --save-dev babel-loader
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: __dirname + '/dist',
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
],
},
],
},
target: ['web', 'es5'],
};
-
以下のコマンドを実行して、モジュールバンドラーを実行してください。
npm run build
-
./dist/bundle.js ファイルが作成されていることを確認してください。
-
./dist/bundle.js ファイルを実行してください。
node ./dist/bundle.js
1.3. TypeScript
TypeScript を使用することで、JavaScript に型を導入することができます。以下の手順で TypeScript をセットアップしてください。
1.3.1. TypeScript のセットアップ
-
TypeScript をインストールします。以下のコマンドを実行して、TypeScript をインストールしてください。
npm install --save-dev typescript
-
tsconfig.json ファイルを作成します。以下のコマンドを実行して、tsconfig.json ファイルを作成してください。
npx tsc --init
1.3.2. トランスパイラの設定
-
必要なパッケージをインストールします。
npm install --save-dev @babel/preset-typescript @babel/plugin-proposal-class-properties typescript
-
.babelrc ファイルを変更します。
{
"presets": [
"@babel/preset-env",
"@babel/preset-typescript"
],
"plugins": ["@babel/plugin-proposal-class-properties"]
}
1.3.3. トランスパイラの実行
-
./src/sample.ts ファイルを作成してください。
class Greeting {
constructor(public name: string) {}
say() {
console.log(`Hello ${this.name}`);
}
}
-
./src/index.ts ファイルを変更してください。
import { Greeting } from "./sample";
const greeting = new Greeting("TypeScript");
greeting.say();
-
以下のコマンドを実行して、トランスパイルを実行してください。
npx babel src --extensions '.ts,.tsx' --out-dir dist
-
./dist/sample.js ファイルが作成されていることを確認してください。
-
./dist/sample.js ファイルを実行してください。
node ./dist/index.js
1.3.4. モジュールバンドラーの設定
-
必要なパッケージをインストールします。
npm install --save-dev ts-loader
-
webpack.config.js ファイルを開き、以下の内容を追加してください。
module.exports = {
mode: 'development',
entry: './src/index.ts',
output: {
path: __dirname + '/dist',
filename: 'bundle.js',
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
},
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
],
},
{
test: /\.tsx?$/,
loader: 'ts-loader',
},
],
},
target: ['web', 'es5'],
};
-
以下のコマンドを実行して、モジュールバンドラーを実行してください。
npm run build
-
./dist/bundle.js ファイルが作成されていることを確認してください。
-
./dist/bundle.js ファイルを実行してください。
node ./dist/bundle.js
TypeScript ファイルをそのまま実行したい場合は、ts-node を使用します。
npm install --save-dev ts-node
動かし方は以下の通りです。
npx ts-node src/index.ts
1.4. webpack-dev-server のセットアップ
webpack-dev-server を使用することで、開発中に自動的にビルドを実行し、ブラウザをリロードすることができます。以下の手順で webpack-dev-server をセットアップしてください。
1.4.1. webpack-dev-server のインストール
-
以下のコマンドを実行して、webpack-dev-server をインストールしてください。
npm install --save-dev webpack-dev-server
1.4.2. webpack-dev-server の設定
-
webpack.config.js ファイルを開き、以下の内容を追加してください。
const path = require('path');
module.exports = {
//...
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
compress: true,
port: 9000,
},
};
1.4.3. webpack-dev-server の実行
-
以下のコマンドを実行して、webpack-dev-server を実行してください。
npx webpack serve
終了する場合は、Ctrl + C を押してください。
-
HTMLWebpackPlugin プラグインを使用して js ファイルに自動的にバンドルされた script タグを生成し、index.html に挿入できるようにします。
npm install --save-dev html-webpack-plugin
-
プロジェクト直下に index.html を作成してください。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>App</title>
</head>
<body>
<h1>アプリケーション</h1>
</body>
</html>
-
webpack.config.js ファイルを開き、以下の内容を追加してください。
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// ...他のWebpack設定
plugins: [
new HtmlWebpackPlugin({
template: 'index.html',
}),
],
};
-
package.json ファイルを開き、以下の内容を追加してください。
{
// ...他の設定
"scripts": {
"start": "webpack server --config ./webpack.config.js --open"
}
}
-
以下のコマンドを実行して、webpack-dev-server を実行してください。
npm start
-
ソースマップを有効にすることで、開発中にエラーが発生した場合に、エラーが発生したファイル名と行数を表示することができます。
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const env = process.env.NODE_ENV || "development";
const isDevelopment = env === "development";
module.exports = {
mode: env,
devtool: isDevelopment ? "source-map" : false,
-
TypeScript の型チェックを実行するために、tsconfig.json に以下の設定を追加してください。
{
"compilerOptions": {
"sourceMap": true
}
}
1.5. テスティングフレームワークのセットアップ
テストを自動化することで、開発中に問題を早期に発見し、品質を向上させることができます。以下の手順でテスティングフレームワークをセットアップしてください。
1.5.1. Jest とは
Jest は、JavaScript のテスティングフレームワークです。以下の手順で Jest をセットアップしてください。
1.5.2. Jest のインストール
-
以下のコマンドを実行して、Jest をインストールしてください。
npm install --save-dev jest
1.5.3. Jest の設定
-
package.json ファイルを開き、以下の内容を追加してください。
{
"scripts": {
"test": "jest"
}
}
-
ES Modules を私用している場合はテストが失敗するので以下の設定を package.json に追加する
...
"jest": {
"moduleFileExtensions": [
"js",
"ts"
],
"testMatch": [
"**/**/*.test.js",
"**/**/*.test.ts"
]
}
}
1.5.4. TypeScript 対応
-
以下のコマンドを実行して、必要なパッケージをインストールしてください。
npm install --save-dev @types/jest ts-jest
-
tsconfig.json ファイルを開き、以下の内容を追加してください。
"module": "es2020",
1.5.5. テストの作成
-
テストファイルを作成してください。
src/app.js
export function sum(a, b) {
return a + b;
}
src/app.test.js
import { sum } from './app.js';
test('adds 1 + 2 to equal 3', () => {
const result = sum(1, 2);
expect(result).toBe(3);
});
src/app.ts
export function sum(a: number, b: number): number {
return a + b;
}
src/app.test.ts
import { sum } from './app';
test('adds 1 + 2 to equal 3', () => {
const result = sum(1, 2);
expect(result).toBe(3);
});
1.5.6. テストの実行
-
以下のコマンドを実行して、テストを実行してください。
npm test
-
テストカバレッジを計測することで、テストがどの程度の範囲をカバーしているかを確認することができます。
"test": "jest --coverage"
1.6. フォーマッタのセットアップ
フォーマッタを使用することで、コードのスタイルを統一し、読みやすくすることができます。以下の手順でフォーマッタをセットアップしてください。
1.6.1. Prettier とは
Prettier は、コードのフォーマットを自動化するツールです。以下の手順で Prettier をセットアップしてください。
1.6.2. パッケージのインストール
-
以下のコマンドを実行して、Prettier をインストールしてください。
npm install --save-dev prettier
1.6.3. パッケージの設定
-
.prettierrc ファイルを作成し、以下の内容を記述してください。
{
"semi": true,
"trailingComma": "all",
"singleQuote": true,
"printWidth": 80,
"tabWidth": 2
}
1.6.4. フォーマッタの実行
-
以下のコマンドを実行して、フォーマッタを実行してください。
npx prettier --write .
-
package.json ファイルを開き、以下の内容を追加してください。
{
"scripts": {
"format": "prettier --write ."
}
}
1.7. 開発ツールのセットアップ
開発ツールを使用することで、開発効率を向上させることができます。以下の手順で開発ツールをセットアップしてください。
1.7.1. パッケージのインストール
-
以下のコマンドを実行して、開発ツールをインストールしてください。
npm install --save-dev @k2works/full-stack-lab
./index.html
を以下の内容に変更します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>App</title>
</head>
<body>
<h1>アプリケーション</h1>
<div id="app"></div>
<div id="app-dev"></div>
</body>
</html>
./src/app.js
を以下の内容に変更します。
console.log('app.js: loaded');
export class App {
constructor() {
console.log('App initialized');
}
}
export function sum(a, b) {
return a + b;
}
./src/index.js
をルート直下に移動して以下の内容変更します。
import { App } from './src/app.js';
const app = new App();
import { render } from '@k2works/full-stack-lab';
const contents = `
## 機能名
## 仕様
## TODOリスト
`;
const uml = `
abstract class AbstractList
abstract AbstractCollection
interface List
interface Collection
List <|-- AbstractList
Collection <|-- AbstractCollection
Collection <|- List
AbstractCollection <|- AbstractList
AbstractList <|-- ArrayList
class ArrayList {
Object[] elementData
size()
}
enum TimeUnit {
DAYS
HOURS
MINUTES
}
annotation SuppressWarnings
`;
const erd = `
' hide the spot
hide circle
' avoid problems with angled crows feet
skinparam linetype ortho
entity "Entity01" as e01 {
*e1_id : number <<generated>>
--
*name : text
description : text
}
entity "Entity02" as e02 {
*e2_id : number <<generated>>
--
*e1_id : number <<FK>>
other_details : text
}
entity "Entity03" as e03 {
*e3_id : number <<generated>>
--
e1_id : number <<FK>>
other_details : text
}
e01 ||..o{ e02
e01 |o..o{ e03
`;
render({ contents, uml, erd });
-
TypScript も同様に変更してください。
-
最後に不要なファイルを削除します。
1.7.2. 開発ツールの設定
-
webpack.config.js を以下の内容に変更します。
...
entry: './index.js',
...
1.7.3. 開発ツールの実行
-
以下のコマンドを実行して、開発ツールを実行してください。
npm start