RequireJS implementation for Zend framework 2

I have written a followup on this post, where I explain that the module is already available.

This is my initial idea for a requireJS module that could be used in zend framework 2. There’s not a lot of details yet, but the logic is there. Implementing this will be the easiest part, as I do believe that the architecture for this should be just right because you otherwise lose the flexibility and structure that both zend framework 2 and requireJS offer. I guess I’ll just start of by explaining my personal zend framework 2 architecture a little bit.

I do not store all of my assets in one directory. 

My approach is slightly different, in the sense that I supply assets on a per module basis. Every module has a public directory, and I use AliasMatch and RewriteEngine to map requests to their assets:

 

So basically I rewrite requests from this “/mymodule/js/main.js” to this “/path/to/application/module/Mymodule/”. This way my modules actually supply their own assets.

 

The reason I started using requireJS should be obvious to everyone that knows what it is.

In case you still want to know why,  it’s because I like structuring and setting up dependencies in a proper manner. This allows me to have a “main” module that will take care of global modules / dependencies such as jquery, allowing me to quickly scan for modules that don’t support jquery1.7.3 yet (example).

 

The problem with requireJS is the structure it expects.

With the way zf2 modules are set up the optimizer will not work. Also, being able to have one entry point (for the “main” requireJS) will be rather difficult with a bunch of modules having their own “main”. This could be solved by mapping those to the main application but then you’d not be working modular.

 

My solution is an implementation that will figure all of this out for you.

I was thinking of building a zf2 module with a viewhelper that allows you to register a path for your zf2 module as well as the main requireJS module. zf2 modules register requirejs modules, and at the end of the run the viewHelper will simply set up the requirejs config (paths, so that /zf2module/* links to the actually resource) and dependencies to make sure that all requirejs modules get loaded.

When enabled, this run could also automatically create a build file for requirejs. This, however, will work event based (zf2) and will ask every module for their requirejs modules (because a build takes all js). This allows you to leave out very specific requirejs modules from the build. Along with this approach, you could also have a build.json / build.js for every zf2 module which would be scooped out by the optimizer (a zf2 layer that will create the build file based on these files).

 

The reason I think this approach is awesome is because of its flexibility.

Simply because using this approach allows you to not have to think about your structure too much (the main goal behind requireJS and zf2 modules) and focus on doing what you know, thus your logic. It’s flexible enough for you to write your own implementations and use this the way you think fits best, while still keeping all advantages of requireJS.

 

Some examples, maybe?

I do not have a working module yet, as I’m still collecting feedback and ideas. I do however have some really simple uses for the view helper.

I do realize this illustrates the usage for your main module view, however it might give you a better idea of the structure I’m thinking about.

 

Any questions, tips or feedback?

Do tell me. This is just the theory and an initial proposal. So all feedback both positive and negative are well appreciated.

 

4 Comments

Add yours →

  1. I think it’s an awesome idea! I haven’t much experience in requirejs (it’s on my todo list) but I have one remark in your code example:

    I’d never put the configuration step into your view. So the $this->requirejs()->registerModulePath() should be done in a module config file. Think of routes in a module.config.php, where every module is able to register more routes to the config. The same should be possible with requirejs module “namespaces”. Then you simple consume those config values in your view (like $this->requirejs()->addModule()).

    • @Jurian, I was thinking of that, but decided to not include it in this plan because it seemed that everything requireJS related is js related and thus front-end. In the end, it will be used specifically to create the paths map for requireJS, which is inline js. Seeing how the backend doesn’t use this information I figured I’d put it in the views. I could take the routing idea, I’ll think about that. Thanks for your feedback!

  2. Hey,
    I’ve been thinking of your solution, but my problem remains… How to bind real paths to public ones (without compiling/deploying data into public/)?

    So I generally like the idea, and I think all this can be handled by something like a dedicated controller and a couple of services, but generating the URLs will still be painful.

    On the other side, overriding the headScript or footScript helpers may really boost up frontend performance (yes, I’m thinking of overriding ALSO main.js).

    The idea is good, but there’s still too many dark spots in it.

    • @Marco, I’m actually describing a way to map file paths to public paths. Your javascript will just be accessible, there’s no real need for what you’re asking. I’m using AliasMatch / RewriteRule, but you could put everything in your public directory if that’s what you like most. But my plan makes every javascript module publicly accessible. If that’s your point, then I guess I could brainstorm some more about putting the files somewhere else. However, I dont like this approach because I want to serve my js directly, and not through a php proxy (which is exactly what you’re describing, right?). Thanks for your feedback. I think it’s useful.

Leave a Reply


6 + nine =

©SpoonX 2017