Frontend for backend developer

Just want to make a reservation that this article is not intended for those who have the development of the frontend main activity. This post is intended for backend developers who urgently need to fasten the web UI or those who are simply interested in new areas, as well as fullstack developers.

So, we go to the problem. The article is remembered , and also, in the open spaces of Habr there were some more similar. They are all presented as jokes, but as they say, “there is some truth in every joke,” and here it’s not even a fraction ... But the question is, how useful are all these frameworks, are they necessary?

A question that I would like to raise, mainly about the assembly. It is at this stage that the js community offers an incredible number of tools, the need for which is not at all obvious. For example, the community offers various options for working with modules, which made sense at one time, but at the moment the import / export specification is supported by all modern browsers, and even under the edge browser. Since we have previously mentioned that we have no reason to work with old libraries, consider the import / export specification. What we really need is some kind of work with dependencies.

I will make a small digression to explain the choice of technologies that will be used in the example for the frontend itself. In order not to delve into the countless variety of frameworks, let's go on a remarkable standard . So, everything becomes simple enough, there is no virtual DOM, there are web components. This could be finished, but still js. If we decide to get rid of pure js, then we will have to somehow solve infrastructure problems, get rid of the boiler codelet, etc. In other words - to fence your bike ... To not do this, I would like to take something where everything has already been done and is of sufficient quality. Accordingly, my choice fell on Polymer - a framework from Google, which pushed through web components to the standard.

We return to the assembly. Many of you (Java developers anyway) got used to such a tool as maven and gradle, and you probably found out that they do an excellent job with resource manipulations (for maven, this is a little worse, of course, but for gradle, there are no problems at all anything). The frontend community offers us to take npm, for which nodeJs is needed, but this is not enough, the webpack is also on top. And they still have to understand and put each developer. Um ... I would like to just dump the repository, do the gradlew build and start working, so let's stop at the usual gradle.

Of course, we won't be able to do without npm, at least, we need a repository from which to get the js library and npm it provides, but the utility is not required. You can find some good solutions like this , but they always download nodeJs, and run npm tasks. Option, but I would like to minimize communication with npm before interacting with the repository and only. How the solution was to write your own plugin for gradle. Although it is quite simple to write plugins for gradle, due to the wide variety of options for specifying versions for the npm repository, the task is somewhat more complicated. The benefit of this is clear documentation .

So, let's write a gradle script to load dependencies. Kotlin dsl is used for the reason that rewriting to groovy dsl is rather trivial, but on the contrary, you would have to spend time if there was no previous experience.

repositories {
    mavenLocal()
    jcenter()
}
dependencies {
    classpath("com.github.artfable.gradle:gradle-npm-repository-plugin:0.0.3")
}
apply(plugin = "artfable.npm")
configure<GradleNpmRepositoryExtension> {
    output = "$projectDir/src/libs/"
    dependencies = mapOf(
            Pair("@polymer/polymer", "3.0.5"),
            Pair("@polymer/app-layout", "3.0.1"),
            Pair("@polymer/paper-toolbar", "3.0.1"),
            Pair("@polymer/paper-icon-button", "3.0.1"),
            Pair("@polymer/iron-icons", "3.0.1"),
            Pair("@webcomponents/webcomponentsjs", "2.1.3")
    )
}

This plugin will add us npmLoad . To allow the IDE to group nicely, we define it into a group

tasks["npmLoad"].group = "frontend"

Great, you can try writing code for our frontend. The built-in Intellij server by default will tell you that Method Not Allowed to attempt to connect scripts via import. To avoid this, check the allow using requests checkbox . (in recent versions it works without it).

Settings (pic. 1)

Let's try to start now, and ... Anyway, nothing worked. Fell dependencies inside the polymer components. The fact is that many js libraries push imports with the expectation of some kind of transpiler like babel. Such an import looks like this:

import '@polymer/polymer/polymer-legacy.js';

Such syntax import is not correct, since for the browser the path must begin only with '/', './' or '../'. In addition, in this form, it cannot be taken either as a relative or as an absolute, since here it is calculated at the beginning from the root of the library directory. Consequently, such ways need to be corrected, well, in order not to do it ourselves - you can take the prepared plug-in .

Depending

classpath("com.github.artfable.gradle:gradle-js-import-fix-plugin:0.0.1")

apply(plugin = "artfable.js.import.fix")
configure<GradleJsImportFixExtension> {
    directory = "$projectDir/src/libs"
}

Task jsImportFix will be added which will put all the imports in order.

So simple, and without the need to deal with the mountain of new tools, you can assemble the front. But let's look at the issue with styles. Frankly, web components allow you to get rid of the boilerplate, and the variables in css, which are already in the standard, open up many possibilities, so there is no longer any need for such things as sass. But suddenly, for example, you really liked bootstrap and wanted to make a design based on it.

Finding any plugin for building on this is not a problem, basically, they all take libsass as the basis and there is a java wrapper on jsass . The only problem is for everyone (at least at the moment when I looked at them) in duplicating dependent files.

Example:

File a:

@import “b”;
@import “c”;

Files _b and _c:

@import “d”;

As a result, in the main file we get 2 identical blocks from the _c file. You can easily fix it, if you add the importer to jsass, api allows. Actually, that's why I am again with my decision here (if there are no such requirements, then it is better to use another solution).

Add to the list of npm dependencies

Pair("bootstrap", "4.1.3")

Plugin dependency

classpath("com.github.artfable.gradle:gradle-sass-plugin:0.0.1")

apply(plugin = "artfable.sass")
configure<GradleLibsassPluginExtension> {
    group(delegateClosureOf<GradleLibsassPluginGroup> {
        sourceDir = "src/sass"
        outputDir = "src/css"
    } as Closure<Any>)
}
tasks.create("processResources")

Fake task processResources will have to be created if the java-plugin is not connected (and we don’t need it here). This is of course a flaw, then I will definitely fix it.

Please note that the received css file should not be connected to the head , since then it will not be visible inside the component, but directly into the template of the component itself.

The last step is to slightly modify the script to get the usual build directory , with a ready project that can be deployed to the prod.

The full code is laid out on github (you will probably have to migrate to gitlab later ...).

I hope the basic idea is clear, and then you can add quite simply absolutely anything. Thanks for reading.

Also popular now: