I have three javascript files that I want to merge into a single file. Is it possible to just copy paste all of the code into one file or will there be namespace conflicts and other problems?
EDIT: I'm worried that each file acts like a namespace encapsulating each file's code, and that this encapsulating will cease to existing if I merge the files.
If the script files were all loaded in the <head> and you paste them in the same order they appeared in the HTML then there shouldn't be any problems.
Having said that, if they use document.write I'm not sure...
If they all work when loaded sequentially, it makes no difference if you concatenate them to a single file and you that instead. Just make sure you put them together in the same order as when you load the seperately.
In answer to your edit: No, each file will not act as a separate namespace.
The top level in each file will share the same global namespace. Hence the having single file with the contents of all three is the same as referencing each seperately assuming the content appears in the same order.
Try it and see if it works. :) The namespace conflicts will depend solely on the code, so without posting it, it will be hard to tell you. You shouldn't have problems putting them in one file so long as they don't have errors already, but if one is dependent on another, make sure you put them in the proper order.
There's absolutely no namespace encapsulation in JavaScript, unless you go out of your way to make it happen. By default, everything ends up in the global namespace. The JavaScript module pattern helps reduce global namespace pollution.
Related
There are a lot of questions and answers about conflicting variables names on Stackoverflow, but they all seem to be about scoping in your own code.
<script src="https://external_one/some_script.js"></script>
<script src="https://external_two/another_script.js"></script>
I'm loading two external, 3rd party JS scripts and need to run them on the same webpage. Separately they work fine, but when I try to import both at the same time, I run into a problem: both scripts have been written in such a way that they use a global _ variable. This means only the script that was imported last will work, as it overwrites the existing _ variable from the first script.
Using a global variable like this is bad practice and using a generic variable name like _ makes it even worse, but as these scripts are rather complex I can't just write my own version and I'm stuck using the scripts from these two providers. They don't seem to provide something like the 'no conflict' option libraries like JQuery provide (to prevent breaking other script that use the $ variable).
So what I'm was trying to figure out, is if it's somehow possible to encapsulate those scripts on import and prevent them from using the same variable. The only option I could think of was to use ajax to load the script, maybe make some changes and then run it using eval but this sounds like a huge problem waiting to happen.
Any suggestions on how to solve this problem?
I have a bunch of javascript "classes" (Prototype) that make up the inheritance hierarchy of a web application I'm building. I've been trying to organize these classes into "namespaces":
var UI = {
Control: Class.create(KVO.Object,
{
...
})
}
The classes are organized into separate files, so when I wanted to add a class to UI, I did this in a separate file:
UI.TextFieldControl = Class.create(UI.Control,
{
...
})
But, when I try to use UI.TextFieldControl in my program after including the files, it is undefined. I guess this is a scope problem of some sort, because within the TextFieldControl file it is defined, but as far as I can understand UI.TextFieldControl should be defined after it is included; what am I doing wrong?
Ok, I found the problem; I was including the file that defines UI twice, once before the file that defines UI.TextFieldControl and once after. Thanks for your responses; I was beginning to worry I didn't understand javascript scope at all!
Have you tries using FireBug? Because by the code you provided nothing seems to be wrong. If your file includes are fine. Your controls should be defined.
Use FireBug and check your files and their order of loading. Maybe your UI.Control is being loaded after you define TextFieldControl? You'll also be able to see your UI namespace if it hass all the necessery classes and also try defining them by hand and see what happens.
If you're using IE you probably forgot to remove some trailing comma, that simply discarded the whole file with your TextFieldControl...
There are essentially 2 places to define JavaScript functions in Grails, directly in a element on the GSP, and within a separate javascript source file under /web-app/js (for example, application.js). We have defined a commonly reused javascript function within application.js, but we also need to be able to generate parts of the function dynamically using groovy code. Unfortunately, ${some groovy code} does not appear to be processed within separate javascript source files.
Is the only way to do this by defining the javascript function within a script tag on a GSP page, or is there a more general solution? Obviously we could define the javascript function in a script tag within a template GSP file which would be reused, but there is a lot of push to keep our javascript functions defined all together in one place (i.e. the external javascript source file). This has performance benefits as well (the javascript source files are usually just downloaded once by each client's browser, instead of reloading the same javascript functions within the source of every html page they visit). I have toyed around with the idea of breaking the function up into static and dynamic pieces, putting the static ones in the external source and putting the dynamic ones in the template GSP, then gluing them together, but this seems like an unnecessary hack.
Any ideas?
(edit: It may sound like the idea of dynamically generating parts of a JavaScript function, which is then downloaded once and used over and over again by the client, would be a bad idea. However, the piece which is "dynamic" only changes perhaps once a week or month, and then only very slightly. Mostly we just want this piece generated off the database, even if only once, instead of hard coded.)
An easy solution to keep your JavaScript unobtrusive is to create a JavaScriptController and map its actions "/js/*" by adding this to your UrlMappings.groovy file:
"/js/$action"{
controller = "javascript"
}
then just create an action for each dynamic JS file you want, include in in your layout <HEAD>, and presto, you've got a JS file that you can insert Grails snippets into! :)
Note: I've found that there's currently a bug in Grails that doesn't map file extensions to content-types properly, so you'll need to include <%# page contentType="text/javascript; UTF-8" %> at the top of your view files.
This is a great solution. I would like to offer a suggestion to use somthing other then a mapping of "/js/$action" because this is no longer going to allow you to access you javascript files in /web-app/js/. All your javascript files would have to be moved to a the directory your controller would point to.
I would use something like
"/dynjs/$action"
This way you still can point to files in the /web-app/js/ files with out conflict and enjoy the benifits of gsp tags in javascript files
Please correct me if I'm wrong.
Or this... have a tag/service/dynamic method that lets tags write out their JS+CSS+whatever else, to a "cache" which is used to build the JS+CSS resources by a different controller.
Full concept here: [http://www.anyware.co.uk/2005/2009/01/19/an-idea-to-give-grails-tags-esp/][1]
If you want to use models created by the controller (that rendered HTML page which reference the Javascript in which you intend to use groovy code) in the Javascript code, then you can use this technique:
This technique does not need to change URL mappings and does not require you to create extra controller.
In your view GSP add javascript as follows:
<script type="text/javascript">
<g:render template="/javascript/yourJavascriptFile"/>
</script>
In views folder create a "javascript" folder. And create a file named:
_yourJavascriptFile.gsp
You can not only use all the GSP code in your _yourJavascriptFile.gsp file, but you can also use all the models created in your controller (that is rendering the view).
NOTE: There is nothing special about javascript folder. You can name it anything you want OR use an existing view folder. This is just a matter of organizing and identifying your HTML spitting GSP from Javascript spitting GSPs. Alternatively, you can use some naming conventions like: _something.js.gsp etc.
Name your scripts like this
/wherever/the/js/files/are/thescript.js.gsp
The gsp code inside will be rendered correctly by grails. This works, but I have no idea if it's considered a Good Idea or not.
There is another way - pass in the generated code into a function that expects closures. Those closures is generated by the program of course. The generated code is of course inlined/script-tagged in the gsp page.
it may or may not work depending on the nature of the code being generated. But i suspect it will work, and if it doesnt, minor tweaking to the coding style of your javascript will definitely make it work. Though, if these 'generated' code doesnt change much, this quite overkill imo.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
How do you guys organise your javascript code? I know that it is good practice to store the code in an external .js file and this is fine for code that is run in multiple pages but how do you organise if you have, say 20 pages, and only 1 of them uses a particular function. Do you create a new external file for that 1 page or create the code inline?
I do two things:
I put all my site's Javascript in one or more files;
I include that file or files on every page that uses any Javascript;
Those files are cached effectively such that they are only ever downloaded once (until they change); and
Pages call the functions they need from those external files.
If your site is one page then put it inline.
If your site is 20 pages and they all use a little bit of Javascript, put it all in one files, include it on every page and call the functions with inlien Javascript as necessary in each file.
I write about this and more in Supercharging Javascript in PHP. Sure it's PHP-specific but the principles are universal.
Basically every extra HTTP request is a problem. So if you have 20 pages each with a different Javascript file then that's a problem, even if those files are small. It's better to combine all that Javascript in one file, download it just once (with effective caching) and just use what you need.
To give you an example. External JS file contains:
function delete_user(evt) { ...}
function suspend_user(evt) { ... }
function unsuspend_user(evt) { ... }
One of your Web pages contains:
$(function() {
$("#delete").click(delete_user);
$("#suspend").click(suspend_user);
$("#unsuspend").click(unsuspend_user);
});
This way you get an external JS that contains all your site's Javascript but none of it is actually used. Use comes from inline code in the pages. This way there is no overhead of having the larger JS file.
Whatever you do, don't put in ALL initialization in your Javascript file. I once made this mistake and put a huge $(function() { ... } function into the external file on the grounds that if the relevant IDs weren't in the page, nothing would happen. There ended up being enough of this code to add nearly half a second to the page load time (and the site wasn't that big).
The browser shouldn't redownload the javascript file once it has it, so I would put it into the single Javascript file. That saves another connection/request to the webserver, and it keeps the code in one place rather than having script tags and code in your HTML/JSP/PHP/etc files. I.e., it's more maintainable, and it's very little overhead to get the code (unless it's a 1000 line monster! but that's another problem entirely) even if it isn't used.
Not that I don't have script blocks in some files, for very very specialised cases. In the end it comes down to what you are happy with - but consistency across the project is what is most important, so don't have a one off script in one place, and then do something different elsewhere.
ALWAYS put JavaScript in a file external to HTML. The problem with JavaScript that exists in page is that it typically exists in the global namespace, which could easily cause namespace collisions that makes code crash.
So, always put JavaScript in an external file.
With that said you should organize your code in an object-oriented manner. Try to capture an entire application representing a single point of execution to a single named function. Always write your code using a single var command per function, which should go at the top of the function, so that your code is easier to read. Ensure all variables and functions are declared with a var command or they will into the global namespace, which is potential failure. Put sections of execution of a giant function into smaller child functions, because this makes code easier to maintain when you can point to a particular named block when debugging or writing enhancements.
Also, always run your code through JSLint to verify syntax accuracy.
If you only have a small amount of code I don't believe it is worth the effort to split it up.
Depending on how much JS you have, consider a build process that can concatenate your separate JavaScript files into one, minified single download.
YUI is incredibly modular. They have a 'core' set of includes and then you can supplement these with the widgets you actually use. For instance, I have no interest in using their file uploader widget so never include the JS for it.
Cache the JS for a date far in the future. If you need to make a change, append a version stamp to the end of the SRC attribute, i.e. my-code.js?v=91
Use namespaces to avoid polluting the global scope. Again, YUI is very organised in this regard - see the YAHOO.namespace() function.
I would say put it in an external file. Chances are you will need to add new functions to it anyway, but also, from an SEO point of view, keeping it in an external file is preferable.
For only one function it would be better to code inline.
I won't include a 100KB Util script file for just calling a Trim function inside it.
If the file is already cached then it won't be a problem if you refer this in a page which calls only one function inside the file.
If I have a choice, I put the JS functions in external files, but not all in one file. Cache or no cache, I group files by their functionality and organize them similar to Java packages. If I have an utility function, say something generic like trim(), that goes to the top most JS file and all pages can use it. If I have something specific to a part of the site (unused in other parts) that goes in something like a sub-package, just for that specific part… and so on.
Of course you must use common sense so you don’t overdo it, and have let’s say a function per JS file. If you have fine grained JS files, that will affect you when your site evolves and you find yourself moving functions from sub-packages to an upper package or the other way around. I think one parent utility JS and one JS per site functionality should, most of the times, suffice.
I want to log to the console when I'm using un-minimized JavaScript files.
Comments are taken out already when I minimize JavaScript. I'm wondering if there's a way I can write a command that isn't commented out but will still be taken out when I minimize the JavaScript file.
I think I'd be pretty upset if a Javascript minimizer changed the behaviour of my code based on some funny/clever/odd code construct. How could you ever be sure that code construct isn't there intentionally?
As has been suggested, have a variable that disables logging. Then as part of your minimize script or batch job, you can swap that variable to its non-logging state using sed (for example) before minimizing.
If your goal is just to reduce the js size you can separate you logging functions into a separate file.
In your "main" js add a function function doLogging(object){} then in your separate logging functions file replace the function with function doLogging(object){/*your logging code*/};
Just remember to include your main js before the logging js. When you minify just comment out the logging script tags from the html. This way you will only have one (or a couple of) empty function definitions in the minified js and one line of code calling those functions per loggingn action.
Unless whatever you're using to minimize your JS supports conditional statements I don't think you can do this.
Why not just log things if a certain variable is set?