Browserify și module dependente de alte module

Până azi, foloseam ori Grunt ori Gulp pentru a combina fișierele JS și nu îmi făceam probleme foarte mari legate de _modul_aritate. Știu de existența AMD, Require & co de foarte mult timp dar pur și simplu nu am găsit niciodată motivația necesară pentru a le încerca.

Azi totul s-a schimbat, am început să folosesc Browserify. În principiu îmi place, doar că am o problemă. Sau cel puțin așa cred…

Am o aplicație simplă backbone, în care am extras fiecare componentă în folderul corespunzător (models, views, collections). Am și un fișier „principal”, să-i zicem app.js, unde am următoarele:

var PageModel = require('./models/Page.js');
var PagesCollection = require('./collections/Pages.js');
var ListItem = require('./views/ListItem.js');
var ListView = require('./views/List.js');
var MainList = require('./views/MainList.js');

Prima problemă? PagesCollection depinde de PageModel:

module.exports = function (PageModel) {
  return Backbone.Collection.extend({
    model : PageModel
  });
};

A doua problemă? MainList depinde de: ListView (care la rândul lui depinde de ListItem) și PageCollection.

Acum, eu le pot trimite pe toate astea ca parametru, dar am senzația că fac ceva greșit și/sau că-mi scapă ceva, pentru că deja mi se pare foarte complicat (deși „aplicația” cu totul are în jur de 50 linii):

var MainList= require('./views/MainList.js')({
    ListView : ListView,
    PagesCollection : PagesCollection,
});

Sau ar trebui să includ dependințele din modulele în care am nevoie de ele? (caz în care… cum voi mai face testarea?)

1 Like

#####Mentionez ca nu am folosit Browserify si nu am foarte multa experienta in JS, but here’s my go at it:

Din cate inteleg eu,

var PageModel = require('./models/Page.js');
var PagesCollection = require('./collections/Pages.js');
var ListItem = require('./views/ListItem.js');
var ListView = require('./views/List.js');
var MainList = require('./views/MainList.js');

Dar in models/Pages.js nu ai asa ceva?

var PageModel = require('./models/Page.js');

Sau asa ceva?

if (typeof PageModel === 'undefined') {
    var PageModel = require('./models/Page.js');
}

Ma gandeam ca ai putea sa dai import la MainList, care sa dea import la dependinte.

Sau chiar asta ai intrebat?

PagesCollection ar putea sa arate asa:

var PageModel = require('../models/Page.js');

module.exports = function() {
  return Backbone.Collection.extend({
    model : PageModel
  });
};

Ideea e ca daca folosesti CommonJS nu mai ai nevoie sa pasezi totul ca si parametru pentru functia de initializare, poti face direct require. Apoi pentru teste poti folosi proxyquirify: https://github.com/thlorenz/proxyquireify (care practic simuleaza functia de require injectand diverse mockuri in functie de ceea ce ai tu nevoie).

2 Likes

O (altă) alternativă la Browserify:
https://angular.io/docs/ts/latest/guide/webpack.html

Am văzut că e inclus şi în unele starter packs, e.g.:

Webpack and Browserify do pretty much the same job, which is bundling your modules to be used in a browser environment. The module is a Node feature, which doesn’t exist in the browser, and ES 6 import is not implemented in any browser yet, which is why things need to be bundled. However, they differ in many ways, Webpack offers many tools by default (e.g. code splitting), while Browserify can do this only after downloading plugins, but using both leads to very similar results. It comes down to personal preference (I am used to Webpack). Webpack is not a task runner, it is just processor of your files run directly from CLI or by a task runner.