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 関係のコンパイルを調べる。

Browserify, WebPack あたりの学習

JavaScriptのモジュール管理(CommonJSとかAMDとかBrowserifyとかwebpack)

JS以外のプログラミング言語で一般的に使われている規格・仕組みがJSにはないので、それを実装するために生まれたのがCommonJS(前身はServerJSという名前でサーバーサイドで動くJSのAPIを標準化するのが目的だった。Node.jsなどにもつながっていく) そのなかでモジュールを扱う方法が今回のテーマ。

元々 CommonJS AMD = Asynchronous Module Definition Webpack
ブラウザでの実装のため Browserify RequireJS
方式 そのまま実行するのではなく、ビルドしておく 実行時に非同期でロードして、依存関係を解消する モジュールをサポートする点は他の2つと同じ。加えてCSSや読み込む画像ファイルなども含めて、単一のファイルに書き出してくれる。ばべr

選択肢は Browserify を gulp に仕込んで使うか、Webpack を使うか。まずは歴史の古い Browserify から学習する。

Browserify

Node モジュール。そのため npm で管理する。まずは npm でインストール。

npm install -g browserify

以下のコマンドでビルド

browserify 元のファイル > 出力先のファイル

Transform

例えば ES6 をbabelを使って変換した後に、Browserify でビルドしてくれる機能。

リスト

https://github.com/substack/node-browserify/wiki/list-of-transforms

Babelify

Browserify で Babel を使って transform するための npm ライブラリ。

https://github.com/babel/babelify

インストール

これをするまえに npm init しておく

$ npm install --save-dev babelify

コマンドラインで実行

  • -o output 先
  • -t transform の設定
  • babelify を使って、babelify の preset の es2015 と react でtransform する
  $ browserify script.js -o bundle.js -t [ babelify --presets [ es2015 react ] ] --debug
 $ browserify main.js -o app.js -t babelify

これだけだとimport exportができない。babelify のプリセットを入れる。

npm install –save-dev babel-preset-es2015

でオプションを入れて実行

$ browserify main.js -o app.js -t [ babelify --presets [ es2015 ] ] --debug

次のようなファイルをエクスポート・インポートしている

//module1.js
export class Module1{
    constructor() {
        //自身のメソッドを実行
        this.callStart();
    }

    //メソッド
    callStart() {
        alert("heaeaaaaa");
    }
}



//main.js
"use strict";
import { Module1 } from './module1.js';
new Module1();

ここまではできた

npm にあるライブラリをブラウザで使う

npm install jquery --save

使うところで次のコードを書く

import $ from 'jquery';
もしくは以下のコード
import jquery from 'jquery';
window.jQuery = jquery;
window.$ = jquery;

import できていないと思っていたが…

普通にできており、問題は単純にready前に実行していたから。以下のように書いて準備ができてから実行すること。

$(function(){
    // 実行する処理
    new Module1();
    $(".target").html("ffsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfs");
    let jQueryValue = $(".target").html();
    console.log(jQueryValue);
});

Gulpで実行する

まずはインストール

$ npm install -g gulp //全く使ったこと無いときだけこれを
$ npm install --save-dev gulp

タスクを書くための gulpfile.js を作成、これはルートに置けばいいのだろうか…→さしあたってOK

//まずはnpmをインポートする
const gulp = require('gulp');

//タスクを登録'hello'という名前
gulp.task('hello', function() {
    console.log('Hello gulp!');
});

//デフォルトで実行されるタスクに'hello'タスクを登録
//gulp で実行すると使える
gulp.task('default', ['hello']);

色々入れる

Browserifyが出力する形式をgulpで扱うためのvinyl(ビニール)という形式に変換するために以下のモジュールを入れる。

$ npm install vinyl-source-stream –save-dev

//まずはnpmをインポートする
const gulp = require('gulp');
const browserify = require("browserify");
const babelify = require("babelify");
const source = require("vinyl-source-stream"); //gulpで使うストリーム形式に変換


//Browserify + babelify
gulp.task('build:scripts', function() {
    return browserify('./main.js') //対象のファイル
        .transform("babelify", {presets: ["es2015"]}) オプション
        .bundle()
        .pipe(source('app.js')) 変換かつ出力するファイル名も指定
        .pipe(gulp.dest('./')); 出力先。これは同じところに。
});

watchify で browserify を差分だけ実行してくれる

Watchify は Browserify の開発者が作っているもので、差分だけをコンパイルすることでかなり早い。これも本当は Gulp から実行できるのだが、ちょっと難しかった。

色々検索した所、package.json の script に書いてしまえば、普通に CLI で実行するのと同じように実行できるとのこと。npm script という名前。

//package.json
{
  "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",
    "vinyl-source-stream": "^1.1.0",
    "watchify": "^3.9.0"
  },
  "scripts": {
    "watch": "watchify main.js -v -t babelify -d -o app.js",
  },
  "browserify": {//いまいち謎だが、内容的には当然browserifyのoptiion
    "transform": [["babelify", {"presets": ["es2015"]}]]
  }
}

npm run スクリプト名で実行できるので、npm run watch で実行できる。できた早い!!

さらにブラウザシンクもする

http://ceblog.mediba.jp/post/154522336717/npm-scripts

こちらのほうがわかりやすいかsass

Node.jsユーザーなら押さえておきたいnpm-scriptsのタスク実行方法まとめ

node-sass が良さそうなので入れる

npm install node-sass –save-dev

"sass": "node-sass --include-path src/sass --watch src/sass/screen.sass src/css/screen.css"

include pass は @import するファイルのある位置のはず。 –watch オプションを与えることで監視。どうやらこれだけで、import しているファイルが変化しただけでも更新してくれる模様。

次のようにすれば、同時に実行してくれる。

"start": "npm run watch:script & npm run watch:sass",