📜 ⬆️ ⬇️

We build our full stack on JavaScript: Client


JavaScript on the client is changing rapidly: libraries, frameworks, packers quickly appear and replace one another. But despite this, many key operations are the same for any client application. And in modern front-end frameworks, with all their diversity, there is much in common.



The article is based on the code of the project Contoso Express .


List of resources where you can get acquainted with some of the topics of the article here .


A bit of history


Web standards are changing slowly: for example, the latest version of HTML 5 was approved 2 years ago, and the previous XHTML first appeared in 2000, i.e. The gap between the new versions was 14 years. At the same time, nothing fundamentally new appeared in the new version. CSS is also developing not fast: the first time I heard about the flexbox layout in 2012, 4 years have passed, and now, it seems, you can use it if you are satisfied with partial support in IE11, and its absence in earlier versions. Even JavaScript is not changing as fast as it may seem: before the recent update of ES6, the previous major version 5.0 was released as much as 6 years ago. At the same time, the emergence of a new standard does not mean that it can be used immediately. It should take a long time until all the major browsers will support it (and for IE you can not wait).


However, requirements for client applications are constantly growing. Google raised the bar by releasing Google Maps and the Gmail client, an interactive SPA (Single Page Application) with an unprecedented level of usability, back in 2005. Such applications were difficult to write, and not every company could afford it. They became widespread relatively recently (3-4 years ago).


In order to write complex SPA applications that would be supported by the main browsers, it is necessary to use various auxiliary techniques, and it is in this area that changes are constantly taking place.


SPA


SPA is becoming a standard in modern web applications, providing the best level of user experience (user experience). The application loads the main resources (styles, code, markup) when the page is first loaded, after which subsequent state changes occur on the client. Data from the server is loaded via AJAX requests, HTML is rendered on the client based on HTML templates or directly from JS (React).


This is different from the traditional architecture, where every state change requires reloading the updated page from the server.


Web applications can be written as a set of several SPA modules or combined with parts operating in the classic mode of postbacks (round trips). In Contoso, authentication pages work through postbacks, the rest of the application is done as a SPA.


Style Preprocessors


CSS syntax has a number of flaws, which are eliminated by preprocessors - add-on languages ​​over CSS: LESS / SASS / Stylus


Major standard CSS improvements:



.my-class { background-color: blue; div { background-color: red; // -> .my-class div { background-color: red; } } } 


 @myPadding = 10px; .my-class { padding-top: @myPadding; // 10px padding-bottom: @myPadding + 5px; // 15px } 


 .error { color: red; font-weight: bold; } .admin-error { border: 1px solid black; .error // -> .error styles inserted here } 

Preprocessors make it easier to write and maintain styles, especially if there are a lot of them. LESS is used in Contoso , although now SASS is more popular, the difference between them is not big.


Choosing a CSS framework


CSS frameworks provide a set of template styles that make it easy to position elements (Grid System), override the standard style settings (HTML looks nice by default), and provide a set of widgets with JS included, such as modal windows, navigation menus, date picker, etc. d.


Basic options:


Bootstrap is the main choice and the first mass css framework. Originally created by Twitter, well suited for both desktop and mobile development. A large set of components. Due to the high popularity of the site on the bootstrap may look like a template.


Foundation is a popular choice, a good set of components and a convenient positioning system.


Semantic UI - focuses on well-designed semantics (naming) of classes of elements, not so good for mobile development.


Material Design is not a framework, but style recommendations from Google that are used in the company's products (Android). There are implementations of this design for React Material UI and for other JS frameworks.


Additionally, you can use the library with a set of icons in the form of a font, the most popular of these Font Awesome .


Contoso uses Font Awesome and Bootstrap.


We select client JS framework


Let's look at the main options:


JQuery is a library that allows convenient direct manipulation of DOM elements with a single interface for different browsers, is well documented, supports AJAX requests and writing plug-ins. Poorly suited for writing complex client applications, does not provide reactive data binding capabilities.


Reactivity in client JS libraries is the ability to dynamically link data (model) and display (HTML view). When a model changes, the display changes automatically (reactively), and vice versa, a change in the display state (the input value changes) changes the model. Here is a jsfiddle link to a simple example of reactivity using Vue.js.Evaluate how much simpler this is than to perform all DOM manipulations manually.


Angular 1.X - the first mass-popular jet framework (there were others, for example Knockout). In addition to reactivity, Angular provided a way to structure the organization of the application, support reusable components (directives), and more. Unfortunately, Angular 1.x is overly confused, has many crutches, is difficult to study and develop, especially as regards reactivity. There are performance issues. Initially, Angular was an independent open-source library. It is then developed and maintained by Google. Angular reached a peak of its popularity in 2014. React is actively supplanted in the future.


React - unlike Angular, this is a library, not a framework, which is designed to generate client mappings. Uses the Virtual DOM technique for faster rendering. This allows React to completely re-render the display each time it changes data, without significant damage to performance.


React is recommended for use with Flux architecture, where data changes always occur in the same direction. Initially, these models are initiated, a display is built on them, the display generates an event that changes the state of the model, which entails updating the display. This makes it easier to understand how state changes occur in an application and makes development much easier.


React involves the use of JSX, which allows you to operate XML (HTML) syntax inside the JS code. This is used instead of traditional HTML templates. JSX makes it possible to use all the features of JS to generate templates, but it can be more difficult to support and collaborate with layout designers. React was created by facebook and is used in some of their projects.


Angular 2.x is the most recent framework (final release September 2016). Focused on the development of complex client applications, excellent performance. Written from scratch and has little resemblance to Angular 1.x. Reactivity is implemented in a much simpler way: native HTML attributes (for example, click, not ng-click) are used for buying. It uses many advanced features of TypeScript: for example, Dependency Injection is implemented through the class constructor and the type of the variable (as in C # / Java). Intensively used decorators. To work Angular requires the connection of third-party libraries (zone.js) uses polyfiles and overrides many standard browser functions. At the moment, it is not clear what will happen with the standard practice for the organization of the system state. Angular 2 can work with Flux architecture (for example using Redux), but Flux is not recommended as the only true architecture.


VueJS is a great alternative to React / Angular. Adheres to the principle from simple to complex (progressive). It's very easy to start with Vue by getting basic reactive capabilities, but at the same time, Vue can be expanded by adding everything you need to build complex SPAs. Vue is easy to integrate, it is fast and intuitive. For a long time, it has constantly been on the JS trending repos list on GitHub and there are good reasons for this. Template syntax is similar to Angular2. To store the state, Vuex with Flux architecture is used. The 2nd version of Vue is coming out soon, where, among other things, performance is improved (with Virtual DOM) and optionally the ability to use JSX is added.


Others - a lot of frameworks / libraries. If you are interested in considering other options, you should look at the TodoMVC site where the implementations of a simple TODO application sheet on various MV * frameworks are compiled.


What to choose


It depends on the specific project. If you are going to build a complex SPA application from the very beginning, then you should try React, as the most popular option for today. But it will take some time to learn new concepts and set up the environment.


If you want a simple solution that can be expanded along with the development of your project, Vue is an excellent option, although it is not so popular and not supported by a well-known developer company.


If you have a complex application, the release of which will not be soon, and you are focused on the future, you can try Angular2.


I would not recommend starting new projects on Angular1, it is better to use Vue for this, it has a very similar syntax, but it is much simpler and more convenient for work.


There is still a performance issue. Many articles comparing different frameworks devote a lot of time to this issue. You need to understand that for most applications, client performance will not be a problem, performance is important if you need to dynamically render large amounts of data or your application will be actively used on low-performing mobile devices. Nevertheless, here is a table with tests of various JS frameworks.


Another criterion for selection is a set of plugins / libraries for a particular framework. In this regard, React / Angular1 is clearly leading, although for VueJs there are already many auxiliary libraries of components, and for Angular2 their number should rapidly grow after the recent release. In the Awesome Lists repository you can find an awesome (delightful) list of resources on the framework you are interested in.


In the future, I will describe various aspects of writing client applications with implementation features on React / Vue. In Contoso, the main version is made using React, there is an alternative branch on Vue, I also wanted to add a branch with the implementation on Angular2, but unfortunately, the framework ecosystem is not yet stable (libraries and tools using Angular2 have not yet fully adapted to the new release) .


Structure


The structure of the client part depends on the chosen framework. In Contoso, the common part for client implementations (React / Vue) are:


Services (services) - data access modules via API. If necessary, additional data transformations take place here.


Formatters (formatters) - provide formatting of data on the client (date, currency, display name, etc.).


Helpers - perform such common client operations as AJAX requests, configuration access, pop-up message display, and the like.


In addition, there are parts that are implemented depending on the chosen framework:


Components (components) - the building blocks for the client interface. All modern frameworks support the creation of a UI as a component tree, but the specific implementation is different. Usually components are grouped into folders depending on the functionality (Project, UserAccount, Orders, eg).


Separately, the state (data) and system events are stored: for React, these are the 'actions', 'store', 'reducers' folders, for Vue - the 'vuex' folder.


Routing


With the classic organization of a web application, different routes (URLs) download different pages from the server. In the SPA application, all data is loaded immediately. When switching to another page, a new page is not downloaded from the server and the URL remains the same.


This is not very convenient for the user: he can not save the current link in the browser, can not use the forward / back buttons to navigate between pages.


There are several ways to add routing to the SPA:



For each client framework there is a separate library for routing.


Contoso uses the History API (pushState) mode.


Using client routing requires a bit of configuration on the server. It is necessary that all unknown server routes are redirected to the main page of the application. Then, after the initial page load from the server, client routing will be able to work.


AJAX requests


This is a task that does not depend much on the chosen JS framework. For Vue and Angular there are specially designed libraries, but their use is optional. There are a lot of AJAX libraries, here are some nice options.


If the project is still using jQuery for something, then you can use it for AJAX queries. In Contoso, jQuery is wrapped with promises and used through the httpHelper module.


Another good option is axios . This library has a convenient API, supports promises, and what is very important for full-stack development, works the same way on the server as well as on the client.


Using XMLHttpRequest directly from JS is difficult, so the Fetch native method is suggested to replace it, it is not supported in all major browsers, but as always in such cases, there is a library with the fetch polyfill polyfill that works with the same API.


There are several actions that can be performed with each AJAX request.


You can block the UI so that the user cannot perform any other actions until the AJAX request is completed and the state of the system is not updated.


If an error occurs during the request, by default you can display a general message (for example, "Server Error") for any request.


Optionally, you can add local logging of all AJAX requests to the browser console.


Validation


Validation on the client is different from validation on the server. On the server you need to validate all incoming parameters. You cannot trust that the client has validated the data, or that the call comes from your client code, and not by the request of the malicious user.


On the client, the situation is different, it is necessary to validate only those places where the user can make a mistake. But, for example, if a third-party component is used to enter the date and there you simply cannot enter an incorrect or empty date, then it is not necessary to validate. At the same time, you need to think more about what error to show and how.


Client validation is usually closely related to the client framework used, because tied to the verification of data that are in the model and errors should dynamically depend on the state of the data model.


In Contoso , in React, auxiliary libraries are not used for validation; for Vue, the "vue-validator" package is used.


Configuration


Typically, the client does not have a large number of configuration settings, but nevertheless they are needed. For example, the settings for formatting (date, full name, currency) data on the client, a flag for optional logging of all AJAX requests to the console, etc. can be used.


For convenience, you can read client configuration values ​​from the server configuration, and on the client, use an auxiliary module that subtracts the values ​​from the server through a separate AJAX request.


In Contoso, this is implemented exactly this way, see the file "helpers / clientConfig".


Error processing


The main source of errors on the client is AJAX requests. If you are developing both client and server parts, it is easier to immediately send the error text that can be displayed on the client. If the API is developed separately, then the error is handled by the HTTP code or the custom line code, it is better to do it right away in the service method that makes the AJAX request.


The remaining errors are often not processed at all, it is assumed that they should not be, and if they did happen, the user will guess to reload the page.


However, in production you can log errors from the client, there are several services for this, for example logentries .


Packaging


When writing a large client application, you have to break it into many small modules, while the browser does not work well with a large number of files (HTTP2 will fix this). Therefore, there is a practice of client builds, when several files, with code or styles, are combined into one or several bundles. To do this, use different tools.


Task managers (task runners) are designed for a wide range of tasks, such as combining and compressing JS files, compiling SASS / LESS, copying, renaming files, and more. The necessary work is divided into tasks that can be performed separately through the CLI (console). To perform various tasks, plugins for a specific manager are used. The most popular task managers are Gulp and Grunt . Recently, there is a tendency to use the npm tools to run scripts and write the scripts themselves to Node without using the task manager and its plugins.


Module bundlers in addition to the common tasks of the client assembly, analyze dependencies in JavaSrcript files and merge the original assembly, respectively. For example, if you have module1.js which imports module2.js, which in turn imports module3.js and lodash. Then the modules in the initial assembly will be in the correct sequence (lodash, 3, 2, 1). Module builders by default expect to see external modules as npm packages in the 'node_modules' folder.


The most popular at the moment is WebPack . The first tool of this type was Browserify , it is simpler than WebPack, but requires more configuration. Rollup is gaining popularity - it differs in that when using the ES6 syntax for import, you can determine which parts of the external libraries are used and include only them, which allows you to reduce the size of the client assembly.


In Contoso , WebPack is used for client builds, and npm or the console itself is used to run tasks. WebPack does the following: combining modules, transcribing TypeScript into ES5, converting styles from LESS to CSS and combining them into one file, minifying JS and CSS for production build.


For development, you need to run WebPack in monitoring mode, with any changes in client files, the assembly will be rebuilt and you need to reload the page in the browser.


 webpack --watch //-w shorter 

WebPack allows for some JS frameworks to support HotReload mode - this is when JS and CSS are updated without full page overload. It is supported in React and Vue, but difficult to configure and sometimes does not work correctly. Not used in Contoso .


I would be happy to comment comments.


Stay tuned!


')

Source: https://habr.com/ru/post/310788/


All Articles