Architecture: Combine multiple JavaScript projects (modular)

I would like to create a clean architecture for my JavaScript project. The project consists of one Node.js server and two separate Angular.js interfaces for different purposes. To build the interfaces, I use an individual assembly of grunts each. The result of the construction is one HTML file for each project and two files with a mini-type / enlargement of CSS and JavaScript. Then each front server is launched on a separate minimum version of the Node server (it only serves static files).

So far so clear. The goal now is to add plug-ins to each of the three main projects. The module should extend the JavaScript of one of the projects. This means, for example, in the case of a single interface for adding an additional angular module to the angular configuration. I already know where and how to add the angular module code to the main application.

The problem is this: how do you create a reasonable build process over several projects, which also depends on the plugin modules? I came up with two solutions.

  • I could add the plugin as an NPM dependency to one of the main projects. However, it is a drawback that every change in the module must be transferred to NPM, and it is not very convenient to develop a plug-in module like this. The plugin does not start by itself.
  • I can have a list of plugins inside the Gruntfile of one of the main projects. This list will contain local file paths. In the assembly of the main module, plug-in assemblies will be performed. This, however, will include viewing changes to the built-in plugin files. This is an unclean decision.
  • I may have another project that contains dependencies on the main project and all the plugins and builds it all together. The question of how to add the dependency remains (case 1 or 2)

How would you solve this problem?

+7
javascript architecture build gruntjs
source share
4 answers

IMHO, this is not something that is related to the work of the task manager (aka gulp, grunt or even webpack, here it does not matter). The community goes to a place where you own a lot of (relatively) tiny node modules that do one thing and do it well, so it's pretty related to your first suggestion.

VCS repository might look like this:

my-repo/ package-1/ package.json package-2/ package.json package-3/ package.json ... 

... then you work with npm link to create symbolic links inside the modules themselves, so you do not need to publish modules to receive updates.

There is a rather new lerna package that does exactly this npm link thing automatically (it determines your dependency graph in your "local" modules and establishes a connection between them), all you have to do is follow their structure. In addition, he knows how to publish publications, you can run commands in all packages and bind other related things.

Babel , React are excellent examples of these modules - separation of interests. Babel is working with lerna to automate bundling between packages, these are their reasons to have a monorepo .

+3
source share

I usually do what you described below 1. But I use local dependencies that will be joined by my assembly chain.

 npm install ~/project_root/sub_project --save-dev 

this way you don’t have to press all the time. you just delete the node_module / sub_project folder and run npm install again inside your build chain.

using a browser, you can add your dependencies to your angular project.

The plugin does not start by itself.

I usually design my services or directives as regular JavaScript classes and end them with angular.

 var Service = require("./path/to/service.js") module.exports = [function() { return { restrict: 'AC', link: function($scope, $element) { var someService = new Service(); $scope.$watch("whatever",function(value){ service.doSomething(); }) } }; }]; 

That way you can run them and test them independently of angular. This also has the advantage of working with WebWorkers . Because they cannot be (fully) used with angular 1.X.

+1
source share

You add unnecessary complexity to the MEAN project.
Why are you combining two parts of html via grunt?
You must use the AngularJS SPA architecture, there is a reason they have accepted it. One of them does not work in such problems.
Instead of concatenating files, simply configure the state of your SPA to invoke the required partial template from the html file. THAT IT!
And use the web services on your server (I think you do this) in such a way that you are not dependent on the origin of the data, since you are consuming a URI, no matter which server it came from.
Regarding the dependencies, you can easily use npm on the front or back side with the --save flag to add them to the package.json file and then copy this file to the appropriate dirs and npm install applications.
But I really don’t see where you are going with all this, if you explain a little more about the functional requirements that will help to understand this.

+1
source share

I had a similar problem a few months ago. Setting dynamic dependencies can be solved quite easily, as you are familiar with streaming build systems such as Grunt or Gulp.

  • You can select a property inside your package.json or devdependencies , which will store all the necessary information, bower.json or even a custom JSON file will do the trick too. I prefer NPM packaging manifests or Bower manifests, as they provide a valid entry point for each module.
  • Using grunt-auto-install , you can dynamically install any additional module dependencies for your construction process, those that you can analyze from the main package.json project.
  • Using each module the main property from each additional package. json will provide you with a list of files to initialize the uglify or concatenating task.
+1
source share

All Articles