14
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AngularJS開発のフォルダ構成

Posted at

AngularJS開発でフォルダ構成をどうするか悩んだのでまとめてみました。
さんざん語られている話題ではありますが。。

#部品単位
こちらなどで紹介いただいている
yeomanを使用するとこんな感じ。

yeoman
│  bower.json
│  Gruntfile.js
│  package.json
│  
├─app
│  │  404.html
│  │  bower.json
│  │  favicon.ico
│  │  index.html
│  │  robots.txt
│  ├─bower_components
│  ├─images
│  ├─scripts
│  │  │  app.js
│  │  │  
│  │  └─controllers
│  │          about.js
│  │          main.js
│  │          
│  ├─styles
│  │      main.css
│  │      
│  └─views
│          about.html
│          main.html
…

コントローラやテンプレートと部品ごとに分割しています。
スッキリしているし、フォルダの中が同じ部品だとわかっているので、後々置換などが発生しても楽そうです。

#ユースケース単位
Mastering Web Application Development with AngularJS(Kindle安い!2014/11/5で1,801円)で紹介されているパターンだとこんな感じ。ちょっと長めに引用。
ソースはこちらです。

usecase
├─client
│  │  .gitignore
│  │  gruntFile.js
│  │  package.json
│  │  
│  ├─dist
│  ├─src
│  │  │  index.html
│  │  │  
│  │  ├─app
│  │  │  │  app.js
│  │  │  │  header.tpl.html
│  │  │  │  notifications.tpl.html
│  │  │  │  
│  │  │  ├─admin
│  │  │  │  │  admin.js
│  │  │  │  │  
│  │  │  │  ├─projects
│  │  │  │  │      admin-projects.js
│  │  │  │  │      projects-edit.tpl.html
│  │  │  │  │      projects-list.tpl.html
│  │  │  │  │      
│  │  │  │  └─users
│  │  │  │          admin-users-edit.js
│  │  │  │          admin-users-list.js
│  │  │  │          admin-users.js
│  │  │  │          uniqueEmail.js
│  │  │  │          users-edit.tpl.html
│  │  │  │          users-list.tpl.html
│  │  │  │          validateEquals.js
│  │  │  │          
│  │  │  ├─dashboard
│  │  │  │      dashboard.js
│  │  │  │      dashboard.tpl.html
│  │  │  │      
│  │  │  ├─projects
│  │  │  │  │  projects-list.tpl.html
│  │  │  │  │  projects.js
│  │  │  │  │  
│  │  │  │  ├─productbacklog
│  │  │  │  │      productbacklog-edit.tpl.html
│  │  │  │  │      productbacklog-list.tpl.html
│  │  │  │  │      productbacklog.js
│  │  │  │  │      
│  │  │  │  └─sprints
│  │  │  │      │  sprints-edit.tpl.html
│  │  │  │      │  sprints-list.tpl.html
│  │  │  │      │  sprints.js
│  │  │  │      │  
│  │  │  │      └─tasks
│  │  │  │              tasks-edit.tpl.html
│  │  │  │              tasks-list.tpl.html
│  │  │  │              tasks.js
│  │  │  │              
│  │  │  └─projectsinfo
│  │  │          list.tpl.html
│  │  │          projectsinfo.js
│  │  │          
│  │  ├─assets
│  │  │  │  favicon.ico
│  │  │  │  
│  │  │  └─img
│  │  │          glyphicons-halflings-white.png
│  │  │          glyphicons-halflings.png
│  │  │          spinner.gif
│  │  │          
│  │  ├─common
│  │  │  ├─directives
│  │  │  │  │  gravatar.js
│  │  │  │  │  modal.js
│  │  │  │  │  
│  │  │  │  └─crud
│  │  │  │          crud.js
│  │  │  │          crudButtons.js
│  │  │  │          edit.js
│  │  │  │          
│  │  │  ├─resources
│  │  │  │      backlog.js
│  │  │  │      projects.js
│  │  │  │      sprints.js
│  │  │  │      tasks.js
│  │  │  │      users.js
│  │  │  │      
│  │  │  ├─security
│  │  │  │  │  authorization.js
│  │  │  │  │  index.js
│  │  │  │  │  interceptor.js
│  │  │  │  │  retryQueue.js
│  │  │  │  │  security.js
│  │  │  │  │  
│  │  │  │  └─login
│  │  │  │          form.tpl.html
│  │  │  │          login.js
│  │  │  │          LoginFormController.js
│  │  │  │          toolbar.js
│  │  │  │          toolbar.tpl.html
│  │  │  │          
│  │  │  └─services
│  │  │          breadcrumbs.js
│  │  │          crud.js
│  │  │          crudRouteProvider.js
│  │  │          exceptionHandler.js
│  │  │          httpRequestTracker.js
│  │  │          i18nNotifications.js
│  │  │          localizedMessages.js
│  │  │          notifications.js
│  │  │          
│  │  └─less
│  │          stylesheet.less
│  │          variables.less

コントローラとテンプレートが同一フォルダで、サービスやディレクティブは共通部品として配置されています。
確かに、コントローラとテンプレートが一緒のほうが開発しやすいですね。
上記書籍にはこの構成について、結構なページ数の解説があって、これだけでも良心的だなあと思います。

上記構成でのgruntoの抜粋を以下に。

gruntFile.js
module.exports = function (grunt) {

~~

  // Project configuration.
  grunt.initConfig({
    distdir: 'dist',
    pkg: grunt.file.readJSON('package.json'),
    banner:
    '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' +
    '<%= pkg.homepage ? " * " + pkg.homepage + "\\n" : "" %>' +
    ' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>;\n' +
    ' * Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %>\n */\n',
    src: {
      js: ['src/**/*.js'],
      jsTpl: ['<%= distdir %>/templates/**/*.js'],
      specs: ['test/**/*.spec.js'],
      scenarios: ['test/**/*.scenario.js'],
      html: ['src/index.html'],
      tpl: {
        app: ['src/app/**/*.tpl.html'],
        common: ['src/common/**/*.tpl.html']
      },
      less: ['src/less/stylesheet.less'], // recess:build doesn't accept ** in its file patterns
      lessWatch: ['src/less/**/*.less']
    },

~~

    html2js: {
      app: {
        options: {
          base: 'src/app'
        },
        src: ['<%= src.tpl.app %>'],
        dest: '<%= distdir %>/templates/app.js',
        module: 'templates.app'
      },
      common: {
        options: {
          base: 'src/common'
        },
        src: ['<%= src.tpl.common %>'],
        dest: '<%= distdir %>/templates/common.js',
        module: 'templates.common'
      }
    },
    concat:{
      dist:{
        options: {
          banner: "<%= banner %>"
        },
        src:['<%= src.js %>', '<%= src.jsTpl %>'],
        dest:'<%= distdir %>/<%= pkg.name %>.js'
      },
      index: {
        src: ['src/index.html'],
        dest: '<%= distdir %>/index.html',
        options: {
          process: true
        }
      },
~~

    },

~~

html2jsで「src/app/**/*.tpl.html」、「src/common/**/*.tpl.html」配下のhtmlをJS化、
モジュール単位のJSファイルをconcatで「<%= pkg.name %>.js」にまとめています。
AngularJSで書かれている分にはファイル結合の順序は問われないと。

index.htmlのビルド前後の差分は以下。

index.html(ビルド前)
<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
  <link rel="stylesheet" type="text/css" href="/static/<%= grunt.config.get('pkg.name') %>.css"/>
  <script type="text/javascript" src="/static/jquery.js"></script>
  <script type="text/javascript" src="/static/angular.js"></script>
  <script type="text/javascript" src="/static/mongolab.js"></script>
  <script type="text/javascript" src="/static/bootstrap.js"></script>
  <script type="text/javascript" src="/static/<%= grunt.config.get('pkg.name') %>.js"></script>
</head>
~略~
index.html(ビルド後)
<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
  <link rel="stylesheet" type="text/css" href=/angular-app.css"/>
  <script type="text/javascript" src="jquery.js"></script>
  <script type="text/javascript" src="angular.js"></script>
  <script type="text/javascript" src="mongolab.js"></script>
  <script type="text/javascript" src="bootstrap.js"></script>
  <script type="text/javascript" src="angular-app.js"></script>
</head>
~略~

どちらもよいですが、個人的にはユースケース単位で分割したほうが好みでした。

14
13
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
14
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?