Motomichi Works Blog

モトミチワークスブログです。その日学習したことについて書いている日記みたいなものです。

gulp+browserify+watchify+babelifyを導入してReact.jsのプロジェクトを作る

参考にさせて頂いたページ

以前作ったgulpのプロジェクト

gulpを使う場合

WebPackを使う場合

exorcistについて

「gulp, browserify, vinyl」と「vinyl-source-stream」について

vinyl-bufferについて

.babelrcとbabel-preset-es2015とbabel-preset-reactについて

今日の環境

  • Windows10
  • node v4.4.7
  • npm 2.15.8
  • gulp CLI version 3.9.1
  • browserify 13.0.1
  • その他 package.json 参照

グローバルにインストールするモジュール

gulp

browserify

watchify

babel

プロジェクトにインストールするモジュール

gulp browserify watchify gulp-babel babelify

react react-dom

babel-preset-es2015 babel-preset-react

Babelで書いたReactのJSXがNo Display Nameになる - はらへり日記」によると、「babel-preset-es2015」はES2015のコンパイルに必要とのこと。

「babel-preset-react」はJSXをコンパイルするのに必要とのこと。

gulp-uglify vinyl-source-stream vinyl-buffer

gulp-sourcemaps exorcist

インストールしていく

プロジェクトディレクトリとして、仮にreact-introductionディレクトリを作成して、進めることにする。

まず任意の場所に作成したreact-introductionディレクトリの中でinitして、package.jsonを作る

npm init

グローバルな領域にインストールする。既にインストールしている場合は良い。

npm install -g gulp browserify watchify babel

プロジェクトにインストールする

npm install --save-dev gulp browserify watchify gulp-babel babelify

npm install --save-dev react react-dom

npm install --save-dev babel-preset-es2015 babel-preset-react

npm install --save-dev gulp-uglify vinyl-source-stream vinyl-buffer

npm install --save-dev gulp-sourcemaps exorcist

この段階でのpackage.jsonの記述内容

{
  "name": "react-introduction",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-preset-es2015": "^6.9.0",
    "babel-preset-react": "^6.11.1",
    "babelify": "^7.3.0",
    "browserify": "^13.0.1",
    "exorcist": "^0.4.0",
    "gulp": "^3.9.1",
    "gulp-babel": "^6.1.2",
    "gulp-sourcemaps": "^1.6.0",
    "gulp-uglify": "^1.5.4",
    "react": "^15.2.1",
    "react-dom": "^15.2.1",
    "vinyl-buffer": "^1.0.0",
    "vinyl-source-stream": "^1.1.0",
    "watchify": "^3.7.0"
  }
}

gulpfile.jsの作成とその記述内容

/************************************************
 * コマンドラインから実行するtaskとその概要
 ************************************************/
 /**
  * コマンド : gulp browserify
  *     - jscompile()を実行
  */

 /**
  * コマンド : gulp watchify
  *     - JS__SRC__PATHの変更をトリガーにして、jscompile()を繰り返し実行
  */



/************************************************
 * モジュール読み込み
 ************************************************/
 var gulp        = require('gulp');
 var babel       = require('gulp-babel');
 var sourcemaps  = require('gulp-sourcemaps');
 var browserify  = require('browserify');
 var watchify    = require('watchify');
 var babelify    = require('babelify');
 var uglify      = require('gulp-uglify');
 var source      = require('vinyl-source-stream');
 var buffer      = require('vinyl-buffer');



/************************************************
 * path設定
 ************************************************/
var JS__SRC__PATH             = './src/js';
var JS__RESULT__PATH          = './result/js'; // 完成品のJSが出力されるディレクトリ



/************************************************
 * tasks
 ************************************************/

/**
 * JS__SRC__PATHに対するコンパイルを一回実行するタスク
 *
 * @return {Object} gulp ストリーム
 */
gulp.task('browserify',function(){
  return jscompile(false);//引数がfalseなので監視しない
});

/**
 * JS__SRC__PATHを監視して、JS__SRC__PATHに対するコンパイルを繰り返し実行するタスク
 *
 * @return {Object} gulp ストリーム
 */
gulp.task('watchify',function(){
  return jscompile(true);//引数がtrueなので監視する
});

// jscompile関数を定義
function jscompile(is_watch){
  // 変数bundlerにwatchify()またはbrowserify()を格納
  var bundler;
  if(is_watch){
    bundler = watchify(browserify(JS__SRC__PATH + '/main.js'));
  }else{
    bundler = browserify(JS__SRC__PATH + '/main.js');
  }
  //関数rebundleを定義
  function rebundle(){
    return bundler
      .transform(babelify, {"presets": ["es2015", "react"]})
      .bundle()
      .on("error", function (err) { console.log("Error : " + err.message); })
      .pipe(source('main.js'))
      .pipe(buffer())
      .pipe(uglify())
      .pipe(gulp.dest(JS__RESULT__PATH));
  }

  bundler.on('update',function(){
    rebundle();
  });
  bundler.on('log',function(message){
    console.log( message );
  });
  return rebundle();
}

./src/js/main.jsの作成とその記述内容

import React from 'react';
import ReactDom from 'react-dom';
import Hoge from './child/react-components/hoge';

ReactDom.render(<Hoge />, document.getElementById('example'));

./src/js/react-components/child/hoge.jsの作成とその記述内容

import React, {Component} from 'react'

export default class Hoge extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return(
      <div className='hoge'>
        hoge element.
      </div>
    );
  }
}

react-introduction.htmlの作成とその記述内容

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<title>react-tutorial</title>
<link rel="stylesheet" href="">
</head>
<body>

  <div id="example"></div>

<script type="text/javascript" src="./js/main.js"></script>
</body>
</html>

watchifyタスクでビルドしてみる

gulp watchify

できた。

react-introduction.htmlをブラウザで開いてみると、以下の要素が表示されている。

<div data-reactroot="" class="hoge">hoge element.</div>

これでES2015でReact.jsが使える環境が整ったので、今回はここまで。

Chocolateyその0001 Windows10にChocolateyをインストールして少し使ってみる

参考にさせて頂いたページ

Chocolatey - Installation

windowsの開発環境は一瞬で整うwith chocolatey - Qiita

Chocolateyを使った環境構築の時のメモ - Qiita

Windowsソフトを管理!パッケージ管理システムChocolateyでインストール、アップデートを簡単にする

Chocolateyとは

macでいうところのhomebrewみたいなものだそう。

コマンドで簡単にアプリケーションがインストールできて、依存関係の解決や、アップデートも簡単にできそうで良い。

今日の環境

2016年7月11日現在

  • Windows10
  • Chocolatey 0.9.10.3

インストールしようとしたら失敗した

公式サイトにあった以下のコマンドをそのまま実行したらエラーになった。
参考程度に貼っちゃったけど、コマンド自体は公式サイトから最新のものを使ってください。

@powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin

エラー内容

エラーというのは以下のようなものだった。

Installation of Chocolatey to default folder requires Administrative permissions.
Please run from elevated prompt.
Please see https://chocolatey.org/install for details and alternatives if needing to install as a non-administrator.

発生場所 C:\Users\motomichi\AppData\Local\Temp\chocolatey\chocInstall\tools\chocolateysetup.psm1:211 文字:5
+     throw "Installation of Chocolatey to default folder requires Admi ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (Installation of...-administrator.:String) [], RuntimeException
    + FullyQualifiedErrorId : Installation of Chocolatey to default folder requires Administrative permissions. Please
    run from elevated prompt. Please see https://chocolatey.org/install for details and alternatives if needing to in
  stall as a non-administrator.

Google翻訳してみたら、

デフォルトのフォルダにチョコレートのインストールは管理者権限が必要です。高架プロンプトから実行してください。

とかそんな感じだったので管理者権限でコマンドプロンプトを実行しないといけないっぽい。

インストール成功する

管理者権限でコマンドプロンプトを起動して、やり直したらいくつかWARNINGが出たけどインストールできた様子。
以下のように表示された。

Downloading https://packages.chocolatey.org/chocolatey.0.9.10.3.nupkg to C:\Users\MOTOMI~1\AppData\Local\Temp\chocolatey\chocInstall\chocolatey.zip
Download 7Zip commandline tool
Downloading https://chocolatey.org/7za.exe to C:\Users\MOTOMI~1\AppData\Local\Temp\chocolatey\chocInstall\7za.exe
Extracting C:\Users\MOTOMI~1\AppData\Local\Temp\chocolatey\chocInstall\chocolatey.zip to C:\Users\MOTOMI~1\AppData\Local\Temp\chocolatey\chocInstall...

7-Zip (A) 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18

Processing archive: C:\Users\MOTOMI~1\AppData\Local\Temp\chocolatey\chocInstall\chocolatey.zip

Extracting  _rels\.rels
Extracting  chocolatey.nuspec
Extracting  tools\chocolateyInstall.ps1
Extracting  tools\chocolateysetup.psm1
Extracting  tools\init.ps1
Extracting  tools\chocolateyInstall\choco.exe
Extracting  tools\chocolateyInstall\choco.exe.ignore
Extracting  tools\chocolateyInstall\LICENSE.txt
Extracting  tools\chocolateyInstall\helpers\chocolateyInstaller.psm1
Extracting  tools\chocolateyInstall\helpers\chocolateyProfile.psm1
Extracting  tools\chocolateyInstall\helpers\chocolateyScriptRunner.ps1
Extracting  tools\chocolateyInstall\helpers\ChocolateyTabExpansion.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Format-FileSize.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Get-CheckSumValid.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Get-ChocolateyUnzip.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Get-ChocolateyWebFile.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Get-EnvironmentVariable.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Get-EnvironmentVariableNames.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Get-FtpFile.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Get-OSArchitectureWidth.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Get-ToolsLocation.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Get-UACEnabled.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Get-UninstallRegistryKey.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Get-VirusCheckValid.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Get-WebFile.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Get-WebFileName.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Get-WebHeaders.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Install-BinFile.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Install-ChocolateyDesktopLink.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Install-ChocolateyEnvironmentVariable.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Install-ChocolateyExplorerMenuItem.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Install-ChocolateyFileAssociation.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Install-ChocolateyInstallPackage.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Install-ChocolateyPackage.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Install-ChocolateyPath.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Install-ChocolateyPinnedTaskBarItem.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Install-ChocolateyPowershellCommand.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Install-ChocolateyShortcut.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Install-ChocolateyVsixPackage.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Install-ChocolateyZipPackage.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Install-Vsix.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Set-EnvironmentVariable.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Set-PowerShellExitCode.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Start-ChocolateyProcessAsAdmin.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Test-ProcessAdminRights.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Uninstall-BinFile.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Uninstall-ChocolateyEnvironmentVariable.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Uninstall-ChocolateyPackage.ps1
Extracting  tools\chocolateyInstall\helpers\functions\UnInstall-ChocolateyZipPackage.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Update-SessionEnvironment.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Write-ChocolateyFailure.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Write-ChocolateySuccess.ps1
Extracting  tools\chocolateyInstall\helpers\functions\Write-FileUpdateLog.ps1
Extracting  tools\chocolateyInstall\redirects\choco.exe
Extracting  tools\chocolateyInstall\redirects\choco.exe.ignore
Extracting  tools\chocolateyInstall\redirects\chocolatey.exe
Extracting  tools\chocolateyInstall\redirects\chocolatey.exe.ignore
Extracting  tools\chocolateyInstall\redirects\cinst.exe
Extracting  tools\chocolateyInstall\redirects\cinst.exe.ignore
Extracting  tools\chocolateyInstall\redirects\clist.exe
Extracting  tools\chocolateyInstall\redirects\clist.exe.ignore
Extracting  tools\chocolateyInstall\redirects\cpack.exe
Extracting  tools\chocolateyInstall\redirects\cpack.exe.ignore
Extracting  tools\chocolateyInstall\redirects\cpush.exe
Extracting  tools\chocolateyInstall\redirects\cpush.exe.ignore
Extracting  tools\chocolateyInstall\redirects\cuninst.exe
Extracting  tools\chocolateyInstall\redirects\cuninst.exe.ignore
Extracting  tools\chocolateyInstall\redirects\cup.exe
Extracting  tools\chocolateyInstall\redirects\cup.exe.ignore
Extracting  tools\chocolateyInstall\redirects\cver.exe
Extracting  tools\chocolateyInstall\redirects\cver.exe.ignore
Extracting  tools\chocolateyInstall\redirects\RefreshEnv.cmd
Extracting  tools\chocolateyInstall\tools\7z.dll
Extracting  tools\chocolateyInstall\tools\7z.exe
Extracting  tools\chocolateyInstall\tools\7z.exe.ignore
Extracting  tools\chocolateyInstall\tools\7z.exe.manifest
Extracting  tools\chocolateyInstall\tools\7zip.license.txt
Extracting  tools\chocolateyInstall\tools\checksum.exe
Extracting  tools\chocolateyInstall\tools\checksum.exe.config
Extracting  tools\chocolateyInstall\tools\checksum.exe.ignore
Extracting  tools\chocolateyInstall\tools\checksum.license.txt
Extracting  tools\chocolateyInstall\tools\detector.zip
Extracting  tools\chocolateyInstall\tools\shimgen.exe
Extracting  tools\chocolateyInstall\tools\shimgen.exe.ignore
Extracting  tools\chocolateyInstall\tools\shimgen.license.txt
Extracting  package\services\metadata\core-properties\1a0b5bbf338444a596bb1ebebba80b77.psmdcp
Extracting  [Content_Types].xml

Everything is Ok

Files: 87
Size:       11891084
Compressed: 7214019
Installing chocolatey on this machine
Creating ChocolateyInstall as an environment variable (targeting 'Machine')
  Setting ChocolateyInstall to 'C:\ProgramData\chocolatey'
WARNING: It's very likely you will need to close and reopen your shell
  before you can use choco.
Restricting write permissions to Administrators
We are setting up the Chocolatey package repository.
The packages themselves go to 'C:\ProgramData\chocolatey\lib'
  (i.e. C:\ProgramData\chocolatey\lib\yourPackageName).
A shim file for the command line goes to 'C:\ProgramData\chocolatey\bin'
  and points to an executable in 'C:\ProgramData\chocolatey\lib\yourPackageName'.

Creating Chocolatey folders if they do not already exist.

WARNING: You can safely ignore errors related to missing log files when
  upgrading from a version of Chocolatey less than 0.9.9.
  'Batch file could not be found' is also safe to ignore.
  'The system cannot find the file specified' - also safe.
chocolatey.nupkg file not installed in lib.
 Attempting to locate it from bootstrapper.
PATH environment variable does not have C:\ProgramData\chocolatey\bin in it. Adding...
Adding Chocolatey to the profile. This will provide tab completion, refreshenv, etc.
WARNING: Chocolatey profile installed. Reload your profile - type . $profile
Chocolatey (choco.exe) is now ready.
You can call choco from anywhere, command line or powershell by typing choco.
Run choco /? for a list of functions.
You may need to shut down and restart powershell and/or consoles
 first prior to using choco.
Ensuring chocolatey commands are on the path
Ensuring chocolatey.nupkg is in the lib folder

WARNINGで黄色く表示された箇所

上記したメッセージから抜粋すると下記の3箇所だった。

WARNING: It's very likely you will need to close and reopen your shell
  before you can use choco.
WARNING: You can safely ignore errors related to missing log files when
  upgrading from a version of Chocolatey less than 0.9.9.
  'Batch file could not be found' is also safe to ignore.
  'The system cannot find the file specified' - also safe.
WARNING: Chocolatey profile installed. Reload your profile - type . $profile

バージョン確認

インストールされてパスが通っているかを確認したいのでバージョン確認をしてみる。

choco -v

アプリケーションをインストールしてみる

例えばFirefoxをインストールする場合は

cinst firefox

または

choco install firefox

Firefoxがインストールできる。

XMLでまとめてインストールする

windowsの開発環境は一瞬で整うwith chocolatey - Qiita」に紹介されているような感じでXMLにまとめておけば、PCを買い替えたときも簡単そう。

今回はここまで。

vagrantその0025 Windows10でvagrantを使う

参考にさせて頂いたページ

Windows10にVirtualBoxとVagrantでCentOSの仮想環境を作ってみた / ユービックログ

VagrantでBox追加時にエラーが出た時の話 - Naba Blog

今回の環境(使用したインストーラー)

virtualboxのインストール

Windows10にVirtualBoxとVagrantでCentOSの仮想環境を作ってみた / ユービックログ

を参考に環境構築をしていく。

VirtualBox-5.0.24-108355-Win.exe をダウンロードしてインストールした。

特に設定変更などはせずにインストールした。

C:\Program Files\Oracle\VirtualBox

にインストールした。

vagrantのインストール

vagrant_1.8.4.msi をダウンロードしてインストールした。

C:\HashiCorp\Vagrant\

にインストールした。

vagrant box add しようとしたらエラー

cd ~
vagrant box add 任意の名前 URL

したら以下のようなエラーが出た。

An error occurred while downloading the remote file. The error
message, if any, is reproduced below. Please fix this error and try
again.

Microsoft Visual C++ 2010 再頒布可能パッケージ をインストールしてエラーを解消する

VagrantでBox追加時にエラーが出た時の話 - Naba Blog

に倣って

をインストールした。

そのときのインストーラーは以下の二つ。

  • vcredist_x86.exe
  • vcredist_x64.exe

vagrant box add する

もういちど

Windows10にVirtualBoxとVagrantでCentOSの仮想環境を作ってみた / ユービックログ

にならって続きを行う。

CentOS 6.7 x64 (Minimal, Puppet 4.2.3, Guest Additions 4.3.30)

を選択することにしたので、

https://github.com/CommanderK5/packer-centos-template/releases/download/0.6.7/vagrant-centos-6.7.box

のboxを使う。

例えば以下のように

vagrant box add centos67box https://github.com/CommanderK5/packer-centos-template/releases/download/0.6.7/vagrant-centos-6.7.box

みたいな感じで実行する。

これは時間がかかる。

回線速度にもよるんだろうけど、うちは遅いので20分くらいかかった。

以下のように表示されてbox追加成功した。

==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'centos67box' (v0) for provider:
    box: Downloading: https://github.com/CommanderK5/packer-centos-template/releases/download/0.6.7/vagrant-centos-6.7.box
    box:
==> box: Successfully added box 'centos67box' (v0) for 'virtualbox'!

以下のコマンドで追加済みのboxを確認する。

vagrant box list

vagrant init する

任意の場所に vagrant_sample ディレクトリを作成して進めてみる。

mkdir sample_vagrant cd sample_vagrant

centos67boxという名前でboxを追加したので

以下のコマンドを実行した。

vagrant init centos67box

以下のように表示された。

A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

このディレクトリにVagrantfileができた。

vagrant up する

Windowsの場合は、ここからはコマンドプロンプトじゃなくて、msysgitでインストールされるgitbashを使うと良いと思う。

以下のコマンドを実行した。

vagrant up

以下のように表示されて成功した。

Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'centos67box'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: vagrant_sample_default_1467987696042_15307
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default:
    default: Vagrant insecure key detected. Vagrant will automatically replace
    default: this with a newly generated keypair for better security.
    default:
    default: Inserting generated public key within guest...
    default: Removing insecure key from the guest if it's present...
    default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
    default: The guest additions on this VM do not match the installed version of
    default: VirtualBox! In most cases this is fine, but in rare cases it can
    default: prevent things such as shared folders from working properly. If you see
    default: shared folder errors, please make sure the guest additions within the
    default: virtual machine match the version of VirtualBox you have installed on
    default: your host and reload your VM.
    default:
    default: Guest Additions Version: 4.3.30
    default: VirtualBox Version: 5.0
==> default: Mounting shared folders...
    default: /vagrant => C:/Users/motomichi/Desktop/all/vagrant_all/vagrant_sample

ここでこけることがよくあるし、実際そういうブログとかも多いと思うのでラッキーだった。

何年か前にwindows7とかMacOSXでやったときはvirtualboxvagrantのバージョンの組み合わせ次第で駄目だったり、WindowsBIOS設定を変更して、仮想化機能を有効にしないといけなかったり、色々躓いた。

仮想化機能の有効化については以下のような感じかな。

Windows7:Virtual PC(バーチャルPC)を使うには - 教えて!HELPDESK

仮想化機能を有効にするためのBIOS設定|テックウインド株式会社

仮想サーバにログインしてみる

以下のコマンドを実行した。

vagrant ssh

ログインできた。

rootユーザーにスイッチしてみる。

su

パスワードの入力を促されるので

vagrant

rootユーザーになった。

ログアウトしてみる。

exit
exit

仮想サーバをシャットダウンしておく。

vagrant halt

シャットダウンされた。

とりあえず今回はここまで。

WebデザインからCSS設計について考える その0004 BEMについて少し考えてみる

参考にさせて頂いたページ

Naming convention / Methodology / BEM

[CSS]BEMの方法論とMindBEMdingという記法 - Qiita

命名規則について

MindBEMdingについて

おそらく下記のような記法がBEMとして広く認知されていると思います。

block-name__element-name--modifier-name

上記のような記法をMindBEMdingというそうです。

公式の命名規則ページについて

公式の記法

Naming convention(命名規則)のページにはBEMの記法として以下のような記法で説明されています。

  • modifierがbooleanの場合 block-name__element-name_modifier-name
  • modifierがkey-valueタイプの場合 block-name__element-name_modifier-name_modifier-value

公式で Alternative naming schemes(代替命名スキーム)として紹介されている記法

いくつかの事柄がNaming convention / Methodology / BEMに書かれています。

そのうちの一つには下記のようにMindBEMdingに該当する記法が紹介されています。

Modifiers are delimited by double hyphens (--).

命名規則以外のこと

BEMはCSSのクラス命名規則以外のことにも触れています。

例えば以下のような「ビルドする前の素材を格納するディレクトリ構造から、ビルドまでの手法」について触れています。

  • File system organization (ファイル・システムの編成)
  • BEM project building methodology (BEMプロジェクト構築方法論)

blockに紐付くjsの振る舞いや、画像素材の管理も含むようです。

そういう事までBEMでやるのはなんかつらそうに見えます。

まとめ

あらためてBEMについて学習してみました。

やはり広く認知されているMindBEMdingの記法を使用して、modifierはbooleanとかkey-valueであるとか気にせずに、下記のようにするのが良さそうな気がしています。

block-name__element-name--modifier-name

次回のこと

次回はSMACSSとBEMを混ぜ合わせて、CSS設計について考えます。

実際に自分がどのように書いているかなど、実例も踏まえて書けたらいいなと思っています。

今回BEMについて学びました。

大規模なサイトのCSSを長期的に運用していくことを考えると、SMACSSとBEMを混ぜるのが良いと思っています。

広く知られているSMACSSやBEMをもとに、新しくチームに加わる仲間や後任者への引き継ぎがなるべく簡単になるようにまとめられたら良いなと思います。

WebデザインからCSS設計について考える その0003 SMACSSの必要部分について学ぶ

参考にさせて頂いたページ

SMACSS

Home - Scalable and Modular Architecture for CSS

前提として知っておく知識

以前の記事で、デザインを作成したり、CSS書いたりする際に参考にさせて頂いたサイトURLをまとめました。

WebデザインからCSS設計について考える その0001 前提知識みたいなもののリンクをまとめた - MOTOMICHI WORKS BLOG

前に見てたサイトどれだっけなー。ってなると困っちゃうので。

はじめに

今回、SMACSSの中で個人的に必要としている部分だけ学ぶということであって、これがSMACSSの全てというわけではありません。

SMACSSについての抜粋

SMACSSのカテゴリ分類

以下の5つのカテゴリがあります。

  • ベース
  • レイアウト
  • モジュール
  • ステート (状態)
  • テーマ

各カテゴリについて掘り下げ

ベース

reset.css、normalize.css、sanitize.cssみたいなものだと捉えてます。

要素に直にスタイルを指定するので接頭辞はありません。

レイアウト

接頭辞はl-またはlayout-とSMACSSのドキュメントに書いてあります。

モジュールを並べる為の枠です。

モジュール

モジュール名

SMACSSではモジュールの一番外側になる要素には module- という接頭辞を付けたりすると冗長であるとし、モジュール名をそのまま付けます。

例えばナビゲーションのCSSならば以下のように書くようです。

.nav{}/* 冗長なので .module-nav という命名はしない */
.nav .ul-ol-elm{}
.nav .li-elm{}
.nav .anc-elm{}

上記のCSSに対応するHTMLは以下のようになります。

<div class="nav">
  <ul class="ul-ol-elm">
    <li class="li-elm">
      <a class="anc-elm" href="#">hoge</a>
    </li>
    <li class="li-elm">
      <a class="anc-elm" href="#">foo</a>
    </li>
  </ul>
</div>

一番親の要素につけるクラスがモジュール名です。
この例では.navです。

この例で子要素のクラスである、
.ul-ol-elm
.li-elm
.anc-elm
は全て、.navの中にあるときしかスタイルが適用されません。

このように、モジュール名のクラス.navだけがスコープの無いグローバルなクラスになります。

サブクラス名

サブクラス名は、モジュールクラス名と一緒に付与することで、「サブモジュール」を作ります。
サブクラスの命名規則は接頭辞としてモジュール名-が付きます。
ここまで書いてきたナビゲーションの例でいうとnav-です。

上記したナビゲーションのCSSではプロパティを何も指定していないので、li要素はdisplay:blockが初期値です。 navのサブモジュールを定義する為に、例えば二行追記して、以下のようにします。

.nav{}
.nav .ul-ol-elm{}
.nav .li-elm{}
.nav .anc-elm{}

.nav.nav-inline{}
.nav.nav-inline .li-elm{display:inline;}

二行追記された上記のCSSに対応するHTMLは以下のようになります。

<div class="nav nav-inline">
  <ul class="ul-ol-elm">
    <li class="li-elm">
      <a class="anc-elm" href="#">hoge</a>
    </li>
    <li class="li-elm">
      <a class="anc-elm" href="#">foo</a>
    </li>
  </ul>
</div>

この例ではモジュールの一番外側にあたるdiv要素にnavとnav-inlineを付けることで、サブモジュールを定義しています。

さらなるサブモジュールを定義するには、例えば二行追記して、以下のようにします。

.nav{}
.nav .ul-ol-elm{}
.nav .li-elm{}
.nav .anc-elm{}

.nav.nav-inline{}
.nav.nav-inline .li-elm{display:inline;}

.nav.nav-inline-block{}
.nav.nav-inline-block .li-elm{display:inline-block;}
ついでに

もしかすると「サブクラスで色を変える」という例の方がイメージしやすいかもしれません。

Bootstrapのボタンの例も書いておきます。

ボタン ≪ CSS ≪ Bootstrap3日本語リファレンス

上記のページにあるように

<button class="btn btn-default">button要素</button>

<button class="btn btn-primary">button要素</button>

として、

btnというクラスとbtn-primaryというクラスを組み合わせて色の違うボタンを表現しています。

ステート (状態)

接頭辞はis-です。

下記の二つはCSSの適用の仕方として、「モジュールクラスと組み合わせたときに適用されるスタイル」という点で似ています。

  • ステートクラスis-による状態定義
  • サブクラスによるサブモジュールの定義

上記した二つが決定的に異なる点として、

  • is-はレイアウトにもモジュールにも組み合わせて良い
  • is-はページが描画された後で、JavaScriptによって外したり付けたりするクラス

という二点がSMACSSのドキュメントで挙げられています。

それに対して、サブクラスはページ描画がされたときに始めから付いていて、jsで外したり付けたりしないクラスです。

テーマ

接頭辞はtheme-です。

ドキュメントの中で以下のような説明がされています。

  • サイトが持つルック&フィールを定義するもの
  • テーマは全てのルールに対して影響を及ぼすもの
  • テーマはユーザに対して表面的なデザイン変更を提供したい場合に使用される
  • サイト内で別セクションでは別の色を使いたい場合やユーザ自身が色を変更したい場合、または言語や国によって異なるテーマを設定したい場合などがある。

bodyであったり、そのひとつ内側に配置した要素にidやclassを付けることによるCSSシグネチャをする役割を持つようです。

個人的な印象としては、CSS設計上これを必要とするサービスはあまり多くない気がしています。

SMACSSに無い接頭辞

スタイルを適用するクラスではないため、SMACSSとは関係ないのですが、HTML要素に付与するクラスには役割ごとに接頭辞を付けておくと管理が楽な気がします。

JavaScriptでgetElementする為のクラスやid

js-という接頭辞を付ける人も少なくないかと思います。

特にjQueryなどでイベントトリガーになる要素や、DOM操作の対象となる要素に付けたりします。

デザインと振る舞いとを分けることができたり、前任者から引き継いだHTMLソースコードについて、理解しやすかったりします。

HTML要素に付けるクラスが多くなり、冗長にはなりますが長い目でみると運用チームとして有益な気がします。

チェックボックスラジオボタンで、label要素に対応したidを付与するときに、label-などの接頭辞を付けるのも良いかと思います。

今回のまとめ

SMACSSのカテゴリ

SMACSSではCSSは以下の5つのカテゴリに分かれています。

  • ベース(要素そのものに設定するので接頭辞は無し)
  • レイアウト
  • モジュール(SMACSSにおいて接頭辞の付かないクラスは全てモジュール)
  • ステート (状態)
  • テーマ

SMACSSの接頭辞

SMACSSにおける接頭辞は以下の3種類です。それ意外のクラスは全てモジュールです。

  • l-
  • is-
  • theme-

モジュールの命名規則

  • 一番親となる要素に付与するモジュールクラス名(接頭辞は無しで、今回の例ではnav)
  • 子クラスは親クラスの中でしかスタイル適用されない(今回の例では.nav .ul-ol-elm{}みたいに半角スペースで区切っている)
  • サブクラス名は、モジュール名を接頭辞として命名(今回の例ではnav-inline)

メリット

SMACSSでは影響範囲の大きいグローバルなクラスを極力作らないことで、CSSの編集による影響範囲を明示し把握しやすくすることで、安心してCSSを編集できる。

次回のこと

次回はBEMについて少し学んで考えます。

JavaScript学習日記 その0004 jQueryの$.ajaxでjsonpを取得する

参考にさせて頂いたページ

今回これを参考に動かしてみた

jQuery.ajaxでphpから出力したjsonpを扱った時のメモ | ミラボ

jsonpって何なのか

JSONPで悩むある程度の人々へ

はじめに

ドメインが違うサーバーから、オブジェクトのデータを取得したい場合はdataTypeをjsonpにするんだけど、「jsonpって何?jsonとどう違うの?」っていう感じだったのと、$.ajaxに渡すオプションをどのように設定したら良いのかわからなかったので、実際に試してみた。

jsonp-sample__api.phpの作成とその記述内容

例として以下の通り。

<?php
$jsonArray = array(
  "hoge" => "ほげ",
  "foo" => "ふー"
);
header('Content-Type: text/javascript; charset=utf-8');
echo sprintf("callback(%s)",json_encode($jsonArray));

jsonp-sample__page.htmlの作成とその記述内容

例として以下の通り。

<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8" />
  <title>jsonp-sample__page.html</title>
</head>
<body>

<h1>jsonp-sample__page.html</h1>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script>
$.ajax({
  url: 'https://hoge.jp/jsonp-sample__api.php',
  type: 'GET',
  dataType : 'jsonp',
  jsonpCallback: 'callback'
}).done(function(data){
  console.log('doneです');
  console.log(data);
}).fail(function(err){
  console.log('failです');
  console.error(err);
});
</script>
</body>
</html>

jsonp-sample__api.phpにブラウザでアクセスしてみる

callback({“hoge”:“\u307b\u3052”,“foo”:“\u3075\u30fc”})

という文字列が表示される。

jsonp-sample__page.htmlにブラウザでアクセスしてみる

デバロッパーツールでconsoleを確認した。

このソースについて

jsonp-sample__api.phpではcallback(オブジェクト)という文字列を出力するような感じに記述している。

非同期でこのjsonp-sample__api.phpにリクエストすることで、この文字列を受け取る。

上記のcallbackという関数名は、$.ajaxに渡すオプションのjsonpCallbackで設定した文字列と同じにするので任意の関数名にできるんだけど、検索してみるとcallbackという関数名にするのが一般的みたい。

$.ajax実行時には以下の4つのキーが最低限必要だと思う。

  • url
  • type
  • dataType
  • jsonpCallback

$.ajax実行時に上記のようなオプションを適切に渡していれば、doneでは特に何かを意識することなく、普通のjsonがreturnされたときのように処理すれば良い。

JavaScript学習日記 その0003-01 jQuery UIのDatepicker | 曜日ごとに色を変える、任意の座表に絶対配置する、インラインに配置する

参考にさせて頂いたページ

絶対表示の位置変更について position()

jQuery UI Datepicker(カレンダー)表示位置の調整 | Eniod's Blog

jQuery UI Datepicker(カレンダー)表示位置の変更 サンプル

.position() | jQuery UI API Documentation

jQuery UI の Position メソッドで要素の表示位置を指定する

Datepickerについて

Datepicker Widget | jQuery UI API Documentation

datepickerにおけるオプション(datepicker) | IT情報サイト - 明日はどっと混む

jQuery UI Datepicker(カレンダー)土・日・祝日の表示色の変更

はじめに

これまでなんとなく使ってきたけど、いざ配置場所を変えようしたり、曜日ごとに色を変えようと思ったらよくわからなかったので改めて学習した。

jQuery UI のDatepickerでカレンダーを表示して、positionで表示位置を調整したり、インラインで配置することで色々なデザインに対応できそう。

オプションの一覧についても、datepickerにおけるオプション(datepicker) | IT情報サイト - 明日はどっと混むに日本語で書いてあったのでありがたい。

こちらは公式でメソッドについても書いてある。 Datepicker Widget | jQuery UI API Documentation

サンプルコード

例として以下の通り。

<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8" />
  <title>jQuery UI Datepicker - Default functionality</title>
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />
  <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
  <script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1/i18n/jquery.ui.datepicker-ja.min.js"></script>
  <link rel="stylesheet" href="/demos/style.css" />
  <script>
  $(function() {
    $.datepicker.setDefaults( $.datepicker.regional[ "ja" ] );

    $( "#datepicker" ).datepicker({
      showOn: 'both',
      showAnim: 'fadeIn',
      numberOfMonths: 1,
      buttonImage: 'img/hoge.gif',
      buttonImageOnly: true,
      minDate: '0',
      maxDate: '+3m',
      dateFormat: 'yy/mm/dd',
      beforeShowDay: function(date){
        var calendar = $('#ui-datepicker-div');
          setTimeout(function() {
            calendar.position({
              my: 'left top', // カレンダーのここを
              at: 'center bottom',// ofで指定した要素のここに
              of: '#here'
            });
        }, 1);

        // 日曜日
        if (date.getDay() == 0) {
          return [true, 'sunday']; //[クリッカブルかどうか, クラス名]
        }
        // 土曜日
        if (date.getDay() == 6) {
          return [true, 'saturday'];
        }
        // 平日
        return [true, ''];
      }
    });

    $( "#datepicker2" ).datepicker({
      showOn: 'both',
      showAnim: 'fadeIn',
      numberOfMonths: 1,
      buttonImage: 'img/hoge.gif',
      buttonImageOnly: true,
      minDate: '0',
      maxDate: '+3m',
      dateFormat: 'yy/mm/dd',
      beforeShowDay: function(date){
        var calendar = $('#ui-datepicker-div');
          setTimeout(function() {
            calendar.position({
              my: 'left top', // カレンダーのここを
              at: 'center bottom',// ofで指定した要素のここに
              offset: '100px 30px',
              of: '#here2'
            });
        }, 1);

        // 日曜日
        if (date.getDay() == 0) {
          return [true, 'sunday']; //[クリッカブルかどうか, クラス名]
        }
        // 土曜日
        if (date.getDay() == 6) {
          return [true, 'saturday'];
        }
        // 平日
        return [true, ''];

      }
    });

    $( "#datepicker3" ).datepicker({
      onSelect: function(dateText, inst) {
        $("#date_val").val(dateText);
      }
    });

  });
  </script>
</head>
<body>

<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<p>日付: <input type="text" id="datepicker" /> <input type="text" id="datepicker2" /></p>
<br><br><br>

<span id="here">absolute1</span>
<br><br><br>

<span id="here2">absolute2</span>
<br><br><br><br><br><br><br><br><br><br><br><br>

<p>インライン配置されるカレンダー(絶対配置されない)</p>
<div id="datepicker3">
  <input id="date_val" type="text">
</div>
<p id="test"></p>
</body>
</html>

.position()のオプション

jQuery UI の Position メソッドで要素の表示位置を指定するによると、以下のようなオプションが設定できるらしい。

  • my
  • at
  • of
  • offset
  • collision
  • using

今回はここまで。