Some of the projects we're working on have strong roots in jQuery 1.4.2 or earlier, and somewhere between lacking the performance edge (or syntactic sugar) of the latest releases, the humiliation of using now-deprecated methods, and the discomfort of deploying a 3+ year old version of an actively maintained library, an upgrade is now imminent.
What are some practices popular in the community that we could adopt/re-visit to ensure a smooth rollout (i.e. focus on obscure compatibility issues, picking up global regressions, re-factoring some of the older code...)? How would they be best integrated into SDLC for future upgrades? What is a reasonable upgrade schedule for a library such as jQuery (I don't anticipate significant gains or justifyable costs to do so with every point release, but once every 6-12 months may very well be reasonable)?
To actually answer your three questions, here are some things I've done or at least recommend:
Best practices for a smooth upgrade rollout
Have tests. These can be unit tests for your JS and/or browser tests. These should cover at least the most typical and the most complex functionality used within your projects. If you don't have tests, write them. If you don't want to write tests, reconsider. If you reeeeally don't want to write tests, at least have a list of use cases that someone will be able to execute manually.
Make sure all your tests pass before the upgrade.
Read the release notes for every (major) version between the version you use now and the most current release. See also the Removed and Deprecated categories in the API docs. If any of your code uses jQuery UI, also look at those release notes and upgrade guides for the interstitial versions. As you do this, make note of the things you would likely have to change in your codebase (possibly making heavy use of grep).
If your project's current jQuery version is >= 1.6.4, also consider using the jQuery Migrate plugin to further assess the work required.
Decide on which version you want to be your upgrade target, based on the work required to get there, whether your project is using any third-party libraries that require a certain version of jQuery, other factors only you can consider, etc.
Meet with your team to go over the list of changes to be done to your codebase, and divide/assign the work accordingly. Maybe write some scripts or other tools to help out. If you have one, your team's coding style guide / best practices document may also need to be updated. Decide on one-shot (recommended) or rolling update releases, if that's possible+desirable. Come up with a suitable release strategy. (I recommend against releasing the upgrade as part of another unrelated large change to your codebase, so it's easy to roll back if you need to.)
Throughout the upgrade process, continually run your tests. When testing manually, always monitor the browser console for new errors. Write new tests that cover unexpected errors.
When all tests pass, decide on how you want to roll out--if it's a site, all users at once or a percentage at a time, etc. For a library or other project, maybe you'd release a beta/bleeding edge version that you can let your more ambitious users test out for you in the wild.
Document everything you just did so it will be easier for the next time.
[Profit.]
How to integrate upgrades into normal workflow
Again, tests. Make sure you have them. Make sure they're good, maintained, and cover a large portion of your codebase and use cases. A continuous integration setup to automate the running of these tests is highly recommended.
Consider getting your team to create and agree to follow a coding style guide or standard. This will make it easier in the future to search for deprecated function calls or constructs, since everyone would be following similar coding patterns. Tools such as scripts, commit hooks, static analysis utils, etc. to enforce good or sniff out bad coding style might be useful (depending on the team).
Investigate and maybe decide to use a package manager like NPM or bower to manage jQuery versions and other third party libraries you might use that depend on it. (You'll still need to maintain your own JS code and go through pretty much the same process as above.)
Again, once you're past version 1.6.4, make sure the Migrate plugin is part of your upgrade workflow.
Assess what worked from the initial big upgrade process, what didn't work, and extract a general process from this that works best with your current workflow. Whether or not you plan to upgrade every time there's a new version, there will be ongoing maintenance tasks and habits that you'd probably want to keep as general development best practices.
Reasonable upgrade schedule
That's essentially a CBA/risk management question. You'll have to weigh some things:
There should be no breaking API changes within the same major version, so you should generally be able to upgrade to the most recent minor version with minimal effort, no refactoring required. This assumes you have and maintain good tests, which you can run on your projects before you decide that all is well enough for a rollout.
Major version upgrades require more research, more refactoring, and more testing. After the research step, you should do a cost-benefit analysis of upgrading.
This might not matter much, but if any of your projects is a website that has many users, what would be the cost of making all of your users have to download essentially all of the changed JS files on your site the next time they visit it (instead of sticking with the older versions that are probably still cached in their browsers)?
The decision to upgrade should always be a subjective one. Minor or major, you'll still have to justify each time whether any upgrade would be worth it. Always read the release notes. Does it fix a security vulnerability or a bug related to issues that you or your users are currently experiencing? Would it significantly improve the performance of your project (be sure to have benchmarks to verify it later)? Does it greatly simplify a coding pattern you've been using, allowing your code to be written more cleanly and easily? Is there a third-party library you want to use that is dependent on this newer version? Are there third-party libraries you already use which are dependent upon the older version? (If so, are these libraries likely to be upgraded anytime soon to work with the newer version?) Are you that confident in your tests and QA process that an upgrade will take a reasonable amount of development resources and cause no major regressions? Were you thinking of eventually switching out jQuery with something else anyway? Etc.
Of course this is just my advice. There are a few recurring themes in it, and I hope they are clear. In any case, I hope someone finds this helpful!
You will always be outdated. Once you are done updating to the latest version, a newer one will come out a few months later.
Unless you are willing to put hours/days/weeks of development, testing and bugfixing, with the possibility of breaking user-facing functionality, you shouldn't be updating just to use the newest way of declaring event handlers. It won't hurt you. And normally this is a risky thing to do. This translates into dev team costs. You already know this. Refactoring, especially when there is no evident risk for the project, is in general hard to justify to managers. And you should double check your thoughts to be sure if having the new jQuery in code that is already working will make any difference.
Now, if you are working on creating new pages in an existing site, you could be including a new version in those areas. But, this will have a consequence: lets assume that you and your team, apart from developing the new part of the site, also have to maintain the part that is using the old one. Everybody will need to be aware of the specific version of jQuery they are writing their code against.
So, to close, I would say something like this. Unless there is real justifiable risk for the project to be delayed or to be technically blocked because of an older jQuery version, you are going to be getting into trouble for breaking something that is already working and will need to put extra hours just to make everything work as well as it was working before.
Anyway, this approach doesn't mean that you could start separating the 'new sections' from the old ones, and using the newest libraries in the new areas.
This is worth looking into: https://github.com/jquery/jquery-migrate/#readme
This plugin can be used to detect and restore APIs or features that
have been deprecated in jQuery and removed as of version 1.9. See the
warnings page for more information regarding messages the plugin
generates. For more information about the changes made in jQuery 1.9,
see the upgrade guide and blog post.
The Twitter guys have solved this problem quite nicely.
http://github.com/twitter/bower
It does what it says on the tin - it is a package manager for the web (and that includes keeping JS files like JQuery up to date)
In order to keep up to date in your development tree, I recommend using src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js" (the full un-minified version which allows for easier debugging)
Then when you go to publish, just replace it with the specific minified version that is in the header comment (currently http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js) This has the bonus of allowing better client side caching and using someone else's bandwidth.
If caching is less of a concern than ensuring that it will automatically get bugfixes for that minor version release, you can use just the major and minor version such as: http://ajax.googleapis.com/ajax/libs/jquery/1.9/jquery.min.js (Note: google doesn't yet have the 1.9 series up; however the 1.8 series is up to 1.8.3) Since these get updated periodically for bug fix releases they don't get cached like the version specific releases
In this era we cannot be predictable about the stability of the any software versions. Few years Before the versions of software and services releases after a year or two year. But at this time the versions of the services are updating rapidly and frequently.
So if you are using any service with your service you have to use Agile Development. By this development method you can easily make changes in the new requirements and change the required methods according to you.
And please don't use depreciated methods because they are not suitable for long-time service versions. And make libraries of the used services of library of your own service function that are using other services so that you can easily change them according to your new version.
For example : like you have a method name update_var(); it is calling a another method of other service like $a = newlib::check_update();. Then by creating libraries you have to change the main library of the function of your and the core library of the involved service
Related
i'm trying to figure out a way to make grunt write an incremental number or a hash on a file.
i have a file named config.yml which contains this:
version: 0.0.0
every time i change some files that i can specify somewhere (say all the .js and .css files), grunt should increment that number in some way.
i've seen some cache busting plugin but it's not what i am looking for as i don't want to have something like config.987234892374982.yml or config.yml?v=1.0.0 for example. i'm looking for a way to have grunt to find that number in that file, change it in a way that makes sense (incrementally ideally, or a random hash) and then save the file.
can you help in some way? thanks a lot!
I would seriously recommend against automatic version bumping for anything beyond the build number.
A version number is more than just an indication of how many times your product has been built. In essence, a version number is a semantic promise to your end user concerning compatibility with earlier releases. Node.js and npm and other systems using versioning are built around the core concept that X.Y.Z version numbers contain the following logic:
Software that doesn't have the same X version will have severely breaking changes that require those upgrading (or downgrading) to completely redesign the logic of how they use the software, and in some cases they even have to find alternatives because what they're doing right now doesn't work anymore.
Software within the same X version can relatively easily be swapped out without having to make sweeping changes to your own site or product.
Software within the same Y version can be swapped out without having to change any code, because it's supposed to be only bug fixes and security fixes. Only code that works around the things fixed needs to be changed.
Software within the same Z version has the exact same source, so if you have 2 copies of the same Z.Y.Z version, they can be used interchangeably.
This is the core contract that NPM and other package managers ask all their content providers to adhere to. In fact, it has already been shown that in some cases where content providers don't adhere to this versioning system, consumers of this content who assume semantic versioning apply have found their build to fail. Many consumers assume that if version 3.5.N works, that any version within the 3.5.X family will be interchangeable, and make use of that assumption by automatically building their code with the most recent version of the 3.5.X family.
Because of this, it's not a good idea to automatically bump versions beyond the build number. Bumping the patch version should only be done when you actually release a new version to the public, not after every build. Bumping the minor version should only be done when you have added new features to the product, but without the need for major changes to software that uses your product. Bumping the major version should only be done when you make drastic and destructive changes to your API, like moving and/or removing functions, function parameters, objects or attributes.
In my work I use dojo, and the experience I've had is that when a major browser upgrade occurs, some parts of the old version of dojo will break. In order to keep the web app working in the latest browser versions, you really have to keep updating to the latest version of dojo.
I'd like to know if this is the case for all javascript libraries, because I'm now working on a masters project which is a web app that my prof has already put into use. I'd like to use some of the nice functionality of a library, but I don't expect that I'll keep maintaining this project forever. I wouldn't want the app to stop working when browser upgrades come out.
Anyway if anyone has info or advice on this topic I would really appreciate it.
Of course this is the case for all javascript libraries.
Browsers come out with new features or break features that worked with older versions. The only thing a library can do is release an updated version that deals with breakages.
If the code is live and needs to keep working, this is all you can do.
The only way to mitigate against it is to stick to standards and only use common functionality that is not a browser hack within the library of choice (which limits you greatly and is not guaranteed to help).
This is much broader than JavaScript. When new versions of OSes come out, native apps need some tweaking. When new versions of software come out, plugins need some tweaking. Anything that relies on something outside of itself is likely going to need some maintenance when that "something" changes. It does tend to be worse for JavaScript, though....
That doesn't mean it's completely hopeless. You can minimize the issues by following some guidelines:
Read the documentation of things you rely on, and stick to documented behavior. Things you just beat on until they "seem to work" are much more likely to break later because they're more likely to rely on undocumented functionality. The more you code things correctly (i.e. how the framework providers expect you to), the more likely that it will stay stable.
Keep the number of things you rely on as small as possible. If you rely on six things, one of them is going to break. If you rely on two things, it may be a lot longer before there's a problem.
Look for frameworks with a long track-record, and look at how they've behaved during upgrades. Unless the development team has a strong statement that they've changed their approach, you should expect the future to look like the past.
Keep the things you rely on simple. The bigger and more all-encompassing the framework, the more likely that some parts of it will have trouble when there's an underlying change. The corollary to this is: keep what you're doing simple. The more complicated your make your program, the more likely it will have problems.
If complexity is required, then it is usually better to be in the framework than in your code. It is more likely that a broadly-used framework will be carefully written to try to avoid future breaks than something random you write of similar complexity.
In the end, complex requirements lead to complex features lead to complex dependencies lead to fragile upgrades. Keep your requirements simple, and your upgrades will be more seamless. There is a trade-off between flashy/fancy and long-term robust. If long-term maintenance is a high cost for you, then keep it simple.
Javascript libraries are not browser-dependent, it would be impossible to manage libraries if it was like that.
Your best bet is to go with JQuery... you might need to update it, not for compatibility, but for new, improved features at least. But it will be updated frequently enough to keep compatibility current. Remember that updating a library doesn't necessarily mean updating the code, thanks to backwards compatibility.
I have a simple question:
Would you rather use a plugin that is actively developed by the author(s) or use a plugin that is good in your perspective, but you know that it was last updated years ago and has no active support?
That is a tough call and depends on the circumstances. If you are responsible for a commercial software product you need to keep in mind that you always have to be able to ship product. If you can't because all the sudden the plugin doesn't work anymore some piece of the technology stack has changed you might have to face very unhappy customers ... In this scenario I would always go for plugins that are in active development/support and then only what is best for my team.
Staying mainstream has also its challenges. Each time you swap a tool, upgrade a piece of your technology stack, you take a risk. It is your responsibility as a software engineer to apply good judgement and then make the right choices.
For non-commercial projects I think it is less of an issue. If the old plugin doesn't work anymore you are under no obligation to find a replacement on short notice. In this scenario I would typically go for what works best for me.
I would use an old plugin if I felt that I could maintain it. In fact I already do use plugins that I've basically forked for one reason or another. Some plugins are small, and some are huge; it depends.
When jQuery goes through a major revision, it's not uncommon for APIs or behaviors to change.
I have noticed that sometimes people have to use multiple versions of jQuery in the same page (See question 1 and question 2). I assume people have to carry old versions of jQuery because some pieces of their code is based on an older version of jQuery. Obviously, this approach causes inefficiency. The ideal solution is to refactor the old code to use the newer jQuery API. I wonder if there are tools that automate the process of upgrading a piece of code to use a newer version of jQuery. I've never written programs in in either Javascript or jQuery. So, I'd like to hear from programmers experienced in these language about their opinion on this issue. In particular, I'd like to know the following.
How much of problem it is to have to load multiple versions of jQuery?
Have you ever had to load multiple versions of any other library in the same page?
Do you know of any refactoring tool that helps you migrate your code to use the updated API?
Do you think such a refactoring tool is useful? Are you willing to use it?
Please don't consider this question closed. Current responses have already gave me good insight about the process and tools available for upgrading jQuery code. But, please feel free to add your own experience with upgrading jQuery code.
your questions are all big. But from my personal experience except from very little problems in the first version which happened after migrating to later ones. Pretty much you should not run into any problems unless something is wrong with the code you have written and not jquery.
I have not seen any proper js developer who uses two different versions at the same time.
JQuery now itself offers a pretty nice api for unit testing called qunit. and if you start implementing test functions there you should be certain that your code works seamlessly.
I Use QUnit for heavy projects. which requires maybe alot of ajax requests etc. ofcourse it is not really worth it to use it for couple of animations etc.
I hope this information is helpful
Ignoring the fact that you can do this with JQuery, using 2 versions of any API is unusual and error prone. It is a rare practice, but at least with JQuery, it is done.
If I were evaluating a vendor's components for a new project and there was a requirement for an older library, I'd think twice before investing in that component. Vendors who supply tools that require old verions are one of:
1) Very cautious and stability minded (good)
2) Not up to speed (not too good)
3) Low on resources (bad)
4) Not motivated to update their tools because not enough people are demanding the tool (really bad)
Of course (5) could be that their tool is so good and they have such a big customer base they don't feel the need to update it. That is ok as far as it goes, and eventually goes back to one of the other issues.
I use enough 3rd party tools to know that sometimes, a tool does a job so well that I pick it anyway, but in general, I want a tool to be current for a new project. There are a lot of "fly by night" vendors out there that just aren't maintaining their products and you don't find it out until you ask for support or new features.
I also use two versions of jQuery on the same page sometimes, but for a different reason. This is code that runs as a third-party widget on the page; in that situation you cannot count on a specific version of any libraries being present.
If you need a library such as jQuery in such code, it's safest to load your version and do something such as myNamespace.jQ = jQuery.noConflict(true) so that you have a namespaced, separate version that you can rely on, and that is decoupled from the rest of the page.
That way, if that page changes their code, your third-party code won't be affected. In this case, by eliminating possible dependencies on the library version in someone else's code, I'd argue that using multiple jQuery versions actually facilitates refactoring.
I have developed one of my modules using Dojo. Its gone really well and I have done a lot of custom plugins and server support in Dojo to allow AJAX calls, RPC + SMD communication with my server.
However, now that I am getting onto the user side of things, I am seeing that jQuery has some really nice already built plugins. Do you think it is possible to support both JS libraries realistically without it being a massive problem?
What kind of integration can I achieve? Does anyone have experience in this?
I have probably written somewhere in the region of 30k lines in Dojo for my Administration panel...
jQuery is very good about not messing with the prototypes of built in javascript objects (unlike Prototype), this allows it to be used with other libraries quite easily.
A source of potential conflict is jQuery's use of $ as a shortcut for jQuery. I'm not a dojo user, but if this conflicts with dojo in some way, there are instructions addressing this.
That said, I think you'd be better off looking at these jquery plugins and rewriting them and porting them to dojo. I'm sure the dojo community would appreciate it, and it would give you experience. It'd also make your application a little slimmer in the waist area.
Edit: I've noticed a couple answers trivializing the download speed of adding an additional library. I'd take this with a grain of salt.
As developers we tend to see only the extra 10ms it takes to download the library over localhost, or from our development server on a 100 Mbit LAN. The download speed is not so trivial from California to Virginia, or especially from USA to Europe. Additionally, it adds further burden on your client's javascript engine. If they are using a 1-2 year old good computer with Safari or Chrome, this would be negligible, but if they're on IE, FF2, or some versions of FF3 the difference can be severe, or at least measurable.
When using 2 libraries (both of which, I'm sure - were designed to be used by themselves) you have 2 main worries:
That one library will effect the other.
That having a dependency on 2 libraries will bloat your pages.
In this case, I would bet that #1 is not going to happen. Although #2 is still a concern.
Most of the popular JS libraries can be scoped to their own global shortcuts. JQuery can be set to not initialize the $ variable. JQuery aside, I hear that Dojo and Prototype can work together without conflicting.
Regardless of what combination of JS libraries you decide to use, the best way to get information on compatibility issues is to hit the mailing lists relevant to the JS libs you'll be using with each other.
http://docs.jquery.com/Using_jQuery_with_Other_Libraries
http://www.dev411.com/blog/2006/06/13/dojo-and-prototype-together
Query.noConflict() makes for fairly easy interoperability because you can redefine $. As hobodave draws attention to, Prototype is lousy in this regard (because you can't easily just redefine $ with Prototype). I am not sure but I think Dojo doesn't have any issues of it's own and plays nicely with others out of the box (please someone correct me if that's not true).
The biggest problem I've had is the number of "must have" libraries written in specific frameworks, such as for things like sophisticated graphing that would be non-trivial to implement from scratch.
Bloat is bad, but compared to image sizes JS script sizes are of negligible concern (because it's so small and connections are so fast and it's only on first page load if you get your caching right, it's almost a non issue). I'd say maintiainablity being more of a worry, and it's a matter of deciding if you want that must-have-plugin that you don't have the time or inclination to reinvent in whatever framework you are using.
I have used Prototype, jQuery, and ExtJS on several projects (for various reasons) and almost always use jQuery and ExtJS together. One way to limit trouble would be to avoid mixing libraries in any given page - keep Admin page to dojo and new pages to jQuery - but what fun would that be? :-)
I find few problems when integrating jQuery and ExtJS. I pick a framework for classes/objects/inheritance (I use ExtJS) and stick to it. Then, I use ExtJS to create most widgets and I use jQuery for low-level DOM manipulation and simple widgets. Again, I cannot recall running into conflicts when using two libraries, but FireBug is a good tool to uncover suspected causes of such conflicts.