I use Smarty to handle my views. To maximize code reuse, I split up my view files into small segments and just include them where ever they are needed. This works well as it keeps my markup consistent when rendered on the browser.
The problem is that I also have JS that will do certain DOM manipulations. It means that my JS needs to have an awareness of the mark up structure, etc. And in a lot of cases, the JS is forced to maintain an identical copy of the mark up that already exist in the Smarty template files.
This is going to become a maintenance nightmare as any changes to the mark up must be done in the Smarty template files and possibly in the JS mark up.
Any suggestions on how to handle this elegantly? Or do I just accept this as a necessary evil?
I split up my view files into small segments and just include them where ever they are needed
Do the same with your JavaScript. Think modular and make modules instead of pages. Any module would include HTML(Smarty in your case), JavaScript and CSS. Any page that needs that modules should require those three files. Or you can bundle all together to make including modules easier. When you create module then you will edit modules not pages. That way you won't break things by editing JavaScript or CSS/HTML.
A module could be anything that can have independency of other modules in a page. Of course modules could talk to each other but you need to define a consistant API for your module system.
This approach would make maintenance easier but the downside is you have to almost rewrite your entire app to make it modular.
Related
I have question concerning optimising application. I have application with multiple directives, so I decided to build single min. css and js file for them all. But at the same time, I was thinking of another way.
What if I would also build one big, minimalised HTML file? Angular allows including templates from script tag:
<script type="text/ng-template" id="tempName">
Template content
</script>
If so, what would be downsides of injecting every directive's HTML in one big file? Would it be any better than multiple small files and firing request when they are needed?
I know, that it wouldn't be so good if we have big application with multiple views, but user only stays at few of them. My idea is to build this file for smaller directives, that shoulnd't cause any problems, right?
What do you think of this?
Like anything there are pros and cons to this approach of caching templates.
Pros:
No need to fetch the template - good for offline capability
If network is slow and this fetch is going to cause some lag as the directive, route, include must resolve the templateUrl. In such cases pre-fetching helps in improving the smoothness of feel.
Pre-fetching also pre-compiles the template ready to be used as it puts in the templateCache.
Cons:
In a large application if all the templates are prefetched we are essentially utilizing more memory to store all the templates when only a handful might get used.
If the prefetched templates are fetched during loading it causes additional request.
If the pros exceed in your application you may want to use some build tool such
as:
gulp-angular-templatecache
webpack-templatecache
grunt-angular-templatecache
... and more
Each file you include is an additional request the browser has to make back and forth, so if u can include it in the same page, then its going to be faster and more efficient.. the main reason for excluding in multiple files is simply for organisation vs the 0.01ms different in page load time.
You can also use something like grunt to work with separate files and then have grunt automatically concat and minify your files for you for on the fly optimization.
Im developing a ember.js based app.
On some "sites" (templates) I want to load a specific js-game, so I have to include extra tags like <script src="game.js"></script>. But since handlebar-templates are defined by <script>-Tags itself, its not possible to simply put my dependencies within a template directly.
How can I include js-files on some individual sites only?
Including files in an Ember.js application is a bit more complex than in a regular website.
If you do not use ember-cli, then you could either include your all your JavaScript files directly in your index.html (one by one) or (and this is better) you could also bundle all your game JavaScript files into a single file (called games.js for instance) and include that single file in your index.html. You can bundle JavaScript files using tools such as grunt or brunch or broccoli.
Now if you do use ember-cli (which I recommend), then you could simply list your files in your Brocfile.js (see documentation here). Learning ember-cli might take a little bit of extra time but it will really help you in the future :)
Good luck!
Ok I found an possibility to solve that problem:
Like described in the handlebars.js-FAQ here (5.), I have to use some kind of a "Hack" to avoid parsing errors. Just need to add an empty command {{!}} into the word "script" like <scr{{!}}ipt src=...>...</scr{{!}}ipt.
That works for me.
Also, as kpdecker says here, it is better to use precompiled templates than defining them inline.
You can try to insert the necessary scripts from didInsertElement hook of the corresponding view. And, if so, in order to avoid duplicates, remove that scripts in willDestroyElement hook of the same view.
I'm building a fairly large-scale JavaScript Backbone.js app with this folder organization:
app
index.html
libs
underscore
jquery
[...]
src
utils
modules
[...]
The index.html file basically loads up all the Backbone.js Routers etc. and instantiates AMD modules etc.
Often however, I find the need to create small applications that basically share dependencies with the Big app.
Suppose I need to create 3 small experiments (separate pages) that all load the same usual suspects (underscore, backbone and a couple of util libraries and modules I've written).
They may though differ in: 1) how they extend these JavaScript libraries, 2) what gets instantiated and 3) markup and interaction.
How do I keep this experimentation DRY?
How do I set up this "extendable Template"?
In my opinion, this is where having a good build system comes in. The more complex your setup, the more useful it is to be able to set up configuration files that can keep your dependency management consolidated in one place. This becomes particularly important when:
You need to load the same sets of dependencies on multiple static pages, but your dependency lists change often during development.
You need to be able to easily create compressed versions of the dependencies for a production version. I find this is pretty important with Backbone, because the uncompressed versions are really big but quite useful during development.
I've generally used Apache Ant for this, but there are lot of build systems out there. What I've done in the past is:
Set up an index.tmpl.html file with the core HTML markup and placeholders for JS scripts, CSS files, and underscore templates.
Make a build.properties file that defines my dependency lists. You can group them in different ways under different property names, e.g. lib.scripts.all or util.scripts.all.
In my build process, create a new index.html file, based on index.tmpl.html, with <script> and other tags to load my dependencies. I have different targets to load the raw files or to compress everything into a production-ready single script file.
You can see an example of this setup in this Github project.
If I understand your requirements, you could set up a similar build file with a few tweaks to allow you to set a) the HTML template to use (your default index or another with experiment-specific markup), b) the output file, c) the specific sets of dependencies to load, d) additional dependencies to load, e.g. experiment-specific modules or initialization scripts. You could set these properties up in a specific target (if you think you'll reuse them a few times) or just specify them on the command line when you invoke ant, via the -D flag.
This would allow you a great deal of flexibility to re-use different portions of your code, and has the added benefit of making it easier to move an "experiment" into your core production code, just by including it permanently in your build process.
I am developing a javascript library made up of a few tightly coupled classes. The classes are broken up into individual .js files, but for brevity's sake, I envision the end user including a single .js file encompassing the entire implementation.
My question is, what is the ideal method for distributing the API? Should I simply repackage all the code into a single .js file, should I keep the existing file structure and setup a series of
document.write('<script src="file1.js"><\/script>');
commands into a 'primary' script file, or is there another way that makes more sense?
Thanks!
I think if you don't intend for the user to jump in there and need to modify it and it's tightly coupled like you mentioned you should put it all in a single JS file and then minify it.
You can provide an unminified version as well but seems for their simplicity you should put it all in a single JS file.
For performance and maintenance reasons, I believe it's better to package them into a single file. The fewer http requests made to retrieve scripts, the better performance (in general - very long scripts can also cause performance slowdown.) I'd also recommend namespacing your api.
Nowadays, we have tons of Javascript libraries per page in addition to the Javascript files we write ourselves. How do you manage them all? How do you minify them in an organized way?
Organization
All of my scripts are maintained in a directory structure that I follow whenever I work on a site. The directory structure normally goes something like this:
+--root
|--javascript
|--lib
|--prototype.js
|--scriptaculous
|--scriptaculous.js
|--effects.js
|--..
|--myOwnScript.js
|--myOwnScript2.js
If, on the off chance, that I'm working on a team uses an inordinate amount of scripts, then I'll normally create a custom directory in which we'll organize scripts by relationship. This doesn't happen terribly often, though.
Compression
Though there are a lot of different compressors and obfuscators out there, I always come back to YUI Compressor.
Inclusion
Unless a site is using some form of a master page, CMS, or something that dictates what can be included on a page beyond my control, I only included the scripts necessarily for the given page just for the small performance sake. If a page doesn't require any script, there will be no script inclusions on that page.
First of all, YUI Compressor.
Keeping them organized is up to you, but most groups that I've seen have just come up with a convention that makes sense for their application.
It's generally optimal to package up your files in such a way that you have a small handful of packages which can be included on any given page for optimal caching.
You also might consider dividing your javascript up into segments that are easy to share across the team.
Cal Henderson (of Flickr fame) wrote Serving JavaScript Fast a while back. It covers asset delivery, not organization, but it might answer some of your questions.
Here are the bullet points:
Yes, you ought to concatenate JavaScript files in production to minimize the number of HTTP requests.
BUT you might not want to concatenate into one giant file; you might want to break it into logical pieces and spread the transfer cost over several pages.
gzip compression is good, but you shouldn't serve gzipped assets to IE <= 6, so you might also want to minify/compress your JavaScript.
I'll add a few bullet points of my own:
You ought to come up with a solution that works for both development and production. In development mode, it should pull in extra JavaScript files on demand; in production it should bundle everything ahead of time. Switching from one behavior to the other should be as easy as setting a flag.
Rails 2.0 handles all this through an asset cache; other web app frameworks might offer similar solutions.
As another answer suggests, placing third-party libraries in a lib directory is a good start. You can also divide your own JS files into sub-directories if it makes sense. Ideally, you'll be able to arrange them in such a way that the files in a given sub-directory can be concatenated into one file.
I will have a folder for all javascript, and a sub folder of that for 3rd party/shared libraries, and sub folders for each component of the site to keep everything organized.
For example:
/
+--/javascript/
+-- lib/
+-- admin/
+-- compnent1/
+-- compnent2/
Then run everything through a minifier/obfuscator during the build process.
I'v been using this lately:
http://code.google.com/apis/ajaxlibs/
And then have a "jscripts" folder where I keep my custom code.
In my last project, we had three kinds of JS files, all of them inside a JS folder.
Library code. A bunch of functions used on most all of the pages, so they were put together in one or a few files.
Classes. These had their own files, organized in folders as needed, but not necessarily so.
Ad hoc JS. Code that was specific to that page. These were saved in files that had the same name as the JSP pages they were supposed to run in.
The biggest effort was in having most of the code on the first two kinds, having custom code only know what to call, and when.
This might be a different approach than what you're looking for, but I've been playing around with the idea of JavaScript templates in our blog engine. In a nutshell, you assign a Javascript template to a page id using the database and it will dynamically include and minify all the JavaScript files associated with that template and create a file in a server-side cache with the template id as a file name. When a page is loaded, it calls the template file which first checks if the file exists in the cache and loads it if it does. If it doesn't exist, it creates it on the fly and includes it. I also use the template file to gzip the conglomerate JavaScript file.
The template idea would work well for site-wide JavaScript (like a JavaScript library), but it doesn't cover page-specific JavaScript. However, you can still use the same approach for page specific JavaScript by including a second file that does the same as above.