Use of vulcanization for polymer modules

  • Tutorial
polymerjs vulcanize

The project I'm working on now has a widget-like client architecture. Moreover, system widgets can use any library for their implementation, for example, ReactJS, PolymerJS, VueJS, d3JS and others. Several system widgets are implemented just like Web components based on PolymerJS .

Therefore, I bring to your attention one of the approaches for optimizing polymer widgets.



Content:


1. Description of the problem
2. What difficulties arise?
3. How can they be solved?
4. The vulcanize-polymer-module
4.1 library . Structure
4.2. Description of bower.json
4.3. Description of package.json
4.3.1. Installing utilities
4.3.2. Configuring RollupJS
4.4. vulcanize-utils.js
5. Conclusions

1. Description of the problem


One of the main problems of polymer applications is the multiple loading of used components and all dependent components, which, in turn, can consist of auxiliary styles, behavior , loaded in the same way. As a result, the console in the network section will be "bombarded" with these files. In view of all this, the first download of such a widget can be quite long, depending on the number of composite web components used.

For these purposes, polymer applications use vulcanization. It is understood that this application has an entry point in the form, for example, index.html , in which the main container component is expanded, for example. In this file, the polymer core itself and the container component file are connectedand then all used components are hierarchically connected, which themselves are separate html-files. The vulcanization process itself consists in “gluing” all used components and the polymer core into one file, which will ultimately be the entry point for index.html .

2. What difficulties arise?


  1. The first difficulty is that I do not have a polymer application, but several composite components (let's call them smart components - CC) that are wrapped in a system widget, that is, there is no single entry point.
  2. The second difficulty is that during the work with the application the page with these widgets may not be called at all, and accordingly, none of the polymer components will simply be needed in the current session, not to mention the polymer core itself.
  3. Thirdly , one CC uses one set of atomic ( paper- , iron- and other) components (let's call them stupid components - GK), and the other - another set. And may be the intersection, there are two different Criminal Code use the same GC .

3. How can they be solved?


If we consider the first complexity, I could vulcanize each UK separately , but then, if we take the third problem, duplication of the same HA is possible, and there will definitely be a duplication of the polymer core, if we consider the situation in which at least two UK are used in one session . Therefore, a different solution is needed.

If we consider the second difficulty, it is necessary to do so, that would be the core polymer and GKy loaded only once, at the first call to one of the Criminal Code , and at the time of treatment to the second, there is no need to re-download everything, but only load the dynamic itself of the Criminal Code .
If we consider the third complexity, then we need to make a list of all the used stupid components in smart ones, which we will eventually vulcanize together with the polymer itself.

4. vulcanize-polymer-module library


I designed all the above theses in the form of a vulcanize-polymer-module library.
I want to tell you more about it.

4.1. Structure

vulcanize-polymer-module/
├── imports.html
├── vulcanize-utils.js
├── rollup.config.js
├── bower.json
└── package.json


4.2. Description of bower.json

In it, we describe all the GCs that we need as dependencies, including the polymer core itself.

For example, the dependencies section might look like this:

dependencies
"dependencies": {
    "polymer": "Polymer/polymer#^2.0.0",
    "polymer-redux": "^1.0.0",
    "iron-flex-layout": "PolymerElements/iron-flex-layout#^2.0.0",
    "paper-button": "PolymerElements/paper-button#^2.0.0",
    "paper-badge": "PolymerElements/paper-badge#^2.0.0",
    "paper-icon-button": "PolymerElements/paper-icon-button#^2.0.0",
    "paper-input": "PolymerElements/paper-input#^2.0.0",
    "paper-item": "PolymerElements/paper-item#^2.0.0",
    "paper-checkbox": "PolymerElements/paper-checkbox#^2.0.0",
    "paper-tabs": "PolymerElements/paper-tabs#^2.0.0",
    "paper-listbox": "PolymerElements/paper-listbox#^2.0.0",
    "iron-a11y-keys": "PolymerElements/iron-a11y-keys#^2.0.0",
    "iron-list": "PolymerElements/iron-list#^2.0.0",
    "iron-icons": "PolymerElements/iron-icons#^2.0.0",
    "paper-progress": "PolymerElements/paper-progress#^2.0.0",
    "vaadin-split-layout": "vaadin/vaadin-split-layout#^2.0.0",
    "vaadin-grid": "^3.0.0",
    "iron-pages": "PolymerElements/iron-pages#^2.0.0",
    "iron-collapse": "PolymerElements/iron-collapse#^2.0.0",
    "iron-overlay-behavior": "PolymerElements/iron-overlay-behavior#^2.0.0",
    "vaadin-context-menu": "^3.0.0"
  }




Since I use redux with polymer, I have included the polymer-redux library .

4.3. Package.json description

It contains the dependencies that we need to build, in particular RollupJS , which is used for intermediate cleaning of the output file code. The commands used for vulcanization are also described, let's take a closer look at them.

scripts
"scripts": {
    "build": "rollup -c",
    "vulcanize": "vulcanize imports.html  --inline-scripts --inline-css --strip-comments",
    "run-vulcanize": "npm run vulcanize > imports.vulcanize.html",
    "vulcanized": "vulcanize imports.html  --inline-scripts --inline-css --strip-comments | crisper  --html imports.vulcanized.html --js imports.vulcanized.js > imports.vulcanized.html",
    "html-minifier": "html-minifier imports.vulcanized.html --remove-optional-tags --collapse-whitespace --preserve-line-breaks -o imports.vulcanized.min.html",
    "build-all": "npm run vulcanized && npm run build && npm run html-minifier"
  }


Teams, in order and priority of their use:
  • build-all is the main team that launches the entire vulcanization process.
  • vulcanized - performs vulcanization itself, that is, combining all components and the kernel into one file, then splits the entire assembly separately into .js and .html files. (The vulcanize and crisper utility are used )
  • build - cleaning js-file code from comments. (using RollupJS )
  • html-minifier - minification of the html file. (using html-minifier )

4.3.1. Install Utilities

As you can see, many additional utilities are used, which we need to install in the system first.

Install Utilities
npm install -g vulcanize
npm install -g crisper
npm install -g html-minifier


4.3.2. Configure RollupJS

Since rollup is only used to clean js code, I use only one plugin for it, rollup-plugin-cleanup . The rollup-plugin-progress plugin is used to visualize the build process.

rollup.config.js
import progress from 'rollup-plugin-progress';
import cleanup from 'rollup-plugin-cleanup';
export default {
	entry: 'imports.vulcanized.js',
	dest: 'imports.vulcanized.js',
	plugins: [
		cleanup(),
		progress({
		}),
	]
};


4.4. vulcanize-utils.js

To solve the second requirement, the utilitarian method loadVulcanized was written , which loads the UK , but before that it loads the vulcanized file, and does it once, and in cases of repeated calls, it loads only the UK itself .
Let's consider its parameters in more detail.

loadVulcanized = function (url, urlVulcanized, controller, html, store)
  • url is the path to the smart component. It is a must.
  • urlVulcanized is the path to the vulcanized assembly. By default, the path to this assembly is ../vulcanize-polymer-module/imports.vulcanized.min.html
  • controller - in my case, this is the controller of the system widget. Optionally.
  • html - html object of a smart component. It makes sense if a controller is specified.
  • store - redux store. Optionally.


5. Conclusions


Of course, you can use polymer-cli with the build parameter , but when assembling with it, it is understood that the polymer project is being built, and since we use components in more than one container, then each UK will have to be assembled separately and the assembly files will have duplication of the polymer core and composite HA . Therefore, the approach described in the article has sufficient efficiency in systems using several UI libraries together, due to a single entry point for all polymer-based MCs.

One of the possible disadvantages can be considered as the redundancy of the HA in the vulcanized file, since it contains all the GAs of all the ACs used in the system, but not all ACs can be used during the work session, which is why not all ACs will be used in uploaded vulcanized file.

Also, as a slight inconvenience, you can consider the fact that after adding a new component, you need to start the assembly again, and then do the repository update (push), and other users should update this library through bower update.

Despite all this, this library solves its problem in this project, which means it can be useful to someone else.

So fork , welcome.

Also popular now: