We are developing a javascript component to be used in a JSF app and we're using Dojo.
The thing is we only need specific parts of the library and we'd like to only insert into our webapp the files/folders we use to accomplish our goal.
We could do this 'by hand' but in the future we might need to add other functionality from Dojo and then we will not know what resources we need -> I guess by this moment you realised we are no Dojo/js gurus.
Basically we are looking for a way to automate this process. We were thinking of getting a list of the dependencies and then create a small script to 'filter' the files.
Is this possible ? Have anyone tried this before ?
Thanks.
I may be misinterpreting your request, but I think dojo does what you want out of the box. Since the latest versions of dojo follow the Asynchronous Module Definition (AMD) format, you use a global require function to describe what dependencies a specific block of code have, and only those modules are loaded. An example from the sitepen dojo intro:
require(["dojo/dom", "dojo/domReady!"], function(dom){
var greeting = dom.byId("greeting");
greeting.innerHTML += " from Dojo!";
});
If you only want to have to to load a single <script/> tag, you'll want to look into the dojo builder. Using the online build tool You can select what packages you want included into the dojo.js layer and it will bundle everything up into a zip file that includes dojo.js/dojo.js.uncompressed.js which contains dojo core in addition to the modules you selected.
Ok, we did this by doing the following (just in case anyone will need this):
* declare a JSF filter and map it to /js/* (all dojo resources are under /js folder, this may need to be modified to fit your folder structure); this way, all requests for a dojo resource will be filtered.
* in the filter class, get all the requested files: (HttpServletRequest) request).getRequestURI() and write it line by line in a file: now you have all the needed resources.
* parse that file with a script, line by line, and copy the files to another location -> build the folder structure.
* use the created files in your WebContent folder (or wherever you need it), you have a clean library -> you only deploy what you use.
The web is littered with full-blown JavaScript libraries who say they will save your day and make your web development life much easier. You get encouraged to include these “mere 80 kb” libraries that is supposed to be the solution to all your needs, and practically make the web site work by itself. Needless to say, I’m not a big follower of JavaScript libraries,, especially since they almost always include lots of superfluous code, so I thought I’d put together a tiny library with only essential JavaScript functions.
The result of that is EJ – Essential JavaScript.
EJ consists of functions that I use all the time and they make writing JavaScript go faster and the result is being able to do work more efficiently. It is also about having the things you would write again and again for every web site you produce in one neat and tiny file instead, to be able to focus on the new things you need to address
Related
AFAIK, in Meteor, when compiling app, all javascript files and all css files will be merged to one file. I think this behavior will slow down app (because user must download all css and javascript that unnecessary for that page). Moreover, this behavior makes our app not dynamic, because maybe some page, we need different css or javascript files.
So my question is: How can we choose custom javascript and custom css for a template ? Does Meteor support this ?
Thanks :)
AFAIK Meteor is not supporting this exactly in that way. So you are left with two workarounds. One would be writing a own extension which helps you in that regard or finding one which already exists. And the other would be putting your special resources somewhere in the /yourMeteorApp/public folder which is excluded from the merge process (see http://docs.meteor.com/#/full/structuringyourapp). And now you could write some template specific logic to load and evaluate JS and CSS resources from there when your template is accessed. Resources in public are available directly on root level - so public/js/my.js would be available under www.example.com/js/my.js.
UPDATE:
This answer is quite old and in modern Meteor apps you should make use of the import logic (and the imports folder) which didn't exist in that way when I originally answered this: https://guide.meteor.com/structure.html#intro-to-import-export
This should be the best way to handle any dynamic JS requirements and strucutre an app by far nowadays.
In practice this has yet to be a problem for me. The combined javascript files are minified and obfuscated. The fact that any "page load" within the UI is done without a server GET makes the UI quite snappy. I have over 20 packages which add up to 2.1MB of js loading when the app cold-starts. Even on iOS it feels fast.
I've been using a grunt file to concatenate all my JS into a single file which is then sent to the client. What advantage do I have in using require calls then? The dependencies are inherent from the concatenation order and I don't have to muddy all my JS with extra code and another third-party library.
Further, backbone models (for example) clearly state their inheritance in their definitions. Not to mention that they simply wouldn't work if their dependencies weren't included anyway.
Also, wouldn't maintenance be easier if all comments related to dependencies were in one place (the grunt file) to prevent human error and having to open every JS file to understand its dependencies?
EDIT
My (ordered) file list looks something like:
....
files: [
"js/somelib.js",
"js/somelib2.js",
"js/somelib3.js",
"js/models.js",
"js/views.js",
"js/controllers.js",
"js/main.js"
], ...
So perhaps requireJS isn't worth it for small projects anyway.
Using require.js allow you to break down each part of your application into reusable modules (AMD) and to manage those dependencies easily. It is not easy to manage dependencies in a javascript application with 100 classes, for example.
Also, if you don't want all the overhead of require, check this out (developed by the same guy who created require.js): https://github.com/jrburke/almond
The answer depends on the size of your app and the end use case..
A single site.min.js payload for the front end (client) generally aims for small file sizes and simple architectures (1 single file generated from maybe 10).
back end based (server) apps are usually much bigger and complicated and therefore may warrant the use of another tool to help with managing large code libraries and dependencies (50 files for example).
In general, RequireJS is worthwhile but only if you have many files and dependencies. An alternative for use in the client would be almond. Again, using a tool like this must warrant the need (many files and dependencies).
The answer from orourkedd is also worth reading.
I like keeping myself busy building modular web-applications, but don't want to spend time where I can save some..
For example I'm building a news module that should be easily implemented over multiple sites, because the same web-application is used.
However not all websites will need a news module. Is it better/easier/faster to create an inline stylesheet/javascript file built into the module itself, than to create a big external stylesheet/javascript with all the libraries? Even though the file for the news module is not needed on all other webpages?
It seems to be much easier to create an inline library in the module itself. So that this only gets loaded when needed, and saves load time and bandwidth on the other pages.
The other thing is that I like writing 'plug-and-play' modules. Say I move a file across the file server into the module folder, and the application will take care of the rest. With inline sheets, I dont have to add new lines to the header/footer etc.
What is the best solution for this? When also taking into account that I rather spend 10 minutes moving a file and it works, than to spend 1 hour appending external libraries just because its more of a 'good practice'?
If you re building web applications, are you using the MVC patern? Do you separate your concerns? (your Templates/Views, your Models, and your logic(Controllers))
If you follow MVC, it makes easier maintaining and customizing your app.
To answer to your exact question, what you need is RequireJS. This way you have only one place to declare your requirements, and RequireJS will handle the rest.. Load order and more..
Quoting from the requirejs website:
Over time, if you start to create more modular code that needs to be
reused in a few places, the module format for RequireJS makes it easy
to write encapsulated code that can be loaded on the fly.
Inline is never a solid way to maintain CSS. Take care to separate the description of your layout from your views. You can easily include the file in the same directory as the module so it should not be an issue.
Or if you want just to load "on fly" some script you can use jQuery.getScript , http://api.jquery.com/jQuery.getScript/ . Otherwise you should follow George's way.
We have a large web project, where we need components which can talk to each other which can be put in a central repository of components for different projects.
Using reuirejs and Backbone for the modular development. Went through different boilerplate available for backbone and requirejs, but none matched my requirement. So I have created following directory structure. It can be explained as follows.
---resources
|---custom-components
|---mycomponent
|---js
|---views
|---models
|---collections
|---css
|---templates
|---mycomponent.js
|---mycomponent2
|---js
|---views
|---models
|---collections
|---css
|---templates
|---mycomponent2.js
|---libraries
|---backbone
|---underscore
|---jquery
|---jquery-ui
|---jqueryplugins
|---jcarouselite
|---thirdpartyplugins
|---page-js
|---mypage.js
|---mypage2.js
resources directory will contain all the resources. Under that we will have 4 directories as mentioned.
libraries, jqueryplugins and thirdpartyplugins are obviusly the directories for the name they say.
page-js directory will contain the actual main-js which will be used inside our html file as requirejs data-main attribute.
Custom-component is where all widgets created by us will reside, as you can see it has a js file with same name as that of the component, which will be entry point of this widget. This directory also has directories for js, css and templates. CSS and templates will be loaded by text plugin and CSS plugin respectively. Js directory will contain all the backbone code to make this widget work.
Custom components will be asked by main-js residing in page-js.
Coming to what I need.
1. I want experts to have review this directory structure in perspective of large web projects, where you will need to share your widgets with other teams. suggestions are welcome.
2. My each custom-component will define a module, which will have dependencies within package structure as well as outside package structure. I want to know, if there is any way to use r.js to optimize only my custom widget dependency within package structure and let the plugins and libraries optimized separately.
3. I am developing single page ajax application, so I will be asking modules on demand so I need to cleanup modules and widgets when I dont need them, is there any way for cleaning up I should be aware of?
About the directory structure
As a directory structure pattern, I highly recommend using directory structure of cakePHP. it's really robust as in words!! I'm running multiple apps (one of them is as big as Groupon) and it works just like a charm.
You may need to tweak it a little because, you know, cake is a PHP framework and yours is a javascript one.
Here is the cake's awesome MVC directory structure:
Please note that you may host thousands of apps on a single cake installation. so if you're interested, what are you waiting for? go to their site and read their docs.
About the cleaning up techniques
Well, here is one of the downsides of the Javascript which I don't like. there is no real way to destroy a OO module like in Java or C++. here we don't have such things like C++'s ~ destructors.
For many years, programmers use module = null to free up memory from un-used codes.
Take a look at these also:
Can dynamically loaded JavaScript be unloaded?
Loading/unloading Javascript dynamically
How to unload a javascript from an html?
Hope it helps and good luck on designing your app ;D
Probably I'm late in answering this, but anyway let me share my views here, incase someone else finds it useful.
Your directory structure looks alright. It is always a better design to keep your business components self contained in to a particular directory. I will not recommend Cake MVC structure which break the Open Close Principle. Also have a look at the directory structure recommended by http://boilerplatejs.org which is a reference architecture for large scale JavaScript development.
I do not get the question very clear. when r.js is run it will optimize all JS files it find in the directory (exclude possible) and then create a single script by going though the dependency tree. In production you only need that single script (plus locale files if i18n plugin is used)
Read my blog post below. It might give you some hints: http://blog.hasith.net/2012/11/how-much-multi-page-single-page.html
some time ago, I was reading an article(a library built by some guy) about how his library can do
lazy loading of JS
resolve dependencies between JS
(typically encountered when trying
to "include" one js from another)
include files only once. thought
specified multiple times regardless
of how they are called (either
directly specifying it as file or
specifying it as one of the
dependencies)
I forgot to bookmark it, what a mistake. Can some one point me to something which can do the above. I know DOJO and YUI library have something like this, but I am looking for something which I can use with jQuery
I am probably looking for one more feature as well.
My site has asp.net user controls
(reusable server side code snippets)
which have some JS. Some of them get
fired right away, when the page is
loading which gives a bad user
experience. Yahoo performance
guidelines specify that JS should
be at the bottom of the page, but
this is not possible in my case as
this would require me to separate the
JS and the corresponding server side
control into different files and
maintenance would be difficult. I
definitely can put a jQuery
document.ready() in my user control
JS to make sure that it fires only
after the DOM has loaded, but I am
looking for a simpler solution.
Is there anyway that I could say "begin executing any JS only after DOM has loaded" in a global way than just writing "document.ready" within every user control ?
Microsoft Research proposed a new tool called DOLOTO. It can take care of rewriting & function splitting and enable the on-demand js loading possible.
From the site..
Doloto is a system that analyzes
application workloads and
automatically performs code splitting
of existing large Web 2.0
applications. After being processed by
Doloto, an application will initially
transfer only the portion of code
necessary for application
initialization. The rest of the
application's code is replaced by
short stubs -- their actual function
code is transferred lazily in the
background or, at the latest,
on-demand on first execution.
OK I guess I found the link
[>10 years ago; now they are all broken]
http://ajaxian.com/archives/usingjs-manage-javascript-dependencies
http://www.jondavis.net/techblog/post/2008/04/Javascript-Introducing-Using-%28js%29.aspx
I also found one more, for folks who are interested in lazy loading/dynamic js dependency resolution
http://jsload.net/
About the lazy-loading scripts thingy, most libraries just adds a <script> element inside the HTML pointing to the JS file to be "included" (assynchronously), while others like DOJO, fetches it's dependencies using a XMLHttpRequest and then eval's its contents, making it work synchronously.
I've used the YUI-Loader that is pretty much simple to use and you don't need the whole library to get it working. There are other libraries that gives you just this specific funcionality, but I think YUI's is the safe choice.
About your last question, I don't think there's something like that. You would have to do it yourself, but it would be similar to using document.ready.
i did in my framework a similar thing:
i created a include_js(file); that include the js file only if it isn't included reading and executing it with a synchronous ajax call.
Simply put that code in top of the page that needs dependencies and you're done!