angular-fullstack / generator-angular-fullstack

Yeoman generator for an Angular app with an Express server
https://awk34.gitbook.io/generator-angular-fullstack
6.12k stars 1.24k forks source link

2.0.0: Not able to generate anything beyond app init #279

Closed chanced closed 10 years ago

chanced commented 10 years ago

I'm not able to generate anything beyond the initialization.

For example, if I run yo ng-component:directive something then the following output occurs:

You're using the fantastic NgComponent generator.

Initializing yo-rc.json configuration.

Type `yo ng-component --help` for a list of available generators.

It also changes my .yo-rc.jsonfrom

{
  "generator-angular-fullstack": {
    "insertRoutes": "true",
    "registerRoutesFile": "server/routes.js",
    "routesNeedle": "// Insert routes below",
    "insertSockets": "true",
    "registerSocketsFile": "server/config/socketio.js",
    "socketsNeedle": "// Insert sockets below",
    "filters": {
      "js": true,
      "html": true,
      "sass": true,
      "uirouter": true,
      "mongoose": true,
      "auth": true,
      "googleAuth": true,
      "facebookAuth": true,
      "twitterAuth": true
    }
  },
  "generator-ng-component": {
    "routeDirectory": "client/app/",
    "directiveDirectory": "client/app/",
    "filterDirectory": "client/app/",
    "serviceDirectory": "client/app/",
    "basePath": "client",
    "filters": [
      "uirouter"
    ],
    "extensions": [
      "js",
      "html",
      "scss"
    ]
  }
}

to

{
  "generator-angular-fullstack": {
    "insertRoutes": "true",
    "registerRoutesFile": "server/routes.js",
    "routesNeedle": "// Insert routes below",
    "insertSockets": "true",
    "registerSocketsFile": "server/config/socketio.js",
    "socketsNeedle": "// Insert sockets below",
    "filters": {
      "js": true,
      "html": true,
      "sass": true,
      "uirouter": true,
      "mongoose": true,
      "auth": true,
      "googleAuth": true,
      "facebookAuth": true,
      "twitterAuth": true
    }
  },
  "generator-ng-component": {
    "routeDirectory": "app/components/",
    "directiveDirectory": "app/components/",
    "filterDirectory": "app/components/",
    "serviceDirectory": "app/components/",
    "basePath": "app",
    "filters": [
      "uirouter"
    ],
    "extensions": [
      ".js",
      ".html",
      ".scss"
    ]
  }
}

Info

yo version : 1.2.0 $NODE_PATH : /Users/chance/bin:/usr/local/bin:/Users/chance/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

console.log(process.platform, process.versions) :

darwin { http_parser: '1.0',
  node: '0.10.29',
  v8: '3.14.5.9',
  ares: '1.9.0-DEV',
  uv: '0.10.27',
  zlib: '1.2.3',
  modules: '11',
  openssl: '1.0.1h' }

Gruntfile

'use strict';

module.exports = function (grunt) {

  // Load grunt tasks automatically, when needed
  require('jit-grunt')(grunt, {
    express: 'grunt-express-server',
    useminPrepare: 'grunt-usemin',
    ngtemplates: 'grunt-angular-templates',
    cdnify: 'grunt-google-cdn',
    protractor: 'grunt-protractor-runner',
    injector: 'grunt-asset-injector'
  });

  // Time how long tasks take. Can help when optimizing build times
  require('time-grunt')(grunt);

  // Define the configuration for all the tasks
  grunt.initConfig({

    // Project settings
    yeoman: {
      // configurable paths
      client: require('./bower.json').appPath || 'client',
      dist: 'dist'
    },
    express: {
      options: {
        port: process.env.PORT || 9000
      },
      dev: {
        options: {
          script: 'server/app.js',
          debug: true
        }
      },
      prod: {
        options: {
          script: 'dist/server/app.js'
        }
      }
    },
    open: {
      server: {
        url: 'http://localhost:<%= express.options.port %>'
      }
    },
    watch: {
      injectJS: {
        files: [
          '<%= yeoman.client %>/{app,components}/**/*.js',
          '!<%= yeoman.client %>/{app,components}/**/*.spec.js',
          '!<%= yeoman.client %>/{app,components}/**/*.mock.js',
          '!<%= yeoman.client %>/app/app.js'],
        tasks: ['injector:scripts']
      },
      injectCss: {
        files: [
          '<%= yeoman.client %>/{app,components}/**/*.css'
        ],
        tasks: ['injector:css']
      },
      mochaTest: {
        files: ['server/**/*.spec.js'],
        tasks: ['env:test', 'mochaTest']
      },
      jsTest: {
        files: [
          '<%= yeoman.client %>/{app,components}/**/*.spec.js',
          '<%= yeoman.client %>/{app,components}/**/*.mock.js'
        ],
        tasks: ['newer:jshint:all', 'karma']
      },
      injectSass: {
        files: [
          '<%= yeoman.client %>/{app,components}/**/*.{scss,sass}'],
        tasks: ['injector:sass']
      },
      sass: {
        files: [
          '<%= yeoman.client %>/{app,components}/**/*.{scss,sass}'],
        tasks: ['sass', 'autoprefixer']
      },
      gruntfile: {
        files: ['Gruntfile.js']
      },
      livereload: {
        files: [
          '{.tmp,<%= yeoman.client %>}/{app,components}/**/*.css',
          '{.tmp,<%= yeoman.client %>}/{app,components}/**/*.html',
          '{.tmp,<%= yeoman.client %>}/{app,components}/**/*.js',
          '!{.tmp,<%= yeoman.client %>}{app,components}/**/*.spec.js',
          '!{.tmp,<%= yeoman.client %>}/{app,components}/**/*.mock.js',
          '<%= yeoman.client %>/assets/images/{,*//*}*.{png,jpg,jpeg,gif,webp,svg}'
        ],
        options: {
          livereload: true
        }
      },
      express: {
        files: [
          'server/**/*.{js,json}'
        ],
        tasks: ['express:dev', 'wait'],
        options: {
          livereload: true,
          nospawn: true //Without this option specified express won't be reloaded
        }
      }
    },

    // Make sure code styles are up to par and there are no obvious mistakes
    jshint: {
      options: {
        jshintrc: '<%= yeoman.client %>/.jshintrc',
        reporter: require('jshint-stylish')
      },
      server: {
        options: {
          jshintrc: 'server/.jshintrc'
        },
        src: [ 'server/{,*/}*.js']
      },
      all: [
        '<%= yeoman.client %>/{app,components}/**/*.js',
        '!<%= yeoman.client %>/{app,components}/**/*.spec.js',
        '!<%= yeoman.client %>/{app,components}/**/*.mock.js'
      ],
      test: {
        src: [
          '<%= yeoman.client %>/{app,components}/**/*.spec.js',
          '<%= yeoman.client %>/{app,components}/**/*.mock.js'
        ]
      }
    },

    // Empties folders to start fresh
    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            '.tmp',
            '<%= yeoman.dist %>/*',
            '!<%= yeoman.dist %>/.git*',
            '!<%= yeoman.dist %>/.openshift',
            '!<%= yeoman.dist %>/Procfile'
          ]
        }]
      },
      server: '.tmp'
    },

    // Add vendor prefixed styles
    autoprefixer: {
      options: {
        browsers: ['last 1 version']
      },
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/',
          src: '{,*/}*.css',
          dest: '.tmp/'
        }]
      }
    },

    // Debugging with node inspector
    'node-inspector': {
      custom: {
        options: {
          'web-host': 'localhost'
        }
      }
    },

    // Use nodemon to run server in debug mode with an initial breakpoint
    nodemon: {
      debug: {
        script: 'server/app.js',
        options: {
          nodeArgs: ['--debug-brk'],
          env: {
            PORT: process.env.PORT || 9000
          },
          callback: function (nodemon) {
            nodemon.on('log', function (event) {
              console.log(event.colour);
            });

            // opens browser on initial server start
            nodemon.on('config:update', function () {
              setTimeout(function () {
                require('open')('http://localhost:8080/debug?port=5858');
              }, 500);
            });
          }
        }
      }
    },

    // Automatically inject Bower components into the app
    bowerInstall: {
      target: {
        src: '<%= yeoman.client %>/index.html',
        ignorePath: '<%= yeoman.client %>/',
        exclude: [/bootstrap-sass-official/, /bootstrap.js/]
      }
    },

    // Renames files for browser caching purposes
    rev: {
      dist: {
        files: {
          src: [
            '<%= yeoman.dist %>/public/{,*/}*.js',
            '<%= yeoman.dist %>/public/{,*/}*.css',
            '<%= yeoman.dist %>/public/assets/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
            '<%= yeoman.dist %>/public/assets/fonts/*'
          ]
        }
      }
    },

    // Reads HTML for usemin blocks to enable smart builds that automatically
    // concat, minify and revision files. Creates configurations in memory so
    // additional tasks can operate on them
    useminPrepare: {
      html: ['<%= yeoman.client %>/index.html'],
      options: {
        dest: '<%= yeoman.dist %>/public'
      }
    },

    // Performs rewrites based on rev and the useminPrepare configuration
    usemin: {
      html: ['<%= yeoman.dist %>/public/{,*/}*.html'],
      css: ['<%= yeoman.dist %>/public/{,*/}*.css'],
      js: ['<%= yeoman.dist %>/public/{,*/}*.js'],
      options: {
        assetsDirs: [
          '<%= yeoman.dist %>/public',
          '<%= yeoman.dist %>/public/assets/images'
        ],
        // This is so we update image references in our ng-templates
        patterns: {
          js: [
            [/(assets\/images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm, 'Update the JS to reference our revved images']
          ]
        }
      }
    },

    // The following *-min tasks produce minified files in the dist folder
    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.client %>/assets/images',
          src: '{,*/}*.{png,jpg,jpeg,gif}',
          dest: '<%= yeoman.dist %>/public/assets/images'
        }]
      }
    },

    svgmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.client %>/assets/images',
          src: '{,*/}*.svg',
          dest: '<%= yeoman.dist %>/public/assets/images'
        }]
      }
    },

    // Allow the use of non-minsafe AngularJS files. Automatically makes it
    // minsafe compatible so Uglify does not destroy the ng references
    ngmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/concat',
          src: '*/**.js',
          dest: '.tmp/concat'
        }]
      }
    },

    // Package all the html partials into a single javascript payload
    ngtemplates: {
      options: {
        // This should be the name of your apps angular module
        module: require('./bower.json').name + 'App',
        htmlmin: {
          collapseBooleanAttributes: true,
          collapseWhitespace: true,
          removeAttributeQuotes: true,
          removeEmptyAttributes: true,
          removeRedundantAttributes: true,
          removeScriptTypeAttributes: true,
          removeStyleLinkTypeAttributes: true
        },
        usemin: 'app/app.js'
      },
      main: {
        cwd: '<%= yeoman.client %>',
        src: ['{app,components}/**/*.html'],
        dest: '.tmp/templates.js'
      },
      tmp: {
        cwd: '.tmp',
        src: ['{app,components}/**/*.html'],
        dest: '.tmp/tmp-templates.js'
      }
    },

    // Replace Google CDN references
    cdnify: {
      dist: {
        html: ['<%= yeoman.dist %>/*.html']
      }
    },

    // Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= yeoman.client %>',
          dest: '<%= yeoman.dist %>/public',
          src: [
            '*.{ico,png,txt}',
            '.htaccess',
            'bower_components/**/*',
            'assets/images/{,*/}*.{webp}',
            'assets/fonts/**/*',
            'index.html'
          ]
        }, {
          expand: true,
          cwd: '.tmp/images',
          dest: '<%= yeoman.dist %>/public/assets/images',
          src: ['generated/*']
        }, {
          expand: true,
          dest: '<%= yeoman.dist %>',
          src: [
            'package.json',
            'server/**/*'
          ]
        }]
      },
      styles: {
        expand: true,
        cwd: '<%= yeoman.client %>',
        dest: '.tmp/',
        src: ['{app,components}/**/*.css']
      }
    },

    // Run some tasks in parallel to speed up the build process
    concurrent: {
      server: [
        'sass',
      ],
      test: [
        'sass',
      ],
      debug: {
        tasks: [
          'nodemon',
          'node-inspector'
        ],
        options: {
          logConcurrentOutput: true
        }
      },
      dist: [
        'sass',
        'imagemin',
        'svgmin'
      ]
    },

    // Test settings
    karma: {
      unit: {
        configFile: 'karma.conf.js',
        singleRun: true
      }
    },

    mochaTest: {
      options: {
        reporter: 'spec'
      },
      src: ['server/**/*.spec.js']
    },

    protractor: {
      options: {
        configFile: 'protractor.conf.js'
      },
      chrome: {
        options: {
          args: {
            browser: 'chrome'
          }
        }
      }
    },

    env: {
      test: {
        NODE_ENV: 'test'
      },
      prod: {
        NODE_ENV: 'production'
      },
      all: require('./server/config/local.env')
    },

    // Compiles Sass to CSS
    sass: {
      server: {
        options: {
          loadPath: [
            '<%= yeoman.client %>/bower_components',
            '<%= yeoman.client %>/app',
            '<%= yeoman.client %>/components'
          ],
          compass: false
        },
        files: {
          '.tmp/app/app.css' : '<%= yeoman.client %>/app/app.scss'
        }
      }
    },

    injector: {
      options: {

      },
      // Inject application script files into index.html (doesn't include bower)
      scripts: {
        options: {
          transform: function(filePath) {
            filePath = filePath.replace('/client/', '');
            filePath = filePath.replace('/.tmp/', '');
            return '<script src="' + filePath + '"></script>';
          },
          starttag: '<!-- injector:js -->',
          endtag: '<!-- endinjector -->'
        },
        files: {
          '<%= yeoman.client %>/index.html': [
              ['{.tmp,<%= yeoman.client %>}/{app,components}/**/*.js',
               '!{.tmp,<%= yeoman.client %>}/app/app.js',
               '!{.tmp,<%= yeoman.client %>}/{app,components}/**/*.spec.js',
               '!{.tmp,<%= yeoman.client %>}/{app,components}/**/*.mock.js']
            ]
        }
      },

      // Inject component scss into app.scss
      sass: {
        options: {
          transform: function(filePath) {
            filePath = filePath.replace('/client/app/', '');
            filePath = filePath.replace('/client/components/', '');
            return '@import \'' + filePath + '\';';
          },
          starttag: '// injector',
          endtag: '// endinjector'
        },
        files: {
          '<%= yeoman.client %>/app/app.scss': [
            '<%= yeoman.client %>/{app,components}/**/*.{scss,sass}',
            '!<%= yeoman.client %>/app/app.{scss,sass}'
          ]
        }
      },

      // Inject component css into index.html
      css: {
        options: {
          transform: function(filePath) {
            filePath = filePath.replace('/client/', '');
            filePath = filePath.replace('/.tmp/', '');
            return '<link rel="stylesheet" href="' + filePath + '">';
          },
          starttag: '<!-- injector:css -->',
          endtag: '<!-- endinjector -->'
        },
        files: {
          '<%= yeoman.client %>/index.html': [
            '<%= yeoman.client %>/{app,components}/**/*.css'
          ]
        }
      }
    },
  });

  // Used for delaying livereload until after server has restarted
  grunt.registerTask('wait', function () {
    grunt.log.ok('Waiting for server reload...');

    var done = this.async();

    setTimeout(function () {
      grunt.log.writeln('Done waiting!');
      done();
    }, 500);
  });

  grunt.registerTask('express-keepalive', 'Keep grunt running', function() {
    this.async();
  });

  grunt.registerTask('serve', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['build', 'env:all', 'env:prod', 'express:prod', 'open', 'express-keepalive']);
    }

    if (target === 'debug') {
      return grunt.task.run([
        'clean:server',
        'env:all',
        'injector:sass', 
        'concurrent:server',
        'injector',
        'bowerInstall',
        'autoprefixer',
        'concurrent:debug'
      ]);
    }

    grunt.task.run([
      'clean:server',
      'env:all',
      'injector:sass', 
      'concurrent:server',
      'injector',
      'bowerInstall',
      'autoprefixer',
      'express:dev',
      'wait',
      'open',
      'watch'
    ]);
  });

  grunt.registerTask('server', function () {
    grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
    grunt.task.run(['serve']);
  });

  grunt.registerTask('test', function(target) {
    if (target === 'server') {
      return grunt.task.run([
        'env:all',
        'env:test',
        'mochaTest'
      ]);
    }

    else if (target === 'client') {
      return grunt.task.run([
        'clean:server',
        'env:all',
        'injector:sass', 
        'concurrent:test',
        'injector',
        'autoprefixer',
        'karma'
      ]);
    }

    else if (target === 'e2e') {
      return grunt.task.run([
        'clean:server',
        'env:all',
        'env:test',
        'injector:sass', 
        'concurrent:test',
        'injector',
        'bowerInstall',
        'autoprefixer',
        'express:dev',
        'protractor'
      ]);
    }

    else grunt.task.run([
      'test:server',
      'test:client'
    ]);
  });

  grunt.registerTask('build', [
    'clean:dist',
    'injector:sass', 
    'concurrent:dist',
    'injector',
    'bowerInstall',
    'useminPrepare',
    'autoprefixer',
    'ngtemplates',
    'concat',
    'ngmin',
    'copy:dist',
    'cdnify',
    'cssmin',
    'uglify',
    'rev',
    'usemin'
  ]);

  grunt.registerTask('default', [
    'newer:jshint',
    'test',
    'build'
  ]);
};
DaftMonk commented 10 years ago

This works fine for me. Are you sure you typed the sub generator exactly as you wrote it (yo ng-component:directive something)?

chanced commented 10 years ago

Yea.

$  yo ng-component:directive something
You're using the fantastic NgComponent generator.

Initializing yo-rc.json configuration.

Type `yo ng-component --help` for a list of available generators.
chanced commented 10 years ago

I'll generate a new project in a few and try again when I get to a breaking point.

kosz commented 10 years ago

I'm experiencing the same issue. I am going to try soon on another dev machine with fresh installs.

I also feel there's a lack of documentation here. I've spent some 30 minutes trying to fish the right information out of the sources available, with little success.

I've looked in the generators folder in the angular-fullstack-generator, and the readme there said those are only deprecated generators. There seems to be little notes on the ng-component features, the readme says little, then when running ng-component --help only a few generators are listed, which don't work, just as explained in this ticket by chanced. I know it's open source, and I'd love to help, ( which is why i'm attempting to test ), but so far it's been tough.

The readme file for angular-generator-fullstack, in the 2.0.0 branch, is also outdated (listing the deprecated sub generators)

A bit tough so far, but i'll keep on digging through it.

kosz commented 10 years ago

so to confirm, here is my console output when trying to use ng-component :

$ yo ng-component --help
Usage:
  yo ng-component [options]

Options:
  -h,   --help  # Print generator's options and usage  Default: false

Description:
    Generators for AngularJS components

Available Generators:
    yo ng-component:route [name]
    yo ng-component:directive [name]
    yo ng-component:service [name]
    yo ng-component:factory [name]
    yo ng-component:filter [name]
$ yo ng-component:route todo
You're using the fantastic NgComponent generator.

Initializing yo-rc.json configuration.

Type `yo ng-component --help` for a list of available generators.

First off it's confusing that when running --help, only a few options are listed. What about controllers ? views ? server related subgenerators like routes, models, controllers ?

Secondly ... I can't use the generators. any attempt gives me that friendly message which does nothing

Also confusing is that the message says yo-rc.json , when in fact the file is .yo-rc.json

Maybe it's relevant to mention that i'm not using a ng-component snapshot, instead i've installed it using :

npm install -g generator-ng-component
DaftMonk commented 10 years ago

@kosz I understand your frustration with the lack of documentation, and I've been holding off release until I can get it written up, and clean out the outdated/incorrect information.

So the reason the generators folder in angular fullstack only contains deprecated generators is because I didn't want those commands to just fail with no explanation. For yeoman to register those deprecated generators, they need to be either in the root of the app, or in the generators folder. I decided to put all deprecated sub generators in the generators folder, and leave all working generators in the root of the app.

Have you tried running the ng-component sub-generators through angular-fullstack? That's how they're intended to be used, i.e, yo angular-fullstack:route blah.

kosz commented 10 years ago

@DaftMonk i'm not really frustrated about the documentation, i can understand since you're working on a new release, but i just wanted to point out that it makes testing of 2.0 difficult, which is what i am trying to do.

In fact the lack of the documentation seems not to be a problem here at all, since based on what you just said above, the same sub generators commands should work. The problem is that for some of us they don't work right now.

Tried everything so far. Last pull was 10 minutes ago.

newerapp$ yo angular-fullstack:route blah
You're using the fantastic NgComponent generator.

Initializing yo-rc.json configuration.

Type `yo ng-component --help` for a list of available generators.
kosz commented 10 years ago

An update:

I was able to get past this problem by running npm link from a freshly cloned generator-ng-component project. Once I did that I ran into the same issue described here: https://github.com/DaftMonk/generator-ng-component/issues/1

DaftMonk commented 10 years ago

Thanks for the feedback so far kosz! I will see if I can reproduce this myself.

DaftMonk commented 10 years ago

Yep, started getting this issue when I tried using the npm version of ng-component rather than the linked version. I'm not sure why its happening yet, but now I can start debugging it. :)

DaftMonk commented 10 years ago

Pushed a new version of the 2.0 branch that fixes this.