Every time you start writing a React application, you somehow choose some option:
Each method has its strengths and weaknesses, both in the long and in the short distance.
Some solutions hide complexity at the beginning, allowing you to make a quick start. This is something like a turnkey solution, but as a result such solutions may not be flexible enough and difficult to adjust. On the other hand, in the beginning everything may seem slightly monstrous and slow, and in order to start you need to tinker a bit, but then the advantages will become obvious. There is always the opportunity to do everything from scratch, exactly the way you want, but in this case you will be responsible for countless aspects and you will need very deep knowledge in all the technologies involved.
Obviously, having a standard inside the company is extremely useful when it comes to developing several projects, so any team can be switched to any project. Or in the case of a design studio that constantly creates new and new projects. In this case, the creation of the base should take as little time as possible. A common standard approach allows teams and developers to share knowledge, you can maintain a certain base of standard solutions, best practices, etc.
Market analysis shows that there are several fairly stable projects that provide some kind of infrastructure for creating websites on React. I chose several of them, trying to ensure that all candidates, for clarity, had as different a nature as possible.
If you collect the entire application into one giant JS file, it will be loaded forever, while users will watch the download animation. Studies show that users prefer to leave sites that do not have time to load in 3 seconds.
import()
now supported by Webpack 2 . For those who still sit on the Webpack 1.x, too, there is a solution . Electrode has a special archetype as a solution.On the one hand, the application should deliver as much as possible at once, so as not to go over the network once more for resources (pictures, styles, scripts), for example, so-called. vendor-chunk with all libraries, important CSS scripts. But at the same time, we want to deliver as little as possible, only what is necessary on this page.
The application can download all the necessary data and generate ready-made HTML, which together with the data will be given to the client, thus virtually eliminating the delay between the initial download and the moment when at least something appears on the site, at least for viewing. We don’t say about the possibility of using all this, this is a separate topic.
Google ranks sites using response time as well. Despite the fact that search engines are able to render AJAX sites, this is bad for the position, so the site must provide a version that search engines can digest. There is a problem with this, if we want to load all the data, and not just the main content area, how to let the server render know that all the downloads are finished? There is no established approach for this yet. In the custom version, we can parse the component tree and pull out, for example, the static getInitialProps
method (by analogy with Next.js), and when all these methods return their values, then it can be rendered.
In order for the components themselves to say what they need from the data, Relay + GraphQL was invented, but the disadvantages outweigh its advantages. It needs a separate server. He is wildly verbally (the scheme itself + mutations are monstrously cumbersome). The complexity of the code you need to write for the simplest actions almost kills all bonuses. Explaining it to someone from the team from scratch is also problematic. In addition, a special Babel transform is required, as well as a utility for downloading and compiling the schema. As a result, you still get something incompatible with SEO. We have to admit that if you only consume the existing GraphQL API, then the situation is a little better. This is a rather promising technology, I want to believe that the guys will manage to make it more friendly. It is also worth noting such a thing as the Apollo Framework.
During the study, I created a couple of libraries that can help with Server Side Rendering:
At some point, server performance will cease to be enough for rendering components. In this case, some components can begin to cache.
Many people use LESS / SASS / Stylus / PostCSS in order to use variables and mix-ins in their styles, so the code is cleaner and more concise.
In any of the candidates, you can always create a separate build process / watch'a for SASS / LESS styles, such as in the Create React App, but you need to somehow connect the resulting CSS to the application (you can import it directly into the Create React App). In this case, Critical CSS and Hot Module Reloading, as well as Server-Side Rendering styles become your concern, which negates the advantages of non-custom solutions.
Obviously, using the best libraries for interfaces, we improve the look of the product, speed up its creation, especially if we are talking about things like Twitter Bootstrap or Material Design. These libraries usually come bundled with CSS that needs to be included in the application in some way.
_document.js
(the main template), but then the style file should be in the static
directory; if you use preprocessors, then it is better to include CSS from under your other files with styles (well, connect them via custom _document
and a collector or a custom Webpack config)Roughly speaking, certain styles can be loaded along with HTML, so users will never see the so-called. flash non-stylized content (FOUC). It is useful, but not critical at all. modern networks are quite productive and the style table weighing up to 100KB is nothing at all.
This is a rare case that is far from necessary for everyone, but many applications support different skins for different brands or just for the convenience of users (well, for example, a dark or light color scheme).
Living inside an ecosystem, well-designed and documented, is always more pleasant than sorting out a bunch of small libraries: less trouble with dependencies, the ability to follow the direction given by the authors, lots of examples. I remember the phrase that if you do not use the framework, then in the end you will write it yourself.
I think no one will argue that in the modern world there are nowhere without tests.
Since we plan to do many projects based on one standard, we want to have as little hassle as possible with the initial setup and launch of our solutions. For this, it is desirable that initialization fetches as few files and configs as possible.
Suppose you work with an application as part of a team, in which case you will have to train your colleagues in some way. Documentation and fixed patterns are a good basis for easy sharing of knowledge within and between teams.
The ability to customize anything should also be present, because we live in real life and anything in it can change at any time, but the requirements are not eternal. And I really would not want to rest against some kind of rigid limitation of the framework.
For convenience, lines with localization should be in a standard format, with substitutions and declensions. It is desirable in one that can be easily perceived by translation companies, because it is they who will be the most busy with them.
None of the frameworks provided provide any means for translation. However, they are easy to add. After searching, I found out that the centralized asynchronous loader works best, in which case each language becomes a separate chunk. This can be achieved by creating a function that takes a language as a parameter and returns asynchronously loaded strings for the language. Something like const loadStrings(lang) => import('./strings/'+lang)
(this construction is unlikely to work right away, but the essence should be clear, you can create Webpack Context'ov before it to guarantee a bunch of 1 language = 1 chunk.
Libraries: FormatJS and Format Message (and that and that works with the so-called ICU Format ).
It is best to organize strings by tokens, i.e. {TOKEN: {en: 'English', fr: 'French'}}
, this is easier for developers and translators. The reverse approach, where the "as if token" is the English string, which did not justify itself.
Discipline \ Name | React App | Electrode | Next.js | Custom |
---|---|---|---|---|
Dynamic routes | Yes | Yes | DIY | Yes |
Server rendering | not | Yes | Yes | DIY |
SSR optimization | no ssr | Yes | not | DIY |
CSS | Yes | Yes | nightmare | DIY easy |
Preprocessors | nightmare | nightmare | nightmare | DIY easy |
Critical CSS | DIY | plugin | not | DIY |
Community | great | there is | there is | you're on your own |
Tests | jest | phantom | DIY | DIY |
Base code | zero | lot | zero | lots of |
Configuration | zero | lot | zero | lots of |
Documentation | the good | so-so | in stock | scattered |
Simple training | sat down and went | acceptable | easy | nightmare |
Further training | easier to die | heavy | heavy | nightmare |
Server engine | nginx | node | node | node |
Customization | eject and death | acceptable | nightmare | anything |
Initial installation | easy | verbally | easy | nightmare |
Predictability | the good | so-so | bad | nightmare |
Upgrades | chic | not bad | so-so | nightmare |
If you are not going to engage in server rendering (you do not sell anything, the application is not indexed by Google, and generally private), then you can safely look in the direction of the Create React App , it is the most popular and simple. It can even customize a little. Only do not eject, it is not worth it.
If server rendering is needed, and you are ready to put up with some restrictions, then choose Electrode (as a condition, you also should not be intimidated by a large number of files, verbose and configurations). This is also a good choice if you are worried about performance.
If you are ready to put up with even greater restrictions and love minimalism, then look at Next.js.
And finally, there is always a custom . Fortunately, libraries like Webpack Blocks , Create React Server , React Router , Redux, and others make life much easier. The only problem is the exchange of knowledge and the development of processes for the rapid creation of applications without repeating the same code every time.
Source: https://habr.com/ru/post/323458/