しがないエンジニアのブログ

技術的な内容をメモ代わりにつらつら

babelを使ったjavascriptの自動コンパイル

Babel

ECMAScript2015 (ES6)やECMAScript7などで書かれたソースコードを一般的なブラウザがサポートしているECMAScript5の形式に出力することができます。

つまり、新しい言語仕様を昔の仕様に落としてトランスコンパイルしてくれるコンパイラ

セットアップ

babel v6.0以降、pluginまたはpresetの指定が必要になっている
基本的には.babelrcというファイルに記述するのだが、設定が少ないため、package.jsonに合わせて記述する

"babel": {
  "presets": [
    "env"
  ]
}

envというのは、コンパイル環境を自動で決定してくれるすぐれもの

あわせて、次の2つのパッケージをインストール

npm install babel-cli
npm install babel-preset-env

コンパイラの作成

実際にコンパイルするためには、babelコマンドが必要になってくる
それをjs側で管理して実行できるようにする
ファイル名は、package.jsonのmainタグで管理されているファイル名に設定(デフォルトはindex.js

const babel  = require('babel-core')
const fs     = require('fs')

const srcFile  = 'src/test.js'
const distFile = 'dist/test.js'
const options  = {"presets": ["env"]}

const code = fs.readFileSync(srcFile, 'utf-8')
const newCode = babel.transform(code, options).code
fs.writeFileSync(distFile, newCode)

console.log('babel build finished!')

サンプルとして、ここでは
src/test.jsの内容を、
dist/test.jsコンパイルして出力するようにしている

例えば、

class Hoge {
  constructor() {
    this.x = 3;
    this.y = 2;
  }
  add() {
    return this.x + this.y;
  }
}
const exp = (x, y) => x ** y;
const hoge = new Hoge();
console.log(exp(hoge.x, hoge.y));
console.log(hoge.add());

を変換する。
$ node index.jsを実行すると、

"use strict";

var _createClass = 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, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Hoge = function () {
  function Hoge() {
    _classCallCheck(this, Hoge);

    this.x = 3;
    this.y = 2;
  }

  _createClass(Hoge, [{
    key: "add",
    value: function add() {
      return this.x + this.y;
    }
  }]);

  return Hoge;
}();

var exp = function exp(x, y) {
  return Math.pow(x, y);
};
var hoge = new Hoge();
console.log(exp(hoge.x, hoge.y));
console.log(hoge.add());

になる。ちゃんと実行もできる

自動コンパイル環境の構築

今のままだと、変更・保存して毎回node index.jsを叩かなくてはいけない
そのため、ファイルを変更したら自動でコンパイルしてくれるようにする
gulpやgruntは使わない

まず、ファイルの変更を監視するwatchというパッケージがあるので、それをインストールする

npm install watch

次に、package.jsonのscriptを変更する

"scripts": {
  "start": "watch 'npm run build' src/",
  "build": "node index.js"
}

これは、src/下のファイルが変更されたら、npm run buildを実行するということ
そして、buildには、先程も実行していたnode index.jsを記述している

これで、

$ npm start

を実行するだけ
あとは、変更を加えるたびに自動でコンパイルしてくれるようになる


参考サイト

Node.jsとかnpmについての基礎的な部分

Node.jsとは

Node.jsとは、サーバサイド用のjavascript

シングルスレッドとか、ノンブロッキングI/Oとか、細かいところは省く(というかそこまで理解してない)

じゃあクライアントサイド用のjavascriptは?といえば、それが今まで使ってきていたjsなのだろう(多分)
サーバサイドで使えるようになったからそういう風に言われているのでは

npmとは

Node Package Managerの略
Node.jsのパッケージ管理ツール

gulpとかbrowserifyとか色々ある

Node.jsの機能の利用は、基本的にnpmを通して使うことが多い

npmの使い方

  • $ npm init
      package.jsonを作成    

       ※ package.jsonとは
        そのディレクトリ内の環境についての設定ファイル
        プロジェクト名や、実行可能コマンド、依存パッケージなどの情報が入っている    

  • $ npm install
      package.jsonが存在する場合、その構成に従ったパッケージのインストールを行う

  • $ npm install -g <package_name>
      グローバル環境にパッケージをインストール
      インストールしたパッケージ(コマンド)を、どこからでも利用可能になる
      ※ よほど汎用的なものでない限り非推奨
      僕がnpm installに-gをつけないわけ

  • $ npm install --save/--save-dev/--save-optional <package_name>
      ローカル(現在のパスの下)にパッケージをインストール
      node_modulesというフォルダが作成される
      そしてpackage.jsonにパッケージ情報が追加される
      一緒にpackage-lock.jsonも追加される   

      ※ package-lock.jsonとは
       node_modulesやpackage.jsonが変更されたときに自動生成される
       パッケージのバージョンログなどが含まれている
       開発者間のパッケージバージョンの同一性を担保する
       npm5から導入された package-lock.jsonについて - kakts-log   

  引数によって、package.jsonの以下3種類のどこかに割り当てられる
   ・ dependencies
   ・ devDependencies
   ・ optinonalDependencies
  なにも書かない場合はdependencies
  勉強メモ/npmの使い方(node.js=v0.11.16, npm=2.3.0, 2015-03時点)

   ・ dependencies
     他の人が共有する際にインストールされる場所
     npm installでdependencies下のパッケージがインストールされる
   ・ devDependencies
     開発者専用のパッケージ群
   ・ optinonalDependencies
     npm installでインストールされるが、失敗しても無視される(らしい)

  インストールしたものはjsファイルで利用することができるようになる
  例えば、npm install hogeとした場合、

const hoge = require('hoge')

  として利用できる

  • $npm uninstall/rm -g <package_name>
      グローバルのパッケージのアンインストール

  • $ npm uninstall/rm <package_name>
      ローカルのパッケージのアンインストール

  • $ npm update -g <package_name>
      グローバルのパッケージのアップデート

  • $ npm update <package_name>
      ローカルのパッケージのアップデート

package.jsonのscript設定

package.jsonには、scriptタグがある
ここに色々追加することで、コマンド上でパッケージを実行することが可能となる
デフォルトでは、以下のようになっている

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1"
}

このとき、npm run test --silentを実行することで

Error: no test specified

が表示される(--silentをつけたのはエラーログを出さないため)
npm run testするときはnpmログを切ったほうがいい

このscriptタグ内を設定して自由にコマンドを追加できる
また、startコマンドは特殊なコマンドとして登録されており、npm startで実行できるようになっている

package.jsonの詳しい中身について:package.jsonの中身を理解する


参考サイト

はてなブログのサイドバーを横に表示する part2

前回の記事で、うまくいかなかったので、その2

gridを使った書き方

#content-inner {
  display: grid;
  grid-template-columns: 800px 1fr;
}

でok

ただ、IE(とEdge)に対応させるためには以下のように修正しなければならなかった

#content-inner {
  display: grid;
  display: -ms-grid;
  grid-template-columns: 800px 1fr;
  -ms-grid-columns: 800px 1fr;
}
#wrapper {
  -ms-grid-column: 1;
}
#box2 {
  -ms-grid-column: 2;
}

悲しいなあ


参考サイト