petermichaux / maria

The MVC framework for JavaScript applications. The real MVC. The Smalltalk MVC. The Gang of Four MVC.
BSD 2-Clause "Simplified" License
764 stars 51 forks source link

How to use with require.js? #4

Closed zielot closed 11 years ago

zielot commented 11 years ago

I found your MVC library and thought it might be the ideal place to play about with client-side MVC models. I was trying to make the maria work with require.js and jQuery since I had a working example already with jQuery and require.js but it seems that the namespacing requirement and the way that models get created clash with the assumptions made by require.js. This is a bit new to me so I may just need to dig in for a bit. Could you give me any tips for using maria with require.js?

petermichaux commented 11 years ago

I don't use require.js and haven't tried using it with Maria-based project. It would be a great thing to know more about since some people seem to like require.js.

medikoo commented 11 years ago

@petermichaux go for CommonJS (standard used by NodeJS) it's closest to what you'll have in future natively in JavaScript, see diff, that demos transition from CommonJS to ES6

Such modules can easily be bundled for browsers with tools like Webmake (I'm the author), and Browserify which is already very popular. I develop complex (bundled from hundreds of modules) client-side applications that way, currently I see no alternative, it's the best way, and way of the future.

petermichaux commented 11 years ago

I don't agree that CommonJS or require.js is the best way but some people certainly are using them. If I can support them better then I would like to if it does not need philosophical changes to Maria.

@medikoo Have you used Maria with any of module loaders?

medikoo commented 11 years ago

@petermichaux I haven't, technically I don't use Maria in any of my project. I just watch it, because I'm interested in MVC solutions.

All client-side applications I work with, currently are organized with CommonJS modules which are ported to browser with Webmake, and seriously I don't see any alternative to this approach. It's the best way to organize the code. Standardization and adoption of ES6 modules, will just put a final dot to it.

hieuhuynh commented 11 years ago

@medikoo You could try using require.js's shim configuration.

require.config({

  // Set configuration for non-AMD scripts.
  shim: {
      'maria': {
          deps: ['evento', 'hijos', 'arbutus', 'grail', 'hormigas'],
          exports: 'maria'  // attach 'maria' to the global object.
      }
  }
});

@petermichaux Have you considered wrapping the libraries in UMD? It provides several choices for whether one would use AMD, CommonJS, or just rely on global. https://github.com/umdjs/umd/blob/master/amdWebGlobal.js

petermichaux commented 11 years ago

I have considered wrapping the library but these kinds of things have been in flux over the last few years and the boilerplate continued to grow. Someone could easily wrap Maria any way they need it to be wrapped and maintain it as a downstream distribution.

zielot commented 11 years ago

@Hieu - this is good info; I didn't know how to do this. @Peter - I wasn't suggesting a change to your library as much as wondering how it could be done. On Apr 7, 2013 11:25 PM, "Hieu Huynh" notifications@github.com wrote:

@medikoo https://github.com/medikoo You could try using require.js's shim configuration.

require.config({

// Set configuration for non-AMD scripts. shim: { 'maria': { deps: ['evento', 'hijos', 'arbutus', 'grail', 'hormigas'], exports: 'maria' // attach 'maria' to the global object. } }});

@petermichaux https://github.com/petermichaux Have you considered wrapping the libraries in UMD? It provides several choices for whether one would use AMD, CommonJS, or just rely on global. https://github.com/umdjs/umd/blob/master/amdWebGlobal.js

— Reply to this email directly or view it on GitHubhttps://github.com/petermichaux/maria/issues/4#issuecomment-16032001 .

petermichaux commented 11 years ago

Currently the Maria build process in Makefile produces two files

I don't want to introduce any module wrapping to those files. I am, however, completely open to Maria producing other build versions. For example,

The application developer can then choose which build version of Maria fits into his system. This could widen the appeal of Maria to more developers.

The changes required would be to add a UMD wrapper "template" in the src directory and update the Makefile to make the extra builds. It would be quite straightforward.

One issue that I haven't investigated is the affect this will have on building Maria plugins. A Maria plugin is some code that modifies the Maria code all made possible by the wonderful benefits of JavaScript's dynamic nature. My hope is a large ecosystem of these kinds of plugins will appear. An relatively trivial example is https://github.com/petermichaux/maria-emphasize/blob/master/src/emphasize.js . If Maria is wrapped in UMD, how can a plugin like that make its necessary modifications on Maria?

petermichaux commented 11 years ago

Standard AMD usage seems to be that the name of the file needs to match the name of the AMD module being defined. That would mean if we want to be able to use "maria" as the string in AMD dependencies the file would need to be named maria.js. That is not possible as the file maria.js is used for the regular build of Maria. I guess maria-amd.js is not a good choice. We could do amd/maria.js in the distribution. Honestly I don't know enough about AMD to choose wisely.

medikoo commented 11 years ago

@hieuhuynh I don't need any extra configuration file to work with CommonJS style, it just works, no point using AMD on my side.

petermichaux commented 11 years ago

Good information about AMD and plugins from James Burke

https://groups.google.com/d/topic/requirejs/LP2spp7J2jU/discussion

petermichaux commented 11 years ago

I've created an example application to investigate the best possible AMD support for both Maria and plugins for Maria.

https://github.com/petermichaux/maria-amd-temporary-example

The README.md file there explains the points of interest of the example.

I'm looking forward to feedback from more experienced AMD users.

zielot commented 11 years ago

This looks very helpful wrt what I was trying to do. Thanks for your work on this. On Apr 13, 2013 12:10 PM, "Peter Michaux" notifications@github.com wrote:

I've created an example application to investigate the best possible AMD support for both Maria and plugins for Maria.

https://github.com/petermichaux/maria-amd-temporary-example

The README.md file there explains the points of interest of the example.

I'm looking forward to feedback from more experienced AMD users.

— Reply to this email directly or view it on GitHubhttps://github.com/petermichaux/maria/issues/4#issuecomment-16336796 .

guybedford commented 11 years ago

You approach seems great to me. Ideally plugin modifications could be made through a clear pattern such as maria.extendView or something a little more well-defined. But that is mostly just nitpicking. One small syntax suggestion - the form:

define(function(require) {
  var dependency = require('some/dependency');

  return definedValue;
});

is generally a slightly more readable and less error-prone way of constructing AMD modules as the require statements line up with the dependencies more cleanly. It's a good practice in most cases, so could certainly be worth using as a standard in the project when using AMD.

petermichaux commented 11 years ago

@guybedford

I'm glad a more experienced AMD user doesn't think I've done something particularly crazy.

Fortunately Maria doesn't have any dependencies so the difference between the plugin example and the example you show doesn't apply to Maria itself.Plugin authors can follow your suggestion if they think it looks best. Trying to control this is probably heading towards the cat herding department. ;-) Please correct me if I'm wrong.

Thanks for your feedback.

petermichaux commented 11 years ago

I still need to learn about the build process to concatenate files and if that works well in the example.

guybedford commented 11 years ago

@petermichaux yeah I think most users see the other form of AMD first, so I think getting any more exposure to the inner require style can only help.

Some suggestions for configuration etc below. Just ideas, nothing you have to do really though.

Your configuration probably needs a baseUrl. Ideally set this to the lib folder so that requires work in the global library space. A path config src can then map paths: { src: '../src' }, allowing local files alongside the global requires.

Getting configuration injection right is then also important. Having a single config.js you can then share that with the build with the mainConfigFile property. Ideally have "./config" as the first dependency within the main file, something like:

main.js:

  require(['./config'], function() {
    require(['maria'] ... etc ...
  });
petermichaux commented 11 years ago

@guybedford Thanks for the extra feedback. I appreciate it. I'll try modifying the example with your advice.

The most important action I can take based on this ticket is to create an AMD-friendly build of the Maria library code. It seems to have been confirmed that all I need to do is to wrap the built maria.js code with the following

define(function() { // AMD

// the basic build of maria.js goes here

return maria;}); // AMD

With this wrapped result as the maria-amd.js file in the Maria distribution, AMD users will be happily on their way building their applications with Maria.