Help us understand the problem. What is going on with this article?

そろそろ自社で今時のCSS、JS教育をしようと思う(プロジェクト作成編)

More than 5 years have passed since last update.

そろそろ自社で今時のCSS、JS教育をしようと思う(Node.js インスコ編)」の続き。
ちなみに前回のインストールは作業者全員にやってもらう必要があるのですが、今回の作業はどちらかというと上級者向けというかシニア向けというか、プロジェクトの中で方針決めたりなんだりする人がする作業です。
プロジェクトまで作ったら後はGitで共有してごりごりチーム開発を進めていきます。

Yeoman

 Yeomanはプロジェクトの雛形を生成することができるツールです。
 なお、プロジェクトの雛形はnpmもしくはGitを扱うサービスで公開されているものより選択可能です。

雛形(generator)を検索する

 以下のコマンドでgeneratorを検索できます。(ただし、1回目はすごく時間がかかります)

$ npm search yeoman-generator

めぼしい雛形をインストールする

 generator-jadestylという、Jade、Stylus、CoffeeScript用の雛形があったのでこちらをいれてみましょう。

$ mkdir c:\sample-project (任意のフォルダ)
$ cd c:\sample-project (ディレクトリ移動)
$ npm install generator-jadestyl --save-dev  (雛形をインストールする)

npm install時のgオプションはグローバル、--save-devオプションはプロジェクトに対してインストールするという意味です。コマンド用途のパッケージはg, それ以外のものはプロジェクト毎に--save-devオプションをつけておくのがよいでしょう。

プロジェクトの作成

 インストールしたgeneratorのgenerator-*以降を以下のようにコマンド入力すると雛形が作成されます。

$ yo jadestyl

-----以下 実行結果-----
     _-----_
    |       |    .--------------------------.
    |--(o)--|    | Welcome to the marvelous |
   `---------´   |    Jadestyl generator!   |
    ( _´U`_ )    '--------------------------'
    /___A___\
     |  ~  |
   __'.___.'__
 ´   `  |° ´ Y `

? What is the title of your application?: y
? Would you like jQuery ?: Yes
? Would you like add a progressbar according with the number of image in the pag? Would you like add a progressbar according with the number of image in the page ?: No
? Would you like Animate.css ?: No
? Would you like Velocity JS ?: No
? Would you like minify your html ?: No
   create bower.json
   create src\index.jade
   create src\scripts\main.js
   create src\styles\main.styl
   create package.json
identical .editorconfig
identical .gitignore
identical .bowerrc
identical .jshintrc
   create Gruntfile.js
   create README.md


I'm all done. Running bower install & npm install for you to install the required dependencies. If this fails, try running the command yourself.


bower cached        git://github.com/jquery/jquery.git#1.11.0
bower validate      1.11.0 against git://github.com/jquery/jquery.git#1.11.0
bower install       jquery#1.11.0

jquery#1.11.0 public\bower_components\jquery
npm WARN package.json y-jadestyl@0.0.0 No repository field.
npm WARN package.json grunt-contrib-connect@0.3.0 No README data
npm WARN prefer global bower@1.3.9 should be installed with -g
npm WARN prefer global grunt-cli@0.1.13 should be installed with -g
npm WARN prefer global yo@1.2.1 should be installed with -g

> yo@1.2.1 postinstall c:\users\ya-sasaki\Desktop\yo-sample\node_modules\yo
> node ./scripts/doctor

[Yeoman Doctor] Everything looks alright!

雛形を作る際いはいくつか設問があります。
今回はTitle入力とJQuery使います宣言だけしました。
出来上がったディレクトリを見てみましょう。

$ tree -I "node_modules|bower_components"
.
|-- Gruntfile.js
|-- README.md
|-- bower.json
|-- package.json
|-- public
`-- src
    |-- index.jade
    |-- scripts
    |   `-- main.js
    `-- styles
        `-- main.styl

4 directories, 7 files

srcフォルダの中にはindex.jade、main.js、main.stylがあります。
Gruntfile.js内に.coffeeを監視ビルドする設定があるのでscriptsフォルダ内に.coffeeのスクリプトを置くと何かしかのタイミングでコンパイルされます。

ローカルサーバの実行

 サンプルプロジェクトのトップディレクトリで以下のコマンドを実行しましょう。
ローカルサーバの実行に成功するとパソコンのデフォルトブラウザが勝手に立ち上がり、諸ファイルのコンパイル後の結果が確認できます。
上手く起動できない人はおそらくローカルポート80が既に利用済です。Gruntfile.jsに記載されているローカルサーバのポートを8000等の適当な数値に変更しましょう。

$ grunt server
Running "concurrent:compile" (concurrent) task <- コンパイルタスク動くよー

Running "copy:src" (copy) task <- まずはコピーして
Copied 1 files

Done, without errors.

Running "stylus:src" (stylus) task <- stylusのコンパイル
File public\styles\main.css created. <- できた

Done, without errors.

Running "jade:src" (jade) task <- jadeのコンパイル
File "public/index.html" created. <- できた

Done, without errors.

Running "coffee:src" (coffee) task <- Coffeeのコンパイル(何もない)

Done, without errors.

Running "concurrent:server" (concurrent) task <- サーバタスクを起動
Running "watch:copy" (watch) task
Waiting...Running "watch:coffee" (watch) task <- coffeeの変更を監視
Waiting...Running "open:server" (open) task <- 指定のurlでブラウザを起動

Done, without errors.


Running "watch:jade" (watch) task <- jadeの変更を監視
Waiting...Running "watch:public" (watch) task
Waiting...Running "connect:server" (connect) task <- ローカルサーバに接続
Waiting forever...
Started connect web server on localhost:8000. <- 8000でlisten
Running "watch:stylus" (watch) task <- stylusの変更を監視
Waiting...

以下はserverタスクを実行後のディレクトリ

$ tree -I "node_modules|bower_components"
.
|-- Gruntfile.js
|-- README.md
|-- bower.json
|-- package.json
|-- public // コンパイル後のファイル
|   |-- index.html
|   |-- scripts
|   |   `-- main.js
|   `-- styles
|       `-- main.css
`-- src
    |-- index.jade
    |-- scripts
    |   `-- main.js
    `-- styles
        `-- main.styl

どうやらデフォルトのserverタスクは最初のコンパイルとファイルの変更監視まで自動でやってくれるみたいです。
Gruntfile.jsを読んでみましょう。
AntやGradleかじった人なら説明不要でしょうが、なんだそれという人のためにコメントいれながら補足します。
難しくないので抵抗持たずに読みましょう。これがわかったら半分終わったようなものです。

// Generated on 2014-09-08 using generator-jadestyl v0.2.4

module.exports = function(grunt) {

  var config = {
    jade: { // jadeのコンパイル
      src: {
        files: [{
          expand: true,
          cwd: 'src/', // srcの対象ディレクトリ
          src: '**/*.jade', // jadeに該当するフォルダ、ファイルパターン
          dest: 'public/', // コンパイル先
          ext: '.html' // コンパイル後のファイル拡張子
        }],
        options: {
          pretty: true // trueだとindent整形、falseだと圧縮かな
        }
      }
    },
    stylus: { // stylusも基本一緒
      src: {
        files: [{
          expand: true,
          cwd: 'src/styles/',
          src: '**/*.styl',
          dest: 'public/styles/',
          ext: '.css'
        }],
        options: {
          compress: false
        }
      }
    },
    coffee: { // coffeeも基本一緒
      src: {
        files: [{
          expand: true,
          cwd: 'src/scripts/',
          src: '**/*.coffee',
          dest: 'public/scripts/',
          ext: '.js'
        }]
      }
    },
    copy: { // コンパイル不要のjsはそのままpublicに移すってこと
      src: {
        files: [{
          expand: true,
          cwd: 'src/',
          src: [
            'scripts/*.js'
          ],
          dest: 'public/'
        }]
      }
    },
    watch: { // jadeの変更を監視するタスク
      jade: {
        files: 'src/*.jade', // 変更されたら
        tasks: 'jade' // コンパイル
      },
      stylus: { // stylus変更監視
        files: 'src/styles/*.styl',
        tasks: 'stylus'
      },
      coffee: { // coffee変更監視
        files: '**/*.coffee',
        tasks: 'coffee'
      },
      copy: { // 
        files: [ // 変更されたら
          'src/scripts/*.js', 
          'src/*.jade', // これあっても意味なくね?
          'src/scripts/*.coffee', // これあっても意味なくね?
          'src/styles/*.styl' // これあっても意味なくね?
        ],
        tasks: 'copy:src' // publicに移す
      },
      public: {
        files: [ // ここのファイルが変更されたら
          'public/**/*',
          '!public/bower_components/**/*'
        ],
        options: {
          livereload: 35729 // ライブリロードする。マジか!?ほれるわ
        }
      }
    },
    connect: {
      server: { // ローカルサーバの定義
        options: {
          port: 8000, // 8000でlistenするよ
          hostname: '*', // Remove this line if you only want the server available locally
          base: 'public', // DocumentRootってやつ
          keepalive: true, // keepAlive設定、どっちでも
          middleware: function(connect, options) {
            return [
              require('connect-livereload')({
                port: config.watch.public.options.livereload
              }),
              connect.static(options.base)
            ];
          }
        }
      }
    },
    open: {
      server: {
        path: 'http://localhost:8000' // ブラウザのurl
      }
    },
    concurrent: {
      compile: { // コンパイルタスクには
        tasks: [ // この中のタスクが含まれる
          'jade',
          'stylus',
          'coffee',
          'copy'
        ],
        options: {
          logConcurrentOutput: false
        }
      },
      server: { // serverタスクには
        tasks: [ // 以下省略
          'open',
          'watch:jade',
          'watch:stylus',
          'watch:coffee',
          'watch:copy',
          'watch:public',
          'connect'
        ],
        options: {
          logConcurrentOutput: true
        }
      }
    },
    useminPrepare: { // jsとかcssを一つにまとめる際に内容を確認する
      html: 'public/index.html', // まとめたjs,cssの適用先
      options: {
        dest: 'public' // まとめたjs,cssの格納先
      }
    },
    usemin: { // まとめたjs,cssの適用先
      html: 'public/index.html'
    },
  uncss: { // そのページで使っているcssをひとまとめにする
    dist: {
      files: {
        'public/styles/styles.css': ['public/index.html']
      }
    }
  },
  cssmin: { // cssを最適化する
      after: {
        options: {
          keepSpecialComments: '0'
        },
        files: {
          'public/styles/styles.css': ['public/styles/styles.css']
        }
      }
    }

  };

  grunt.initConfig(config); // タスクの定義を登録

  // Load all Grunt tasks
  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
  // $gruntのみで実行したときはcompileに加え、最適化のタスクを動かす
  grunt.registerTask('default', ['concurrent:compile', 'useminPrepare', 'concat', 'uglify', 'uncss', 'cssmin:after', 'usemin']);
  // $grunt server したらcompile + サーバの立ち上げと各種ファイルの監視をする
  grunt.registerTask('server', ['concurrent:compile', 'concurrent:server']);
};

jade,stylus,coffeescriptはこれで一通り試せるようになりました。

それぞれの構文を覚えたい人はググって頑張ってください(ここでは簡単な構文の説明とかはしません)

次回はサードパーティのライブラリをbowerでパッケージ管理してみたり、Gitを使ったプロジェクト共有について書くか、もしくはjade, stylus, coffeeのさわり的なところを書くか。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away