Node.jsでXMLHttpRequestを使う

Node.jsでXMLHttpRequestを使おうとしたら以下のエラーがでて怒られた。

ReferenceError: XMLHttpRequest is not defined

XMLHttpRequestは、Webブラウザーの組み込みオブジェクトで、Node.jsには含まれていないみたい

つらい

Node.jsで使いたければ個別にインストールが必要

なので

① yarn(or npm) で install

yarn add xmlhttprequest

②コードでimport して使う

import { XMLHttpRequest } from 'xmlhttprequest'

終わり

Babel 設定ファイル #2

Babel 設定ファイル

Babelの設定ファイルとは、BabelでどのようにJavaScriptを変換するかを定義したもの。

設定ファイルの作成

Babelの設定ファイルはプロジェクトのルート(package.jsonがある場所)に

babel.config.jsonというファイルを作成するだけで、このファイルが設定ファイルとして扱われる。

設定ファイルの種類や、作成方法はいくつかあるが

Babelがとりあえずオススメしてるのはbabel.config.jsonを作成すること。

(※設定ファイルの拡張子は.json以外にも、.js.cjs.mjsが使用可能)

設定ファイルの中身

babel.config.json

{
  "presets": [...],
  "plugins": [...]
}

babel.config.js

module.exports = function (api) {
  api.cache(true);

  const presets = [ ... ];
  const plugins = [ ... ];

  return {
    presets,
    plugins
  };
}

設定ファイルには基本的に使用するpresetspluginsなどを定義するが

.jsの場合はプログラムが書けるので、設定内容を動的に作る事もできる。

その他の設定については公式ドキュメントを参照

設定ファイルの種類

Babelの設定ファイルは大きく以下の2種類がある

  • プロジェクト全体設定

    babel.config.json

  • ファイル関連設定

    • .babelrc.json
    • package.jsonbabelというキーを指定して定義

プロジェクト全体設定

プロジェクトルートに置かれたbabel.config.jsonはプロジェクト全体の設定として扱われる。

また拡張子を変えてbabel.config.jsonbabel.config.jsの2つを作成すると

コンパイル時に

Error: Multiple configuration files found. Please remove one:

と怒られる。

プロジェクト全体設定は1つしか設定できないようだ。

ファイル関連設定

ファイル関連設定はプロジェクトの一部にだけ適用する事ができる設定ファイルで

.babelrc.jsonという名前で作成すればよい。

例として

root
 ┣ src
 ┃ ┣ index.js
 ┃ ┗ hoge
 ┃   ┣ hoge.js
 ┃   ┗ .babelrc.json
 ┣ package.json
 ┗ babel.config.json

このような構成だった場合、プロジェクト全体にはbabel.config.jsonで定義した設定が適用されるが

root/src/hogeに含まれるファイルは.babelrc.jsonに定義された設定が追加で適用される。

適用された設定を表示する

ファイルパスを指定して、そのファイルに適用されたBabelの設定を表示する事ができる。

babelでコンパイルを行う前に環境変数BABEL_SHOW_CONFIG_FORに対して

設定を表示したいファイルのパスを設定する。

例えば、src/index.jsに適用された設定を表示する場合

$env:BABEL_SHOW_CONFIG_FOR = "./src/index.js";
npx babel src --out-dir lib

↓結果

Babel configs on "D:\Users\owner\Desktop\work\babel-sample\src\index.js" (ascending priority):
config D:\Users\owner\Desktop\work\babel-sample\babel.config.json
{
  "plugins": [
    "@babel/plugin-proposal-class-properties"
  ],
  "presets": [
    [
      "@babel/env",
      {
        "targets": {
          "edge": "17",
          "firefox": "60",
          "chrome": "67",
          "safari": "11.1"
        },
        "useBuiltIns": "entry",
        "corejs": "3.6.4"
      }
    ]
  ]
}

programmatic options from @babel/cli
{
  "sourceFileName": "../src/index.js",
  "caller": {
    "name": "@babel/cli"
  },
  "filename": "src\\index.js"
}
Successfully compiled 1 file with Babel (441ms).

次に、./src/hoge.hoge.jsに適用された内容を表示する場合

$env:BABEL_SHOW_CONFIG_FOR = "./src/hoge/hoge.js";
npx babel src --out-dir lib

↓(結果)

Babel configs on "D:\Users\owner\Desktop\work\babel-sample\src\hoge\hoge.js" (ascending priority):
config D:\Users\owner\Desktop\work\babel-sample\babel.config.json
{
  "plugins": [
    "@babel/plugin-proposal-class-properties"
  ],
  "presets": [
    [
      "@babel/env",
      {
        "targets": {
          "edge": "17",
          "firefox": "60",
          "chrome": "67",
          "safari": "11.1"
        },
        "useBuiltIns": "entry",
        "corejs": "3.6.4"
      }
    ]
  ]
}

config D:\Users\owner\Desktop\work\babel-sample\src\hoge\.babelrc.json
{
  "plugins": [
    "@babel/plugin-proposal-class-properties"
  ],
  "presets": [
    [
      "@babel/env",
      {
        "targets": {
          "edge": "17",
          "firefox": "60",
          "chrome": "67",
          "safari": "11.1"
        },
        "useBuiltIns": "entry",
        "corejs": "3.6.4"
      }
    ]
  ]
}

programmatic options from @babel/cli
{
  "sourceFileName": "../../src/hoge/hoge.js",
  "caller": {
    "name": "@babel/cli"
  },
  "filename": "src\\hoge\\hoge.js"
}

./src/index.jsにはbabcl.config.jsonの内容しか表示されないが

./src/hoge/hoge.jsには、.babelrc.jsonの内容も表示される。

Babelは複数の設定ファイルがあった場合は、元の項目を上書き(マージ)するらしい。

babel.config.jsonの内容が、.babelrc.jsonによって上書きされる。

Babel 基本 #1

Babelとは何か

BabelはJavaScriptコンパイラ

新しい構文で書かれたJavaScriptを古いブラウザでも動作するように変換するのがBabel。

Babelの主な仕事

  • JavaScriptコードを変換する

  • ポリフィル(最近の機能をサポートしていない古いブラウザでも、新しい機能を使えるようにする)機能

  • ソースコード変換

使い方

ES2015+の構文で書かれたJavaScriptを現在のブラウザで動作するコードにコンパイルする例

  1. パッケージのインストール
yarn add -D @babel/core @babel/cli @babel/preset-env
yarn add @babel/polyfill
  1. babel.config.jsonの作成

    プロジェクトのルートディレクトリ直下に作成する。

    設定の内容はサンプル

{
  "presets": [
    [
      "@babel/env",
      {
        "targets": {
          "edge": "17",
          "firefox": "60",
          "chrome": "67",
          "safari": "11.1"
        },
        "useBuiltIns": "usage",
        "corejs": "3.6.4"
      }
    ]
  ]
}
  1. srcディレクトリのコードをコンパイルして、libディレクトリに出力する例
npx babel src --out-dir lib

Core Library

Babelのコア機能は@babel/coreに含まれている。

実際に@babel/coreを使ってコンパイルするコードを書くこともできる

// Babelのコア機能を読み込む
const babel = require('@babel/core');

// JSコードとコンパイルオプションを用意
const code = `
console.log("Hello, world");
`;

const options = {};

// コンパイル!
const result = babel.transform(code, options);

// 結果を表示
console.log(result);

// 表示結果
// {
//   metadata: {},
//   options: {
//     cloneInputAst: true,
//     babelrc: false,
//     configFile: false,
//     passPerPreset: false,
//     envName: 'development',
//     cwd: 'D:\\Users\\owner\\Desktop\\work\\babel-sample',
//     root: 'D:\\Users\\owner\\Desktop\\work\\babel-sample',
//     plugins: [
//       [Plugin], [Plugin], [Plugin],
//       [Plugin], [Plugin], [Plugin],
//       [Plugin], [Plugin], [Plugin],
//       [Plugin], [Plugin], [Plugin],
//       [Plugin], [Plugin], [Plugin],
//       [Plugin], [Plugin], [Plugin],
//       [Plugin]
//     ],
//     presets: [],
//     parserOpts: {
//       sourceType: 'module',
//       sourceFileName: undefined,
//       plugins: [Array]
//     },
//     generatorOpts: {
//       filename: undefined,
//       auxiliaryCommentBefore: undefined,
//       auxiliaryCommentAfter: undefined,
//       retainLines: undefined,
//       comments: true,
//       shouldPrintComment: undefined,
//       compact: 'auto',
//       minified: undefined,
//       sourceMaps: false,
//       sourceRoot: undefined,
//       sourceFileName: 'unknown'
//     }
//   },
//   ast: null,
//   code: '"use strict";\n\nconsole.log("Hello, world");',
//   map: null,
//   sourceType: 'script'
// }

CLI Tool

@babel/cliはターミナルからbabelを使えるようにするツール。

以下のようにコマンドからbabelのコンパイルが行える。

./node_modules/.bin/babel src --out-dir lib
# or
npx babel src --out-dir lib

これはsrcディレクトリにある全てのJavaScriptファイルを解析し、指定した変換を適用して、各ファイルをlibディレクトリに出力するコマンド。

(※このコマンドでは変換方法を指示してないので、出力コードは入力コードと同じになる)

どのような変換を行うかは、オプションで指定する事ができる。

変換(Plugins & Presets)

コードの変換機能はプラグインとして提供される。

アロー関数で書かれた処理を、functionに変換する指示をする例

  1. pluginを導入する
yarn add -D @babel/plugin-transform-arrow-functions
  1. コマンドのpluginsオプションで①で導入したpluginを指定する
npx babel src --out-dir lib --plugins=@babel/plugin-transform-arrow-functions
// 変換前
const hello = () => console.log("Hello World");

// 変換後
const hello = function hello() {
  return console.log("Hello World");
};

このようにして、Babelに変換方法を指示する事もできるが、1つ1つプラグインを指定するのではなく

プラグインがセットになった「プリセット」を指定する事もできる。

(プラグインと同様に独自のプリセットを作成することもできる。)

プリセットの使用例として、envプリセットを使う例

  1. プリセットの導入
yarn add -D @babel/preset-env
  1. コマンドでプリセットを指定する
npx babel src --out-dir lib --presets=@babel/env

オプションはコマンドで指定するのではなく、設定ファイルを用意する事でも行える。

設定ファイル

設定ファイルはプロジェクトルート直下にbabel.config.jsonという名前で作成する。

{
"presets": [
  [
  "@babel/env",
    {
      "targets": {
        "edge": "17",
        "firefox": "60",
        "chrome": "67",
        "safari": "11.1"
        }
      }
    ]
  ]
}

上記の設定では、プリセットにenvを使用し、ターゲットに指定したブラウザで動作しないコードの変換のみを行うという設定。

Polyfill

※Babel 7.4からpolyfillは非推奨となったそう、以下の記事に詳しく書かれている。 aloerina01.github.io

なので、以下の文章読むより、上記の記事を見たほうがよい。

ポリフィルは、PromiseやWeakMapなどの新しいビルトインの機能を使えるようにする仕組みです。

  1. Polyfillの導入
yarn add @babel/polyfill

ポリフィルは-Dオプションを指定せずにインストールする。

ポリフィルは実際に動作する上で必要なプログラム群のため。

設定ファイルのuseBuiltInsについて

{
  "presets": [
    [
      "@babel/env",
      {
        "targets": {
          "edge": "17",
          "firefox": "60",
          "chrome": "67",
          "safari": "11.1"
        },
        "useBuiltIns": "usage"
      }
    ]
  ]
}

useBuiltIns: "usage"を指定することで、Babelは指定した環境で足りない機能がないかどうかを、全てのコードを検査し、必要なポリフィルのみを読み込みます。

例として

Promise.resolve().finally();

このコードは以下のようになる。

require("core-js/modules/es.promise.finally");

Promise.resolve().finally();

これはEdge17には`Promise.resolve().finally()がないため。

設定ファイルのuseBuiltIns: "usage"を指定していることで、足りない機能だけが読み込まれます。

お気に入りのNPM

お気に入りのNPMパッケージメモ

json-server - npm

jsonファイルを用意するだけで簡単に疑似REST APIサーバーを作成できる。 開発時に適当なREST APIが欲しい時に使う。

dat.gui - npm

Three.jsのサンプルページの右上などにあるUnityのInspector的なUIを実装できるツール

codepen.io

verdaccio - npm

ローカルのnpm registryを構築できるライブラリ。 社内だけで使用する独自のnpmパッケージを作成して イントラに公開するという用途では使えそう。

Create React App はじめに

Create React App はじめに

Create React Appを使えば

webpackやbabelなどのツールをインストールしたり設定したりする必要がなく

Reactをサクッと始める環境が整えられる。

アプリケーションの作成

Nodeのバージョン8.10以上が必要らしいので、予めインストールしておく。

Create React Appを使ってアプリケーションを作成するには以下の3つの方法がある。

ちなみに

以前に npm install -g create-react-app を使ってグローバルに create-react-app をインストールしたことがある場合は、 npx が常に最新バージョンを使用するようにするために、 npm uninstall -g create-react-app を使ってパッケージをアンインストールすることをお勧めします。

とのこと

npx

npx create-react-app my-app

(npx は npm 5.2+ 以降に付属している)

npm

npm init react-app my-app

(npm 6+では `npm init が利用可能)

Yarn

yarn create react-app my-app

(yarn createはyarn 0.25+で利用可能)

上記のいずれかのコマンドを実行するとmy-appディレクトリが作成される。

テンプレートの選択

上記のコマンドに--template [template-name]を追加で指定する事で

テンプレートを指定してアプリケーションを作成できる。

例えば、TypeScriptを使うプロジェクトとして作成する場合:

npx create-react-app my-app --template typescript

また Create React App はパッケージマネージャーにYarnを使っているが

下記のようにオプションを指定すると npm を使うようにすることもできる

npx create-react-app my-app --use-npm

アプリケーションを作ったら

yarn start or npm start

cd my-app
yarn start
# or
npm start

作成されたmy-appに移動してyarn start or npm startをするとプロジェクトが立ち上がり

http://localhost:3000にアクセスするとCreate React Appで作成されたアプリケーションが表示される。

また、yarn testとすればテストが実行され、yarn buildとすると本番用のアプリがビルドされて出来上がります。

npm コマンドメモ

npm コマンドメモ

すぐ忘れてしまうのでnpmのコマンドをメモしておく。

バージョン

> npm -v
> npm -version

初期化

> npm init

このコマンドを実行するとプロジェクト名などを入力するモードになり、入力を追えるとpackage.jsonが作成される。

また以下のようにすればあれこれ入力せずにデフォルトの内容でpackage.jsonが作成される。

> npm init -y
# or
> npm init -yes

パッケージのインストール

package.jsonの内容からパッケージをインストールする

> npm install
# or
> npm i

gitからプロジェクトを落としてきて、環境を構築する際などに使う。

package.jsonにはプロジェクトで使用するパッケージの一覧が記述されていて

npm installとするだけでそれらのパッケージが一斉にインストールされる。

ローカルにインストール

> npm install パッケージ名
> npm i パッケージ名

# --saveオプション、依存するパッケージとしてインストールする(省略可)
# ※package.jsonのdependencies欄にパッケージ名が登録される。
> npm install --save パッケージ名
> npm install -save パッケージ名
> npm install -S パッケージ名

# --save-devオプション、開発時のみ使用するパッケージとしてインストールする。
# ※package.jsonのdevDependencies欄にパッケージ名が登録される。
> npm install --save-dev パッケージ名
> npm install -D パッケージ名

グローバルにインストール

npm install -g パッケージ名
npm install --global パッケージ名

パッケージのアンインストール

# ローカル
> npm uninstall パッケージ名

# グローバル
> npm uninstall -g パッケージ名

インストール済のパッケージを表示

# ローカル
> npm list

# グローバル
> npm list -g

リスト表示する階層を制限したい場合は--depthを指定すればよい。

> npm list -g --depth 0

Webpackの導入と動作確認

やること

webpackを導入しつつ、実際にwebpackを使って
複数のソースコードを1つのファイルにバンドルしてみる。

実行環境

  • node v10.10.0
  • yarn 1.22.0

最終的なディレクトリの中見

root
 ┣ node_modules
 ┣ public
 ┃ ┣ index.html
 ┃ ┗ js
 ┃   ┗ bundle.js
 ┣ src
 ┃ ┣ app.js
 ┃ ┗ modules
 ┃   ┣ hello.js
 ┃   ┗ world.js
 ┣ package.json
 ┣ webpack.config.js
 ┗ yarn.lock

1. package.jsonを作る

適当なディレクトリを作成し、そのディレクトリ内で以下のコマンドを実行する。

yarn init -y

2. webpackとwebpack-cliを入れる

yarn add -D webpack webpack-cli

3. webpackの設定ファイル(webpack.config.js)を作成する。

webpack.config.jsというファイルを作成する。

const path = require('path');

module.exports = {
  // webpackのモードを指定する(development、production、noneの3種類)
  mode: 'development',

  // エントリーポイントになるファイルを指定
  entry: './src/app.js',

  // 出力に関する設定
  output: {
    // 出力するファイル名
    filename: 'bundle.js',
    // 出力先のディレクトリパス
    path: path.resolve(__dirname, 'public/js')
  }
}

4. package.jsonにscriptsを追加

  "scripts":{
    "build":"webpack"
  },

webpackはwebpackというコマンドで実行できる。
これでwebpackでバンドルする準備は整った。

5. 適当にソースコードを追加する

root/src/modules配下にhello.jsworld.jsを作成

hello.js

export default function hello() {
  return "hello"
}

world.js

export default function world() {
  return "world";
}

6. app.js(エントリーポイント)ファイルを作成する

root/src直下にapp.jsを作成

import hello from './modules/hello';
import world from './modules/world';

const text = hello() + world();

document.body.innerText = text;

7. バンドルする

ターミナルにてyarn buildとすると、root/public/js/bundle.jsが作成される。

ここで出力されるのはwebpackによってバンドルされたファイル。
出力先やファイル名はwebpack.config.jsで指定した通りになる。

作成されたbundle.jsを適当なHTMLファイルから読み込んでブラウザで実行すると
helloworldと表示される。

8. 終わり

ひとまず「webpackを使って複数のjsファイルを1つのファイルにバンドルする」という
基本中の黄本はこれにて完了。

実際にbundleされたファイルを覗いてみると
自分が書いたコードはただの文字列として羅列されている。

本当に1つのファイルにコードを全部まとめてしまっていて
この文字列をjavascriptのeval関数で再評価する処理になっている。

またwebpackによって__webpack_require__という関数が定義されていて
この関数によってうまいこと外部ファイル読み込みの動作を実現している。