Redux チュートリアルで必要になったES6記法 immutableに配列やオブジェクトを変更する

// オブジェクトを引数として受けて、それを展開する書き方
// Propertyがvalueとnameのものを展開して、valueとnameで受ける
const testFunction = ({value,name}) => (value + name)

const testObject = {
	value: "a",
	name: "b",
}

console.log(testFunction(testObject));
console.log("tesf")

//リストに新たな項目を追加する方法
const list =[0,1,2,3];

const addList = (list) => {
	return [...list,"add"];
}

console.log(addList(list));
// slice(n)はn番目を含んでそれ以降の配列を返す
var newList = list.slice(2)
//console.log(newList);

// slice(0,n)は0から、n番目を含まない、その範囲の配列を返す
var newList = list.slice(0,2)
//console.log(newList);

// slice(m,n)はmから、n番目を含まない、その範囲の配列を返す
var newList = list.slice(1,2)
//console.log(newList);
// index 番目(0から始まるやつで) の配列だけを削除するFn
const removeCounter = (list, index) => {
  // Old way:
  //return list
  //  .slice(0, index)
  //  .concat(list.slice(index + 1));

  // ES6 way:
  return [
    ...list.slice(0, index),
    ...list.slice(index + 1)
  ];
};

console.log(removeCounter(list,1))

See the Pen arrow function object by nakanishi (@nakanishi) on CodePen.

//オブジェクトにオブジェクトをマージする場合の書き方
const addObject = (lastObject, addOne) => {
	//からのオブジェクト{}に、どんどん上書きしていく
	return Object.assign({}, lastObject, addOne)
}

const lastObject = {
	name: "name",
	value: "value"
}

const add1 = {
	name: "name2",
	value: "value2"
}

const add2 = {
	newProp: "newProp"
}

//同じプロパティがあれば、上書きされる
var show = addObject(lastObject, add1);
//console.log(show);

//同じプロパティがなければ、新たにプロパティが作られる
var show = addObject(lastObject, add2);
console.log(show);

See the Pen JyjypY by nakanishi (@nakanishi) on CodePen.

function returnInt(element) {
  return parseInt(element, 10);
}

['1', '2', '3'].map(returnInt); // [1, 2, 3]
// Actual result is an array of numbers (as expected)

// Same as above, but using the concise arrow function syntax
['1', '2', '3'].map( str => parseInt(str) );

npm script でタスク処理する開発環境を作った npm スクリプトでタスク処理をする環境を作りました。akabebeko さんのものを元に修正しました。.sass, Babel, Browserify, 開発用サーバーを立てる、デプロイ用のイメージを作成する

アカベコさんの記事、リポジトリを元に、自分にあった環境を作成しました。

npm-scripts で Web フロントエンド開発を管理する

https://bitbucket.org/Y_NAKANISHI/web-start-npm-script

変更点は以下

  • stylus ではなく Sass を使用する。そのための npm は node-sass を用いる。
  • Sass の import のためのディレクトリも最初から用意。
  • assets以下に、jsだけしか入っていないフォルダ (例えば自分以外の人が以前のプロジェクトで書いたjsを引き継ぐとか、npm にないライブラリを、bower も使わないで管理したいとかそういうフォルダ) を無理くりコピーする。本当は cpx でバチコーンと出来るはずだとは思うんですが、書き方がわからなかった!!
  • 自分は絶対使うので最初から jQuery を仕込む。

もう少し改善したい。

設定 babel browserify watchify babelify presets es2015

ES6 でクラス構文、及びモジュールを扱うための import 構文を書き、ブラウザで使用可能な ES6 に Babel で変換し、さらにモジュールの依存関係を Browserify で解消する。という一連の作業を npm scripts で実行する方法について書いています。

Babel, Browserify, Watchify, Babelify の関係

  • Babel は ES6(ES2015)→ES5 に変換するツール。(恐らく Babelify も内部では Babelを使用している。) 自分は class 構文、及び import, export 構文を書くために必要。
  • Browserify はモジュール機能を使うために必要。(require , export 構文を用いて読み込む JS ファイルの依存関係を解決するシステム。ES6 のimport, export 構文は ES6 に変換されると、require, export 構文になる。) transform オプション(-t)に babelify を指定することで(-t babelify) まず bable で変換した後にモジュールの処理がされる。
  • Babelify は Browserify のオプションとして指定することで(-t babelify)Babel で変換してくれる。(どのようなルールで変換するか、プリセットの設定が必須)
  • Watchify は Browserify の watch 版。つまり、ファイル更新がされたときだけ実行される。さらに、差分だけをビルドするので、ファイル更新を Browserify でウォッチするよりも、早い。 またこれは Browserify と同じ作者が作成しており、ウォッチ用途にはこちらが推薦されている。
  • Babel は実行時に presets オプションが必須。同様に Babelify にも presets が必須。.babelcr ファイルもしくは package.json に記録することが可能。
  • Browserify, Watchify は –transform (-t)オプションで Babelify を指定することで Babel の処理を間に入れることが出来る。Babel と同様に Package.json で指定可能。

npm scripts でタスクを実行する

npm scripts (package.json 内の script フィールドに記述する) でタスクを実行する。ここには CLI (コマンドラインインターフェイス、Mac ならターミナル等) で npm を実行するコマンドと同じものを基本的に書けば良い。(基本的に、といったのは、ここで実行するコマンドはシェルに依存するので、mac や win など OS に異なる場合には、コマンドも異なるため。その差を埋める方法については後述)

Grunt や Gulp といったタスクランナーを使わずに npm scripts で コマンドラインを実行する利点は、第一にタスクランナー専用のプラグインよりも、CLI から実行可能な npm の方が多く、第二にそれぞれのタスクランナー専用の設定ファイルを書く必要がないという点がある。(参照:原文翻訳) (ただし Grunt や Gulp で運営されるプロジェクトも多くあるため、これらのタスクランナーの知識は不必要ということでははない。)

実感として、初歩的なビルド、コンパイルであれば CLI での実行は簡単で、公式ドキュメントを参照すれば十分に理解できる。ただし、複雑なタスクの実行するには npm scripts への理解が必要になる。それでも公式マニュアルに情報が多いため、対応が楽だと感じている。

npm 及び package.json について

npm 及び package.json については次の記事を参照。(npm とは何か / Package と module の違い)

次のコードは package.json の中に書かれるもののサンプルで、”scripts” 内に npm scripts を書く。ここには基本的に CLI で実行するコードを書く。package.json は json なので次のルールを守って書く。

  • {“プロパティ1″:”値1″,”プロパティ2″:”値2”} と JS オブジェクトに似た全体像になる
  • {“プロパティ”:{“子プロティ1″:”値1″,”子プロティ2″:”値2”}} と階層化する際には、値にさらにオブジェクトを持つ。
  • 単に値が複数ある場合には配列を使う。{“プロパティ1”:[“値1″,”値2”]}
  • 全ての値は””で囲う。”は使用できない。そのため””内で””を使用するためには「\”」とエスケープする。
  • &を使うと、並列に実行される
  • && を使うと、実行後に実行される
  • npm scripts 内で、さらに run npm コマンド名を実行することも出来る。
{
  "name": "browserify-test",
  "version": "1.0.0",
  "main": "main.js",
  "dependencies": {
    "jquery": "^3.1.1"
  },
  "devDependencies": {
    "babel-preset-es2015": "^6.22.0",
    "browserify": "^14.1.0",
    "gulp": "^3.9.1",
    "node-sass": "^4.5.0",
    "vinyl-source-stream": "^1.1.0",
    "watchify": "^3.9.0"
  },
  "scripts": {
    "start": "npm run watch:script & npm run watch:sass",
    "watch:script": "watchify main.js -v -t babelify -d -o app.js",
    "build": "browserify main.js  -t [ babelify --presets [ es2015 ] ] -o app.js",
    "watch:sass": "node-sass --include-path src/sass --watch src/sass/screen.sass src/css/screen.css"
  }
}

実際の npm scripts

オプションを npm scripts 内に記述する

次のような npm scripts がある場合、コマンドラインで npm run build  や npm run watch:script と実行する。

-t [ babelify –presets [ es2015 ] ] はオプションで、babelify を使って ES6→Es5 に変換し、そのさいのプリセットは es2015 で実行することを指定している。(詳細は後述)

  • -0 –output の省略形。出力先のファイルの指定をするオプション
  • -v コンパイルした際に通知が入る。これを指定しないと、コンパイルしても何も教えてくれない。
  • -d –debug の省略形。ソースマップを出力する。
 "scripts": {
    "build": "browserify main.js  -t [ babelify --presets [ es2015 ] ] -o app.js",
    "watch:script": "watchify main.js -v -t [ babelify --presets [ es2015 ] ] -d -o app.js"
  }

オプションを Package.json 内に記述する

オプションはPackage.json 内に記述することも出来る。

まず Browserify の設定は Package.json に以下のように記述できることが Browserify ドキュメントに書いてある。つまり”browserify”: {“transform”: [“babelify”]}とすれば Babeliy を使うことを指定できる。ではその際のプリセットはどうすればいいか?

"scripts": {
    "watch:script": "watchify main.js -v -t babelify -d -o app.js",
    "build": "browserify main.js -o app.js"
  },
  "browserify": {
    "transform": [
      [
        "babelify",
        {
          "presets": [
            "es2015"
          ]
        }
      ]
    ]
  }

Babel の設定ファイル .babelrc

Babel の設定ファイルは .babelrc というファイルで、自動的に探して参照してくれる。しかし、同じ内容を package.json の中に書くことが出来るとマニュアルに書いてある。”babel”という項目の中に、設定を書く。

Babelify が使うプリセットの指定

Babelify が使うプリセットの指定は、.babelrc ファイルに書くように Browserify と Babelify の組み合わせで使うためのガイドラインに書いてある。さらに.babelrc は package.jsonの中に書くことが出来るわけだから、package.json 内に{“babel”:{“preset”:[ここにプリセットを書く]}とすればよい。

結果として次の様に書くことが出来る。browserify には transform に指定に babelify を指定し、babel のプリセットに関しては、babel 内に書けば良い。

  "scripts": {
    "watch:script": "watchify main.js -v -d -o app.js",
    "build": "browserify main.js -o app.js"
  },
  "babel": {
    "presets": [
      "es2015"
    ]
  },
  "browserify": {
    "transform": [
      "babelify"
    ]
  }

watchify の設定ファイル

watchify のオプションは browserify と同じだと書いてある。つまり結果として .babelrc を参照するが、なければ package.json 内を参照する。参照先はbrowserify と同じなのだと思われる。

highlighter_668843

npm scripts の完成形参照先

最終的には次のような npm scripts になると思われる。build:js と watch: js を御覧ください。私は現時点では「| exorcist」等理解できないものがあるので、これについても調べておって記事を書く。

npm-scripts で Web フロントエンド開発を管理する

次回

さしあたって JavaScript 周りのコンパイル、ビルドはできるようになったので、次はブラウザシンク、ロード、また CSS 関係のコンパイルを調べる。

ES5, CoffeeScript, ES6の記法の違い

ES5, CoffeeScript, ES6の記法の違いが混乱するのでまとめた。

ES5 CoffeeScript ES6
参考資料 詳しい
標準ブラウザで 読める 読めない (要トランスコンパイル) 読めないものも多くある (実務レベルでは要トランスコンパイル/主としてBabelを用いる)
 記法デモ Class構文 JQuery.cssの書き方 Class構文 ES5と6の違い
セミコロン いる いらない いる
function(){内容} function(){内容} ()=> 改行インデント 内容 ()=>{内容}
 function(引数){内容}   function(引数){内容} (引数)=> 改行インデント  内容  (引数)=>{内容}
関数の実行 call(); call()

引数がないときは必ず()が必要

call();
関数の実行(引数あり) call(“start”); call “start”

引数があるときは()を省略可能

call(“start”);

ES6のクラス構文

See the Pen mOPoaG by nakanishi (@nakanishi) on CodePen.

class クラス名/冒頭は大文字  { 内容 }

内容にはコンストラクタとメンバ変数とメソッドを書く。

  • constructor(引数1,引数2) { this.引数1; this.引数2; this.call();等々}
  • メソッドはclassの中、constructorの外に書く call(){}

クラスを使うときはnew クラス名()、もしくはvar 変数名 = new クラス名()

new クラス名()をすると、コンストラクタに書かれた内容が実行される。変数名に代入すると、オブジェクトが変数に入る。

機能単位でクラスを作って、newをして実行するのが良い

最終的には機能毎にファイルを分けて、クラスを作成し、export/importをして、必要な時にnewで呼び出すのがよい。

CodePenでES6以上をBabelでコンパイルして使う

ES6とBabel

ES6ではclass構文が使えるようになり、素直なオブジェクト指向プログラミングが可能になったが、ES6は現状サポートしていないブラウザもある。そのためES6で書いたスクリプトはBabelを使ってES5にトランスコンパイルして使用する。

CodePenとBabel

CodePenではBabelをプリプロセッサーとして用いることができ、これによってES6記法のJSをES5記法に変換することができる。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-11-13-14-31-37

ES6のfunction記法抜粋

ES6はarrow functionが使える。これとjQueryを組み合わせた記法を以下に示す。

特に、arrow functionとjQueryのhoverメソッドを用いる場合にthisの扱いに注意することがポイントである。

See the Pen NbNaXY by nakanishi (@nakanishi) on CodePen.

CoffeeScriptとの違い

CofeeScriptの開発はほぼ停止しているらしく、かつ一番必要とされていたクラス構文がES6で実装されたことから、基本的にはES6を中心に書いていけばよいものと思われる。

  • {}も()も;も基本的に必要で、通常のJSと同じ。
  • インデントは内容には関係しない (CoffeeScriptはインデントによって内容が変わる)
  • import,export,require関係は微妙に異なるようなので注意
  • クラス構文が使えるのはどちらも共通しているが、書き方が少し異なるようだ