I'm sure this is a bad idea for technical reasons but haven't found any source explaining if it is or why.
Let's say I'm building a React website and want to use two component frameworks, like ant.design and material-ui because I love 90% of what ant.design does but I just slightly prefer the modal dialogues in material-ui more and want to use those in conjunction with ant.design components.
They both seem to play quite nicely with each other.
Why is this a bad idea? Is there potential for conflict in future? Does this increase bloat somehow?
You may want to refer to this question asked yesterday for a little pointer:
How to make Bootstrap 3 and Ant Design 3 live together
As pointed out above:
Bloat - the unnecessary inclusion of code you do not need, which can be avoided through custom builds.
Duplication/Overwrite - code included by duplicate existing or merely serve to overwrite existing rules making the code 50% pointless.
Conflict - issues may arise from conflicting JS code, not least from the potential to have conflicting version dependencies.
Namespacing - as identified in the linked question, it is impossible to namespace the antd css to avoid collision with bootstrap.
Code Styles - No two libraries will be implemented in exactly the same way and you will find yourself having to navigate issues that arise from this.
In my own experience I have never found a single library/suite that delivers everything, but the closest I have found to this is Ant Design.
Visually it may not be the best, and there may be implementation/pattern issues that some developers do not like, but the reality is that the less you have to build, the quicker you can deliver, and end users will care more for functionality than they will the way your app looks. The priorities you place on these things will differ from them for sure.
I personally love the look of Material UI and others, as highlighted here:
https://hackernoon.com/23-best-react-ui-component-libraries-and-frameworks-250a81b2ac42
But the reality is, you need to look to which single framework and set of components provides the best and most complete functionality you actually require.
In my case, as mentioned, this was Ant Design; being the only one with a strong set of UI components including Date Pickers etc, without having to add more and more components into my codebase via NPM.
Related
This question is about possible higher-level approaches that one could take to applying version control to React components. Specifically, these components should be more on the "atomic" end of the spectrum, i.e. doing one thing powerfully in a variety of contexts.
Specifically, I'd like your thoughts on versioning such components at scale, whilst addressing issues such as:
Cross-project usability (i.e. <Button /> component in both of my React apps);
Theming (how themes and styles can be shared across these components); and
Dependencies (e.g. version 1.0.5 of <StackedButton /> depends on version 2.1.0 of <Button />)
I've been looking into Bitsrc.io as a possible tool to help me manage this. I've been largely addressing these issues by having quite a few (~10) Git repositories, each managing a loosely coupled set of components, e.g. text-components, layout-components, table-components, but I feel like I'm at a point, where with the number of components and the dependencies they have, further maintainability may be sacrificed if I make the wrong decision.
I've had some success using lerna; I think it might fit your needs pretty well. You basically would combine all 10 of your repositories in a single one, with each one now being a package within the repository.
Lot of advantages to this approach. Mainly, it lets you still have separate published packages, giving consuming apps flexibility on what they want/don't want to pull in, but it removes a lot of the overhead of having a lot of packages. It becomes much easier to make sweeping changes, and it's impossible for your packages to get out of sync, since they're always updated together. If you make a breaking change in one package that another package relies on, you would fix the package in the same PR as the breaking change.
Large web applications tend to accrue a huge array of libraries that support both front-end and back-end functionality. I want to reduce the number of dependencies in order to increase stability and ease of maintenance. I'm looking for a good path to reducing dependencies in a web app that includes libraries such as:
Bootstrap
CKEditor
Chosen/Select2
jQuery plus various plugins
d3/Raphael
SlickGrid
Handlebars
Underscore
I'm looking for techniques, languages, or frameworks that combine as many of those dependencies as possible.
Here's what I've explored so far:
Refactoring small dependencies and removing unused parts could go a long way.
React would impose discipline on the jQuery spaghetti code and reduce the need for a few of the dependencies.
Elm would go farther towards imposing discipline with its type safety.
ClojureScript would also impose discipline through a functional programming paradigm.
Except for refactoring, all of these potential solutions would introduce some additional complexity of their own in order to integrate with the Ruby on Rails back-end. React seems to have the most replacements for the current dependencies.
The safest path forward seems to be to start with refactoring and gradually introduce one of the functional languages or libraries. How would I refactor with this goal in mind? Would first refactoring to plain JS (i.e. removing jQuery) be useful?
Libraries/dependencies
Usually when I inherit a large project to refactor, the first thing to do is determine the core dependency e.g. what's the main library most of your custom code uses? From your list I can already tell underscore and jQuery are basically trying to do the same thing. Which one is the most optimized and fastest has been gradually leveled during the years. Let's assume for a second Underscore is still the fastest, you're still depending on jQuery for traversing and what not. Are you willing to include an extra library to gain micro speeds? The extra payload for each page is not worth it in my opinion.
Then Bootstrap is most likely your main CSS driver, however, it has some JavaScript abilities which might be used. Carousel, date-picker, drop-down, toggle some other widgets ... See if they are used (probably yes), if not, get rid of the Bootstrap js library. Keep in mind Bootstrap is still depending on jQuery.
Chosen/select are optional plugins. They're goal is most likely covered in Bootstrap/jQuery. Try to refactor them out.
Slickgrid is also a grid system. What's the benefit over the Bootstrap grid? Sounds like they refactored out Bootstrap. If it's used, refactor to a bootstrap grid to increase the common knowledge of the team.
Handlebars for templating. If you use the logic operators it's useful, otherwise you can easily find a small replacement function.
function renderTemplate(obj, template) {
var tempKey, reg, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) {
tempKey = String("{{" + key + "}}");
reg = new RegExp(tempKey, "g");
template = template.replace(reg, obj[key]);
}
}
return template;
}
CKEditor/Raphael are libraries with one specific goal in mind => wysiwyg/vector. Best to keep those but lazy loading sounds ideal. Only include them on the page when they are needed.
// after the additional library was loaded ...
cacheObj1.on('focus', this.initCKE);
cacheObj2.on('click', this.initVector);
If you're server language handles <script> includes into the <head> tag, you can choose to keep simple script references, required by the specific page in mind. Don't end up with twenty DOM ready events inline, try to end up with just one ready event to initialize everything your project needs.
jQuery plus various plugins
Bootstrap
Handlebars
CKEditor refactor to lazy loading
Chosen/Select2 refactor to core lib
d3/Raphael refactor to lazy loading
SlickGrid refactor to core lib
Underscore refactor to core lib
Application/custom JS
Now the tricky part begins. How good are your JavaScript skills and how decent was the previous programmer? If you find a lot of jQuery selectors all over the place, chances are high it's not programmed in a modular approach. The hard task of refactoring every peace of code to something configurable begins.
The idea here is to have an instance or loader file which talks to your libraries. Perhaps a custom function file (which can hold underscore functions if you prefer) to use throughout your code. Prototypes or "classes" and singletons to finish it off. A nice post about refactoring if I may add with links on how to set this up. Then a grunt/gulp setup is nothing too fancy these days. Automation for JS(npm, bower) and CSS(compass, less) can be covered on the fly.
Conclusion
jQuery is most likely your main dependency. So you will start from scratch if you take it out. All the plugins you talk about is the extra fat on page load. The less the better, but sometimes it pays off just to RE-USE other functionalities like cookie scripts, json support, polyfills, ... the list goes on and on. Try to stick with one or two core libraries and clearly separate dependencies and application code.
Don't forget to bundle and minify ^^
Happy refactoring!
I have been using JavaScript and jQuery for quite a while now and want to extend my skill set further, during my search I came across two popular names Angular and Backbone and while reading about them I found one line common in both them which somehow also seems to be their USP i.e.
It is designed for developing single-page web applications
This makes my confused.
What is that I cannot do with JS or jQuery and I would require these?
I have created web application on single page, where users can perform CRUD operations on single page through asynchronous calls so why so much importance of for these others libraries?
And as a middle level web developer who has have good hands on JS is it right path to move to these two or here is something else I should look into before these?
Please help?
Structure.
In an ongoing project that started about 4 years ago we built the front end with jQuery. We were able to do just about everything that we needed creating several single page applications that were quite functional.
As the project progressed and the code base grew we started experiencing some major problems with maintainability of the code. We ended up with hundreds or thousands of lines of JavaScript code per page in a tangle that was almost impossible to navigate. This could have been avoided if we were more careful of course but at the time we focused on making sure the back end architecture was robust.
Many years ago the community learned that code needs structure to be maintainable. We developed MVC patterns, multi-tiered applications etc. But JavaScript was never a big player in the field and we largely ignored it.
Over the last 6 months or so we introduced Angular into the project and started sorting out some of the mess in the project. The results are remarkable. Not only is the code simpler and easier to create, the structure makes it easier to implement tests, easier to maintain and generally a huge improvement over what we had before. We still use jQuery but now we have been burnt by the lack of structure and know a thing or two about the architecture of a JavaScript application. Angular and its like provide you with the tools to architect a good application.
When you are creating larger scale web applications it is wise to check out Backbone, Angular or perhaps Meteor. jQuery supports neat tricks, but it does not help you structure your code in a maintainable way. Larger scale web apps build on jQuery need their own vision on how to separate the code into layers with their own responsibility.
The other frameworks give more support.
I would suggest checking out at least one of the libraries. Perhaps you eventually won't use them, but it will benefit how you work in jQuery.
Well Now a days there has been quite a hype about Angular.js and especially SPAs (Single Page Applications). Well to be honest, I had the same question in my mind about a month ago when my team decided to shift from Jquery to Angular.
Whenever it comes to Jquery, one of the first thing that comes in our mind is the DOM manipulation. While using Jquery we always think of manipulating the DOM. Show/hide elements, animating elements, getting data from tags you name it. But Angular offers something more than that. It offers you an architecture, a way to structure your applications at the front end.
So whenever you go for Angular.js, change the way you think about creating web applications (and believe me its worth it). Most of Angular's structure uses the concept of Dependency Injection which is a neat way to maintain your code.
Backbone is only a library whereas Angular.js is a complete framework to create and manage Single Page Applications
Talking about the fact that Angular.js should be used when we are creating large scalable apps, it is true. In my case the team I work with is full of Jquery Ninjas. We have been creating a great app for the last 3 years and believe me it became difficult for us to maintain and debug thousands of lines of Jquery. This is the main reason we have decided to revamp this app into Angular.
Kindly see some of these Helpful links. You will get a better idea.
http://net.tutsplus.com/tutorials/javascript-ajax/3-reasons-to-choose-angularjs-for-your-next-project/
"Thinking in AngularJS" if I have a jQuery background?
Coming from Java, I'm wondering if a Java best practice applies to JavaScript.
In Java, there's a separation of interface and implementation, and mixing them up is considered a bad practice. By the same token, it is recommended to hide implementation details of your library from end developers.
For example, log4J is one of the most popular logging libraries out there but it is recommended to write code to the slf4j library or the Commons Logging library that "wraps" log4j. This way, if you choose to switch to another logging framework such as logback, you can do so without changing your code. Another reason is that you, as a user of a logging library, how logging is done is none of your concern, as long as you know what logging does.
So back to JavaScript, most non-trivial web applications have their own custom JavaScript libraries, many of which use open source libraries such as jQuery and dojo. If a custom library depends on, say jQuery, not as an extension, but as implementation, do you see the need to add another layer that wraps jQuery and makes it transparent to the rest of JavaScript code?
For example, if you have the foo library that contains all your custom, front-end logic, you'd introduce the bar library that just wraps jQuery. This way, your foo library would use the bar library for jQuery functions, but it is totally oblivious to jQuery. In theory, you could switch to other libraries such as dojo and google web toolkit without having a big impact on the foo library.
Do you see any practical value in this? Overkill?
Although it makes sense from a theoretical standpoint, in practice I'd say it's overkill. If nothing else for these two reasons:
Anything that adds to the size of
the request (or adds more requests)
is bad - in web world, less is more.
If you're using say jQuery, the
chances of you switching to
something like Mootools is (imho) slim to none. From what I've seen, the top libraries each aim to solve different problems (at least in the case of Mootools and jQuery - see this great doc for more info on that). I'd assume that you'd incur a tremendous amount of headache if you were to try to implement a middleware library that could easily switch between the two.
In my experience and being a Java developer myself, sometimes we tend to take the whole "abstraction" layer pattern too far, I've seen implementations where someone decided to completely abstract a certain framework just for the sake of "flexibility" but it ends up making things more complicated and creating more code to maintain.
Bottom line is you should look at it on a case by case basis, for example you wouldn't try to create an abstraction layer on top of struts, or on top of JPA, just in case you then go to a different framework (which I've rarely seen done).
My suggestion is, regardless of the framework you are using, create objects and components that use the framework internally, they should model your problem and be able to interact between them without the need of any specific framework.
Hope this helps.
There are a lot of good answers here, but one thing I don't see mentioned is feature sets. If you try to write a library to wrap the functionality provided by, say, jQuery, but you want to be able to easily swap out for something like prototype, you have a problem. The jQuery library doesn't provide all the features prototype provides, and prototype doesn't provide all the features jQuery provides. On top of that, they both provide their features in radically different ways (prototype extends base objects -- that's damn near impossible to wrap).
In the end, if you tried to wrap these libraries in some code that adds 'abstraction' to try to make them more flexible, you're going to lose 80% of what the frameworks provided. You'll lose the fancy interfaces they provide (jQuery provides an awesome $('selector') function, prototype extends base objects), and you'll also have to decide if you want to leave out features. If a given feature is not provided by both frameworks, you have to either ditch it or reimplement it for the other framework. This is a big can of worms.
The whole problem stems from the fact that Java is a very inflexible language. A library provides functionality, and that's it. In JavaScript, the language itself is insanely flexible, and lets you do lots of crazy things (like writing a library, and assigning it to the $ variable). The ability to do crazy things lets developers of javascript libraries provide some really creative functionality, but it means you can't just find commonalities in libraries and write an abstraction. I think writing javascript well requires a significant change in perspective for a Java developer.
Someone wise once said "premature optimization is the root of all evil." I believe that applies in this case.
As others have expressed, you don't want to abstract for the sake of flexibility until you have an actual need for the abstraction. Otherwise you end up doing more work than necessary, and introducing unnecessary complexity before it is required. This costs money and actually makes your code more brittle.
Also, if your code is well organized and well tested, you should not be afraid of major changes. Code is always changing, and trying to anticipate and optimize for a change that may or may not come will almost always get you in more trouble than it saves you.
Acknowledgement: I should give credit to Agile programming and my practice and readings on the topic. What I've said comes directly from my understanding of Agile, and I've found it to be an extremely good razor to cut out the extra fat of my work and get lots done. Also none of what I've said is actually JavaScript specific... I'd apply those principles in any language.
There are good arguments calling this development practice - wrapping in order to switch later - into question in any language.
A good quote by Oren Eini, from his writeup on wrapping ORMs:
Trying to encapsulate to make things
easier to work with, great. Trying to
encapsulate so that you can switch
OR/Ms? Won’t work, will be costly and
painful.
This is definitely something that is done in enterprise environments.
Take for example a company that has their own custom javascript framework that is used on all of their projects. Each of the projects decide to use their own framework (jQuery, Dojo, Prototype) to add functionality to the underlying modules of the company framework. Employees that move between projects can now easily do so because their API with working the project's codebase is still the same, even though the underlying implementation could be different for each project. Abstraction is helpful in these situations.
It is overkill. Javascript is not Java and is not in any way related to Java. It is a completely different language that got J-a-v-a in the name for marketing reasons.
If you are concerned with availability of add-on libraries, then choose a framework with a large ecosystem. In an enterprise environment you will be further ahead by standardising on a vanilla off-the-shelf uncustomised web framework that you can upgrade every year or so tracking the rest of the world. And then supplement that with a SMALL in-house add-on library which you will, of course, have to maintain yourself, not to mention training any new programmers that you hire.
Since you are talking about Javascript in the client (web browser) it is more important that you limit the complexity of the things that people do with it. Don't build huge amounts of client side code, and don't make stuff that is so brittle that another programmer can't maintain it. A web framework helps you both keep the linecount down, and keep your own code reasonably simple.
It is not a question of Javascript best practice, because that would be different for server-side JS such as Rhino or node.js.
Adapter pattern is not a common solution in this case. The only example I know to use this pattern is extjs. Javascript projects are usually too small and they aren't worth the effort you would make by creating such an abstraction layer.
The common solution for this problem is that you try to use multiple frameworks together for example with jquery.noConflict.
I've done this before, and can talk a bit about the experience of writing a library/toolkit wrapper.
The plan was to move from Prototype to some other library. Dojo was the first choice, but at the time I wasn't sure whether that's the library to move everything to (and by everything I mean ~5MB of Prototype-happy JS). So coming from a world of clean interfaces, I was set to write one around Prototype and Dojo; an awesome interface that would make switching out from dojo a breeze, if that was in fact necessary.
That was a mistake that cost a lot of time and effort for a few reasons. The first one is that although two libraries can provide the same functionality, (a) their API will almost always be different, and most importantly (b) the way you program with one library will be different.
To demonstrate, let's take something as common as adding a class-name:
// Prototype
$("target").addClassName('highlighted');
// Dojo
dojo.addClass("target", "highlighted");
// jQuery
$("target").addClass("highlighted");
// MooTools
$('target').set('class', 'highlighted');
Pretty straight-forward so far. Let's complicate it a bit:
// Prototype
Element.addClassName('target', 'highlighted selected');
// Dojo
dojo.addClass("target", ["highlighted", "selected"]);
// jQuery
$("target").addClass(function() {
return 'highlighted selected';
});
// MooTools
$("target").set({
"class": "highlighted selected"
});
Now after choosing an interface for your version of the addClass you have two options: (1) code to the lowest common denominator, or (2) implement all of the non-intersecting features of the libraries.
If you go with the 1st -- you'll loose the "personality" / best qualities of each of the library. If you go with #2 -- your addClass' code will be at 4 times larger than the ones provided by any of the libraries, since for example when Dojo is included, you'll have to write the code for the function as the first param (jQuery) and the Object as the first param (MooTools).
Therefore, although it is theoretically possible, it isn't practical, but is a very nice way to understand the intricacies of the libraries out there.
Ext.js is of interest to me because it appears to have a fairly complete widget set (though I've certainly run into shortcomings of the widgets after a very short time). The problems I potentially have with it, however, include these:
in my opinion it's very ugly, and looks like a cross between a Windows UI and some PHP content management system (yes I know I can write my own theme, but there may be limits to what I can change, and it may not be as easy as it should be, and I'd rather work with something that is clean, elegant, and attractive out of the box.)
the graphs currently use Flash, which limits the clients it can be useful on (version 4 promises to resolve this problem)
the license is a bit restrictive, which is not an issue now, but it makes me think twice about becoming intimately familiar with a tool that I may not be able to use in the future.
Honestly the look & feel is probably the biggest issue to me: I've seen in the past that developers (or companies) who don't place a high value on aesthetics often can't be bothered by other 'details' either.
So: is there a other better alternative?
UPDATE:
Another problem with Ext.js, is that it seems to be an all-or-nothing proposition. That's one reason I'm not looking seriously at SproutCore, which in other respects is awesome. (Well... it needs some performance improvements, but it'll get there eventually I think...)
Cappuccino seems to be the same way: you're not using it on a web page, rather you're building a Cappuccino app that just happens to use the web as its runtime environment.
In other words, ideally I don't want a JS version of Flex: it's own little walled garden. jQueryUI would be ideal if it were more complete, since it doesn't break with normal web development methods and paradigms. But if walled gardens are all there are, I'll live with it.
If you are looking for a RIA-Framework you shouldn't use jQuery(UI). Instead use one of the following frameworks.
Qooxdoo (www.qooxdoo.org): Pure Open-Source RIA-Framework with the most of the features of ExtJS. There were coming up some interessting new themes in the last weeks
Cappuccino (http://cappuccino.org): Nice framework with a nice GUI
ZK (http://www.zkoss.org/): ExtJS like RIA-Framework
SproutCore (http://www.sproutcore.com/): Apple-Style RIA-Framework
I undestand your pain - I use to got same - in ExtJS I saw only problems (those what you mentioned, and belive me much more others), however because I was a little forced to use it, I started to use it and I followed in love - It very complex and optimal solution for javascript driven apps.
You can go and look for alternatives like jQuery (I was there for 1 year), dojo, and others frameworks, but whoever says that they are better than ExtJS, he rather did not have ..... time to know ExtJS
It my very subjective opinion
I dont know much about PHP, and I am using ExtJS with ASP.Net MVC, they fit well. I wish I could use an integrated JS Widget set, but Jquery UI widget set was not rich enough when I last evaluated and I dont think it still is. But it is at least included in the last version of MVC.
My only complain about ExtJS would be the number of user extension controls that you need to use, I'd like to see those as part of ExtJS core widget set, but they are not, but still distributed with the library. ExtJS is a very nice fit for a cross-platform Rich Web Application. I would recommend trying ExtJS, I have really no complains about it other that what I already said above.