LoginSignup
23
23

More than 5 years have passed since last update.

サーバー/クライアント両方を javascript(coffee-script)で書くときのビルド設定

Last updated at Posted at 2013-03-03

サーバー/クライアントを両方jsないしcoffeeで書くときの、ディレクトリ構造や、Gruntfileのサンプルがあまりみつからなかったので自分で実施しはじめている内容をまとめてみる。

ディレクトリ構造は以下のようにした。
coffee-scriptのソースは、src/ に全て入れ、client/ server/ でディレクトリを分ける。

.
├── Gruntfile.coffee
├── README.md
├── app.coffee
├── component.json
├── lib
├── package.json
├── public
│   ├── css
│   ├── img
│   └── js
├── src
│   ├── client
│   └── server
└── views

分けておくと、Gruntfileで以下のようにclientとserverでビルドターゲットを分けることがけっこう簡単にできる。

module.exports = (grunt) ->
  grunt.initConfig
    pkg: grunt.file.readJSON('package.json')

    coffee:
      server:
        files: [
          {
            'app.js': 'app.coffee'
          }, {
            expand: true,
            cwd: 'src/server',
            src: ['**/*.coffee'],
            dest: 'lib/',
            ext: '.js'
          }
        ]
      client:
        options:
          bare: false
        files: [
          {
            expand: true,
            cwd: 'src/client',
            src: ['*.coffee'],
            dest: 'public/js/lib/',
            ext: '.js'
          }
        ]

    concat:
      options:
        separator: ";"
      vendor:
        src: [
          'components/underscore/underscore-min.js',
          'components/jquery/jquery.min.js',
          'components/backbone/backbone-min.js'
          ],
        dest: "public/js/vendor.js"
      app:
        src: ["public/js/lib/**/*.js"]
        dest: "public/js/app.js"

    uglify:
      options:
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
      app:
        files:
          'public/js/app.min.js': ['<%= concat.app.dest %>']

    watch:
      src_server:
        files: ['app.coffee', 'src/server/**/*.coffee']
        tasks: ['coffee:server']
      src_client:
        files: ['src/client/**/*.coffee']
        tasks: ['coffee:client', 'concat:app']

  grunt.loadNpmTasks('grunt-contrib-uglify')
  grunt.loadNpmTasks('grunt-contrib-coffee')
  grunt.loadNpmTasks('grunt-contrib-concat')
  grunt.loadNpmTasks('grunt-contrib-watch')

  grunt.registerTask 'default', ['coffee', 'concat', 'uglify']
  grunt.registerTask 'server', ['coffee:server']
  grunt.registerTask 'client', ['coffee:client', 'concat:app']

watchもターゲットも分けておくと、クライアントのソースを保存したときにサーバもコンパイルされるなどの無意味なタスクが走らなくなるので良い。

ちなみに自分は、人の5倍くらいの回数ファイルを保存するので、watchは使ってない。
gruntは、rakeとかとちがって、プロジェクトのサブディレクトリからでもgruntコマンドを叩けるので、自分でemacsからタスクを叩けるように設定している。

(defun grunt-for-build ()
  "coffee-script compile for grunt task"
  (interactive)
  (let ((cur-dir (expand-file-name default-directory)))
    (compile 
     (if (string-match "/\\(server\\|client\\)s?/" cur-dir)
         (concat "grunt " (match-string 1 cur-dir))
       "grunt"))))

(define-key coffee-mode-map (kbd "C-c C-l") #'grunt-for-build)

こちらも、クライアント/サーバどっちのディレクトリに居るかによって、ターゲットを分けて実行している。

23
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
23