20

I'm working on an angular application. We based our application on https://github.com/Swiip/generator-gulp-angular and everything is working fine. This angular seed project basically scans all your JS files in a directory and concats them into a single JS file when you go into production.

We're building an admin backend for a billing system. The client now also wants a "public backend" for all their clients. A place where clients and log in and send messages basically. The UI is the same for the public backend, we could re-use the same directives everywhere. The only problem is that the public backend is tiny and the admin backend is huge. I don't think serving the full admin app to a random client is good practice.

How do I go about building two applications from the same code base?

Peeter
  • 9,282
  • 5
  • 36
  • 53
  • 2
    Pull all of your custom directives into a library, and share that library between the two projects. Not only that, you could put that project onto bower (privately hopefully) then when your gulp runs bower it will automatically update the libs if need be. – Callum Linington Jun 01 '15 at 07:57
  • 1
    That's what I was going to do if I didn't get an answer, but I dislike the approach. I'll have to maintain 3 different projects (site A, site B and commonModules), instead of a single project. – Peeter Jun 01 '15 at 12:00
  • however, each project should be smaller now. Bower helps with maintenance right, so if you update commonModules, when you run gulp on the others its there. Its not that difficult... – Callum Linington Jun 01 '15 at 13:58
  • 3
    _"I'll have to maintain 3 different projects"_ This is the correct approach. Write decoupled packages which are assembled with a package manager (bower, npm) and build tool (grunt, gulp). My current project at work is built from 14 internal, proprietary repos and many 3rd party ones. – JAAulde Jun 05 '15 at 12:19

3 Answers3

10

Don't serve two applications from the same codebase. That is a recipe for disaster. This is a rough outline of how I would handle this:

  1. Audit the application you have already built. Identify which components are reusable between the two projects and establish that as your base project project.
  2. If you built things with modularity in mind, this shouldn't be back-braking. You may need to refactor to get yourself into the right position. John Papa's Angular Styleguide would be a great place to help on that front (it's been great as I've learned Angular).
  3. Turn that base front-end project into a bower dependency that could be updated independently of your custom application code. More on creating a Bower package here. Maybe you could even open-source what you've built?!?
  4. Build custom functionality on top of your modularized base build. Each group of custom functionality would be one of your applications (in your case that sounds like an admin panel and a public app).
  5. Post launch, you could manage the apps with one product team if they are mostly the same. Identify which features are common, build them into the base app and deploy those changes via bower to your two custom apps. Add in custom functionality on a per-project basis; if the codebases diverge enough, you could separate this into two product teams.

As noted by others, you would manage the apps with a good build tool like Grunt/Gulp which would pull in the common dependencies for you.

serraosays
  • 7,163
  • 3
  • 35
  • 60
5

I'd have to disagree with the accepted answer as well. Maintaining one codebase is significantly more straightforward and less time consuming, and will be favorable in case where your project expands into even bigger number of applications that need to be deployed and built independently.

Defining the build

There would be one app.js file per application, defining which components to import and make the build from. The structure could look similar to the following:

components
-- component-1
-- component-2
-- component-3
app-1
-- app.js
app-2
-- app.js

To build app-1, we need components 1 and 3, so in app-1/app.js we'd define:

require('../components/component-1/file.js')
require('../components/component-3/file.js')

If you'd want to deploy separately user-related settings, you could create UserSettings module, with its own routes, and include components this module needs. This module would then be included in the build of your application. The same could apply to routes, config, runs etc. - optimally these would all pertain to one module, or component.

Dependencies

At some point you'll face the question of whether you want to bundle dependencies for all applications in one go, or create a bundle for each application separately. The only solution I came up with so far, is to curate manual list of dependencies for each application, and execute a bundler based on that list, but I'm sure there's a better way.

Maciej Gurban
  • 5,615
  • 4
  • 40
  • 55
3

I do not agree with the options presented here. The idea of splitting up my code base into 3 different projects would be feasible if I was building re-usable components. But I'm just splitting up my application. These parts wont be re-used in any of my other projects as they are project specific.

The overhead of maintaining 3 different projects (dependencies, building, documentation, releasing, versioning) is not worth it.

I believe looking into ES6 imports (with Webpack or System.js) or RequireJS is a much more better option, however I do not know how they would work in the Angular1.X ecosystem.

Peeter
  • 9,282
  • 5
  • 36
  • 53
  • You have to abstract away the different project files in some way. If all the directives are reusable like you say in the initial question, well that's a big step towards that. Re: Require + Angular - they do different things. Angular handles injection into the DOM, Require handles the loading of the JS scripts by the browser. Check this video (and best of luck whatever you choose): https://www.youtube.com/watch?v=ZhfUv0spHCY&feature=player_profilepage#t=456s – serraosays Jun 15 '15 at 01:23
  • I don't think they do the same thing. With DI, Angular feeds you your dependencies. With RequireJS, you're in charge of your dependencies. You load them from a path. They counter each other more or less: http://stackoverflow.com/questions/3058/what-is-inversion-of-control – Peeter Jun 25 '15 at 09:59