Skip to content

Instantly share code, notes, and snippets.

@0x-r4bbit
Last active May 2, 2022 03:50
Show Gist options
  • Save 0x-r4bbit/5411171 to your computer and use it in GitHub Desktop.
Save 0x-r4bbit/5411171 to your computer and use it in GitHub Desktop.
Proposals on how to structure 'standalone' modules in angular. Please read it and leave your opinions for a better angularjs world!

Angular module structure (proposal)

Everyone who's reading this, please leave your opinion/ideas/proposals as a comment for a better world!

Background

Most of you guys read Josh' proposals to make components more reusable, I think. Now, reading through this proposals definitely gives a feeling that this is the right way. Anyways, If you haven't read it yet, you should.

So Josh shows us, how angular apps can be structured in a better and more reusable way. Reusability is a very important thing when it comes to software development. Actually the whole angularjs library follows a philosophy of reusability. Which is why you able to make things like:

// Defining a module
angular.module('myModule', ['dep1', 'dep2']);

// Fill it with components
angular.module('myModule').controller();
angular.module('myModule').factory();

// ... and so on

That whole module thing can now be put into another app, or module, or whatever since it's a module and it knows it's own dependencies. So, turned out that structuring angular apps by feature rather then by layer is the better way of structuring angular apps. It's more reusable!

You might know this already after reading Josh' great proposal. I would like to take a step in a similar direction when it comes to developing kinda 'standalone', installable angular modules, which are app independent.

But what about standalone modules?

Now, what do I actually mean with 'standalone' angular modules? So, with angular, you not only can build awesome apps, you can also build awesome modules which can be reused by others. The AngularUI Project for example, is also just a big angular module with several components and submodules (with its own dependencies) you can use to build your angular apps.

A few weeks ago, I published ngTranslate, an angular module which provides a set of components (services, directives, filters) to translate your app's content at runtime in multiple languages. First of all, it wasn't even planned to make a whole module out of it, but it has grown with the times.

So, ngTranslate is just one of those 'standalone' modules. You can inject it as a dependency into your app and use it's provided components (for more information read the docs.

When developing this module, there were a lot of questions in my brain I hadn't really the perfect answers for. With this gist I'd like to discuss with you guys, how we handle 'standalone' module development.

Nowadays we have great tools like grunt, bower or that Yeoman guy (who just uses the mentioned tools), to make our development process as easy and fast as possible. There are already great packages you can simply install with a

$ bower install <package-name>

The same goes for angular packages you can find on GitHub with a bower- prefix.

We need more of them!

In my little dream world, there'll be someday a BIIIG bunch of reusable angular modules for specific use cases on the interwebs, just like you know from npm.

So if you're interested in making the angular world as easy to use as npm, leave a comment right here and discuss this topic with the community.

The questions that came up

When thinking about a clean structure while developing ngTranslate, the following questions came up:

  • How to name the module (Conventions?)
  • How to name the repository on GitHub?
  • Is the repository name the same name which stands in package.json, component.json?
  • How to name the bower repository?
  • How to name the registered bower package?
  • How should the generated (development and production) file be named?
  • How to structure the module itself?
  • How to structure test environment regarding to the module structure?

These questions can be break down into several things I'd like to discuss with you. I'll go through them one by one.

How to name the module (Conventions?)?

Naming a module can be very easy, but it can also be a mess. When developing an angular module, a module has to be named in camel-case. This is pretty straight forward, but it gets a bit harder when thinking about, what the actual name should be when there has to be a prefix.

Angular's built-in modules are all prefixed with ng, which totally makes sense since ng is actually just a shortcut for angular. That's why we have modules like ngResource, ngCookies and so on and so far.

In my opinion, the ng-prefix looks pretty nice but I think it's actually kinda reserved for angular's own modules. At AngularUI the modules are prefixed with ui which also makes totally sense, but they arent' camel-cased. We use a dot-notation there and name the specific components in camel-case.

I think it'd be great if each module out there follows the same convention and structure. So what do you guys think? Module names always camel-case? What should the prefix look like? Can we go with ng or should everybody has it's own little 'namespace'?

Please leave a comment.

How to name the repository on GitHub?

I think this one comes pretty much hand-in-hand with 'How to name the module?'. After deciding to name the module ngTranslate I wonder under which name to publish the module on GitHub. The following things influence the repository name:

  • The name should be short, so it's easier to type
  • It should have the module name in it
  • It should have the prefix in it (or not?)

Easier to type means for me: no camel-case, we go dash-case. So I had something like

***-translate

But what about the prefix? ng-? angular-? I choosed ng- because it's

  • a) Easier to type
  • b) angular- is already used by angular itself

So I came up with ng-translate. But again. This goes hand-in-hand in how to name a module propery. Also, maybe we want -angular- in the repository names, so we that we know: this is an angular module. I don't know.

What do you guys say?

Is the repository name the same name which stands in package.json, component.json?

Now we I had a conflict. The repository name was ng-translate. The module name was ngTranslate. What should be the name in the package files? What are the consequences when not naming the package properly (regarding searching etc.)? I went with ng-translate again, since the repository is called the same.

Again, I'm not sure if it's the right way.

How to name the bower repository?

In my opinion, there should be always two repositories.

  1. The repository to develop the module (e.g. https://github.com/PascalPrecht/ng-translate
  2. A bower repository, which just includes the files you need (for easy installation. e.g. https://github.com/PascalPrecht/bower-angular-translate

But how to name these bower repos? This also goes hand in hand with the other questions. I think, what's definitely clear, is that it should have a bower--prefix in the name. The Angular team also uses this convention for their own modules.

As you can see, I named the bower repo for ngTranslate bower-angular-translate. So why not bower-ng-translate?

Actually, I just used the conventions of the existing angular module packages there's no real reason why I didn't use bower-ng-translate, but maybe you say I should have done so.

How to name the registered bower package?

Just like the repository name but without the bower--prefix. What do you say?

How should the generated files be named?

First: every angular module out there should have a grunt file which provides a task to build a bower package

But how should the generated files be named? We know things like modulename-x.x.x.js and modulename-x-x-x.min.js. I think this convention is okay for files that get generated by a grunt task.

The bower package shouldn't have the version number in the name, since it's already in the component.json file. But if the generated files from the grunt task are actually the files which also get deployed as bower package, shouldn't they also just have the module name without the version number? This makes the process easier.

Leave a commment.

How to structure the module itself?

As you can see, ngTranslate currently has the following file structure:

|-- ngTranslate
|   |-- directive
|   |   |-- translate.js
|   |-- filter
|   |   |-- translate.js
|   |-- provider
|   |   |-- translate.js
|   |-- translate.js
|-- test
|   |-- unit
|   |   |-- translateSpec.js
|-- .gitignore
|-- .travis.yml
|-- CHANGELOG.md
|-- CONTRIBUTUNG.md
|-- Gruntfile.js
|-- LICENSE
|-- README.md
|-- component.json
|-- karma.conf.js
|-- package.json

Now this is actually pretty straight forward, but there are still some things I'm not really sure about. First, I've extracted the provider code into a seperate file in an extra provider folder. Is this actually needed? The angular project just uses provider definitions as service definitions, which actually don't have to be in an own folder.

So maybe we can rid of that. Otherwise, there are folders like directive and filter, which are also in the angular modules. So these should be there, but shouldn't there a provider folder too?

The next thing I'm not sure about is the name of the actual source folder. It's called ngTranslate. I did this because the modules in the angular project are also named this way. But this is probably done because there are several modules in one folder, where a 'standalone' module would never have another module in it. So this could be called src instead of ngTranslate. The AngularUI components are currently also splitted up into many little modules. And per module there's also a folder called src.

Shouldn't all angular modules out there follow these conventions?

How to structure test environment regarding to the module structure?

The translateSpec.js file in the test folder is grown with the times. I'm thinking about splitting it up into one file per component, just like the module itself is currently structured. Does this make sense? Of couse, totally depends on how we decide how angular modules should be structured.

Discuss and get the best out of it

It'd be so freakin' awesome if you guys leave your opinions on that here. We could then develop a specification which describes how a generic angular module boilerplate could/should look like. In addition to that, there could also be a generator-angular-module beside the existing generator-angular for Yeoman.

That's all. Please help out making my little dream come true.

/pp

Copy link

ghost commented Jul 28, 2015

Conventional wisdom suggests throwing out Bower and replacing it with a more genuine package manager: npm. We did that and only had to add a couple of missing packages to an npm repository: ngTranslate and d3. We never used Grunt as Gulp (the new de facto standard, with good reason) has long been available. I don't see much value in Yeoman (even if most generators depend on Bower and Grunt) and instead do our generation with Swagger. We maintain our own basic seed application (never encountered a seed that was suitable for new development at the time we needed the seed, they get very stale very quickly).

Copy link

ghost commented Dec 12, 2016

The suggestion to use Bower based components is disqualifying as far as this being a practical proposal.

@Virat003
Copy link

Needed to compose you a very little word to thank you yet again
regarding the nice suggestions you’ve contributed here.

AngularJs Traning in chennai

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment