📜 ⬆️ ⬇️

Definer.js - simple modular system

While JavaScript has not acquired these modules, we continue to improvise.
So one more implementation of modules came to light - definer .

The main idea of ​​this modular system in the absence of a modular system. Source codes of the application are conveniently laid out in modules indicating dependencies between themselves, and then they are assembled into one self-sufficient file, which does not know anything about the modules.

For a good understanding of the idea, under the cut examples from simple to complex.
')


Take the abstract page of online store products, index.html :
 <html> <head> <meta charset="utf-8"/> <title> -</title> <script src="jquery.js"></script> <script src="https://rawgithub.com/tenorok/definer/master/definer.js"></script> <script src="modules/cart.js"></script> <script src="modules/list.js"></script> </head> <body> <ul class="list"> <li class="item"> <span class="name"></span>, <span class="price">250</span> </li> <li class="item"> <span class="name"></span>, <span class="price">100</span> </li> <li class="item"> <span class="name"></span>, <span class="price">300</span> </li> </ul> </body> </html> 


We will use jQuery for working with DOM and definer for modules.

Cart module that implements an online store cart with the ability to add products and get the total value of the added goods:
 definer('Cart', function() { function Cart() { this.list = []; } Cart.prototype = { add: function(target) { var item = $(target); this.list.push({ name: item.find('.name').text(), price: +item.find('.price').text() }); }, sum: function() { return this.list.reduce(function(sum, item) { return sum + item.price; }, 0); } }; return Cart; }); 


The list module, which depends on the Cart and implements the interaction of the visitor with the catalog:
 definer('list', function(Cart) { var iCart = new Cart(); $(function() { $('.item').on('click', function(e) { iCart.add(e.currentTarget); console.log(iCart.sum()); }); }); }); 


It turned out a page where you can click on the product and in the console see the total value of the added goods. But, at the same time, we divided the functionality into two independent modules.

In this example, we have a global variable, which can also be put into a module, this is jQuery.

Connect the modules/clean.js in front of the existing modules:
 definer.clean('$'); 


Now the $ variable is not in the global context:
 console.log($); // undefined 


To continue using jQuery in modules, add a dependency:
 definer('Cart', function($) { ... }); definer('list', function($, Cart) { ... }); 


Assembly


Now everything is ready and you can collect the source code into a single file.

Install the module collector:
 npm install definer 


Putting all the modules from the modules directory into the index.js file:
 ./node_modules/.bin/definer -d modules/ index.js 


Now in index.html enough to connect only jQuery and the assembled file:
 <script src="jquery.js"></script> <script src="index.js"></script> 


Build with grunt-definer


For ease of development there is a grunt plugin . You can set monitoring to change module files and automatically start the assembly.

Install everything needed for the grant:
 npm install grunt grunt-cli grunt-contrib-watch grunt-definer 


Add the Gruntfile.js file to the project root:
 module.exports = function(grunt) { grunt.initConfig({ watch: { scripts: { files: ['modules/*.js'], tasks: ['definer:all'] }, }, definer: { all: { target: 'index.js', directory: 'modules/' } } }); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-definer'); }; 


And we will start monitoring:
 ./node_modules/.bin/grunt watch 


Now the build will be performed automatically in the background, and we can change the module files and refresh the page in the browser to see the result.

Build third-party files


Now two files are connected to the page - jQuery and the assembled modules. You can add jQuery to the assembly and connect only one file to the page.

To do this, simply add the clean option to the grunt-target:
 definer: { all: { target: 'index.js', directory: 'modules/', clean: { $: 'jquery.js' } } } 


Now in index.html enough to connect only one assembled file:
 <script src="index.js"></script> 


Jsdoc


It is possible to generate a JSDoc containing information about the collected file.

To do this, add the jsdoc option to the grunt goal:
 jsdoc: { "file": "    -", "copyright": "2014 Artem Kurbatov, tenorok.ru", "license": "MIT license", "version": "package.json", "date": true } 


It is possible to specify the relative path to the JSON file, from which the collector will receive the value of the field of the same name.

Put the package.json file in the project root:
 { "version": "0.1.0" } 


The following JSDoc will appear in front of the modules in the assembled file:
 /*! * @file     - * @copyright 2014 Artem Kurbatov, tenorok.ru * @license MIT license * @version 0.1.0 * @date 17 February 2014 */ 


Total



Definer helps:


Documentation for definer and grunt-definer can be found on github.

Source: https://habr.com/ru/post/212817/


All Articles