Skip to content

Is it possible to have multiple modules within a single generated project? #737

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
benjamincharity opened this issue Aug 25, 2015 · 13 comments

Comments

@benjamincharity
Copy link

It seems like this should be simple but I can't seem to get it working for the life of me.

I want to create a parent module (app) that includes other modules as dependencies (app.admin, app.reporting, etc). However, it seems that only files which are included in the top level index.module.js are included in the served page.

The error I get is the standard not available angular error:

Uncaught Error: [$injector:modulerr] Failed to instantiate module client due to:
Error: [$injector:modulerr] Failed to instantiate module test due to:
Error: [$injector:nomod] Module 'test' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

Looking into the generated files it is clear that only the top level index.module and it's required files are being loaded.

Any ideas on this? Been using this generator for a while now with pleasure. Hope I can keep with it!

Info

Generator version: 0.12.1

.yo-rc:

{
  "generator-gulp-angular": {
    "version": "0.12.1",
    "props": {
      "angularVersion": "~1.4.0",
      "angularModules": [
        {
          "key": "animate",
          "module": "ngAnimate"
        },
        {
          "key": "touch",
          "module": "ngTouch"
        },
        {
          "key": "sanitize",
          "module": "ngSanitize"
        }
      ],
      "jQuery": {
        "key": "none"
      },
      "resource": {
        "key": "none",
        "module": null
      },
      "router": {
        "key": "ui-router",
        "module": "ui.router"
      },
      "ui": {
        "key": "none",
        "module": null
      },
      "cssPreprocessor": {
        "key": "node-sass",
        "extension": "scss"
      },
      "jsPreprocessor": {
        "key": "babel",
        "extension": "js",
        "srcExtension": "es6"
      },
      "htmlPreprocessor": {
        "key": "none",
        "extension": "html"
      },
      "bootstrapComponents": {
        "name": null,
        "version": null,
        "key": null,
        "module": null
      },
      "foundationComponents": {
        "name": null,
        "version": null,
        "key": null,
        "module": null
      },
      "paths": {
        "src": "src",
        "dist": "dist",
        "e2e": "e2e",
        "tmp": ".tmp"
      }
    }
  }
}
@sinorga
Copy link

sinorga commented Aug 29, 2015

Hi, I have the same requirement. When app become bigger, I would like to extract some sub-modules, but I don't know how to do.

@benjamincharity
Copy link
Author

@sinorga I still feel that we should be able to generate different compiled files per module.. but this is the solution I landed at to allow us to define separate modules although it is all compiled into one file.

Define a module (app/splash/):

import SplashController from './splash.controller';
import router from './splash.routes';

export default angular.module('client.splash', [
    'ngAnimate',
    'ngTouch',
    'ngSanitize',
    'ui.router',
])
    .config(router)
    .controller('SplashController', SplashController)
;

Then import it for use in my primary app (index.module.js):

import constants from './components/constants/env.constant';
import indexConfig from './index.config';
import routerConfig from './index.route';
import runBlock from './index.run';

// Modules
import splash from './splash';
// ... etc

angular.module('client', [
    'ngAnimate',
    'ngTouch',
    'ngSanitize',
    'ui.router',
    'angularMoment',
    'client.splash',
    // .... etc
])
    .config(indexConfig)
    .constant('ENV', constants.ENV)
    .config(routerConfig)
    .run(runBlock)
;

I'm still new to this class based approach so this may not be 100%... but it's bridging the gap for now.

@sinorga
Copy link

sinorga commented Sep 4, 2015

@benjamincharity I am new to this field too, thanks for your sharing. I tried to modify the gulp task flow to build all modules, but I think yours is much simple and straightforward by using ES6 syntax. I would try it :D Build all modules into one files is suitable for me at this moment.

@benjamincharity
Copy link
Author

Glad it's helpful. I like the separation of partitioned modules, but until we hear from someone with more knowledge (bump!) it is definitely getting us by!

@zckrs zckrs mentioned this issue Sep 9, 2015
@Swiip
Copy link
Owner

Swiip commented Sep 11, 2015

Thanks for sharing. Definitely needs to be a recipe of the generator

@zckrs
Copy link
Collaborator

zckrs commented Sep 11, 2015

Maybe the next sample app should contain a module 'layout'

@hardywu
Copy link

hardywu commented Oct 5, 2015

It seems that an extra line of splash is needed to tell the compiler not to ignore the unused module.

@4kochi
Copy link

4kochi commented Oct 15, 2015

The solution of @benjamincharity works for mw too. But as @hardywu mentioned if have to an extra line of code so the splash module is compiled

var a = splash;

Otherwise the module is ignored by the compiler. Maybe there is an option in the compiler to compile all files and modules, even if they are not used.

Anyway it would be generally great if the example app could cover this scenario. It makes a lot of sense to have a folder with angular modules which are more or less self containing. So one only have to add the module to the dependencies of the main angular app. We use this a lot to reuse modules between different projects.

@hardywu
Copy link

hardywu commented Nov 1, 2015

@4kochi Somehow, it works in one line without compiler configuration:

import './splash';

@4kochi
Copy link

4kochi commented Nov 2, 2015

Thanks @hardywu, that works for me too. But I did not found out why yet.

@sb8244
Copy link

sb8244 commented Dec 30, 2015

It works as import './splash'; because angular has its own dependency system. When you import splash, that code is inserted before the code that uses the splash module, and it all works

@vucalur
Copy link
Contributor

vucalur commented Feb 13, 2016

While importing to index.module.js works, it's still a workaround folks!
Furthermore, it doesn't prevent devs from purposelessly hunting the cause of the error before they figure out it's gulp configuration fault rather than a mistake in their app code.

Multiple modules should be handled by gulp.
My workflow works with following change:

in gulp/scripts.js (https://github.com/Swiip/generator-gulp-angular/blob/master/generators/app/templates/gulp/_scripts.js#L87):
change:
var sources = [ path.join(conf.paths.src, '/app/index.module.js') ];
to:
var sources = [ path.join(conf.paths.src, '/app/**/*.module.js') ];

You may have a different extension than js: (js|ts|coffee)

@sinorga You mentioned modifying gulp code as well. What was your change? What didn't work?
My solution might have the same flaw.

I haven't tested this modification thoroughly and I am not familiar with the code in gulp/*, so no PR from me.
It seems https://github.com/Swiip/generator-gulp-angular/blob/master/generators/app/templates/gulp/_unit-tests.js#L24 (path.join(conf.paths.tmp, '/serve/app/index.module.js')) should be changed as well.

I hope someone will pick up from here.
Cheers

@sb8244
Copy link

sb8244 commented Feb 13, 2016

I disagree @vucalur. I think that index.module.js might be a bad name, as it is more like an application entry-point. Apps built with this generator seem like they should have a single entry point (per application) that loads all modules and is targeted by scripts. However, the modules themselves shouldn't be targeted by scripts because it produces 1 artifact per module, instead of 1 artifact per application.

For instance, if you have 30 modules over 2 applications (admin + webapp), then you only want 2 artifacts from the build process, not 30 or 32.

That is a bigger idealogical change on my part, where index.module.js is replaced by app.entry.js and, if you wanted multiple entries, then gulp can target **/*.entry.js. The entry imports the modules (which it should because it is the application and must declare its dependencies).

I would love to see other peoples' ways of doing it. @vucalur and myself clearly have different ideas, and I'm sure we will see a few other suggestions.

@Swiip Swiip closed this as completed in 87b30f2 Mar 28, 2016
Swiip added a commit that referenced this issue Mar 28, 2016
[fixes #737] adds recipe for using multiple modules
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants