Small Web page project packaging optimization solution, web project packaging Solution
Background
Zookeeper currently uses Vue or React for all new Web projects in the team, and RN is a heavyweight framework. However, small Web pages are too large. Some early projects used the original HTML page construction technology, but the business logic was basically not reusable.
Zookeeper has worked on several small Web pages in the last six months. While Continuously learning the front-end knowledge, he is also restructuring and exploring possible better solutions for small Web projects. This article gives an overall description of the previous work.
Objectives and positioning
Compared with Vue/React and other projects, a small Web page does not need to support SPA, which is based on the principle of MVP (Minimum Viable Product, as long as small pages meet requirementsSufficientYou can. Therefore, when restructuring the existing original Web page, the following two aspects will be taken as the highest priority:
Continuously improve the reusability and maintainability of projects;
Constantly Improve the front-end performance, mainly including the loading performance;
For zookeeper, The componentized code structure is the most feasible method at present. For the second point, there are very few third-party dependencies and a good packaging method, is required.
Project Structure Evolution
Zookeeper the project structure and packaging methods of small Web pages described in this article are achieved after several project reconstruction.
First version
The first version of zookeeper is based on the most primitive HTML + JS + CSS. In order to make the project code better maintained, the first consideration is that there are two points that need to be done:
To make the page content maintainability, you need to use a JS template;
The data access layer is required because the business is complex, the division of labor is fine, and there are many interfaces.DAL
(Data Access Layer) separated separately;
Finally, selectMustache
Library. The reason is that its syntax is simple and easy to learn. At the same time, this type of syntax has a large number of users, and of course it is also popular.underscore
/ejs
Type template syntax. To ensure that the content page is non-logical and simpleMustache
Advanced EditionHandlebars
Not used.
Zookeeper's second problem is the conclusion after understanding the company's business and project code. Equivalent to refactoring existing code, the main purpose is to separate duties, isolate complex and variable interfaces, and let the remaining Code focus on solving business problems.
Another serious problem was discovered only after zookeeper began coding: I needed to separate the code of the management content template so that it would not affect the main business logic, so I thought of the Model View Presenter mode. Simply put, this is a weakened version after the MVVM mode removes the View-ViewModel bidirectional data binding. As shown in:
In small Web pages, there is generally no Model layer. The Presenter part of the page is only responsible for controlling the rendering of the interface through parameters, and exposing View layer events as components. According to this idea, the structure of the first version of the project has basically come out. See:
Introduce Webpack 2 +
The project structure of the first version of idea is enough to meet the needs of small Web pages, and it will not bring much complexity. However, the original Web page is inherently not conducive to modular development, and there is also a fundamental problem:
Code decoupling will clear the project file structure and separate duties, facilitating maintenance;
The packaging results need to compress the relevant code into a single file to improve the loading performance;
In Web page development, Zookeeper forms a paradox. Therefore, we need to introduce a packaging mechanism to decouple the project code from the package file. The old Gulp and Grunt will not be viewed. The existing projects mainly use FIS3 and Webpack 1.x. The former is made in China and easy to use. The latter is more difficult, but like other open-source projects outside China, they can always make a 50%-document of a software well. (In fact, there are still a lot of things to talk about, but after reading it, I feel more practical)
After reading the documentation of Webpack 2.x, Zookeeper basically decided to use the packaging machine. It has the following advantages that can't be stopped:
Native supportimport
Syntax. In this way, we can completely get rid of the problem of poor management of the file structure. All the object-oriented and modular aspects can be introduced, and finally we can write code comfortably;
Tree Shaking is supported. Originally, this is a unique feature of rollup packaging machine, and now Webpack is available;
Although the Webpack configuration file is complex, it can be found that it has great potential and is quite flexible to use with the plug-in mechanism;
When Webpack 2.x is introduced to zookeeper, different functions are separated in the form of a single file, and the interfaces between modules become very clear, but they still need to be improved.
Refer to Vue project structure
After zookeeper is added to the balancer, the JavaScript file has been well decoupled, but the templates are also placed on the homepage, and the styles are also placed in a file. The dependency is messy and cannot be managed. A good way to improve it is to refer to other excellent projects. For example, Vue has a set of good project organization structures and can be used for reference directly. Major changes to the new project are as follows:
Truly separate components. Component ContentMustache
Template, style usedLess
The syntax and JS part control the rendering logic of the component and do not associate the service logic as much as possible. The combination of the three is equivalent to a. vue file. By modifying Webpack configurations or using appropriate plug-ins, This method also supports other templates and CSS syntax, suchejs
OrSCSS
;
Select to support multi-page portals without using the routing function. This simplifies the complex URL structure in the SPA and removes the need to attach routing logic to the packaging results. Another advantage is that the introduction of simple version of SSR will be very convenient in the future, and the routing is nginx;
The detailed description of the project structure of zookeeper is described below. The structure is as follows:
It must be noted thatState Store
In fact, it is not available at present. It is mainly used here for good looking :). If vuex, MobX, and Redux are added in the later stage, it will be complete. At present, because of the simple business logic, it is enough to solve the status or other brute force problems. App. js processes public business logic in the project, freeing the page entry from focusing on content.
Project Structure Description
Directory structure
The project directory structure is as follows:
---- Build # Webpack configuration file... ---- src -------- assets # resource file
-------- Components ------------ GoodsInfo # GoodsInfo. mst # component template, using the Mustache syntax GoodsInfo. js # component rendering and operation logic. General Business-independent GoodsInfo. less # component style
------------ RiskPromt... ------------ expose header... -------------- SharePanel... utils. js # A set of auxiliary methods related to the view layer
-------- Dal # data access layer index. js # entry file. Centralized management of the Request interface and pseudo data getInfoById. js # Interface request implementation getInfoById. json # interface returns pseudo data, the mock method can be generated in index. js
-------- Main # default page entry Main.html # Page Template Main. js # page business logic Main. less # Page Style
-------- MainBanner # page entry with the bottom Banner... app. js # extract the common business logic of multiple pages, for example, the specific implementation of the sharing Function common. js # application-level auxiliary method set common. less package. json README. md
Third-party dependency
With the help of Webpack 2 +, the project selects the following open source third-party libraries as the basic dependency:
es6-promise
: Using Promise can make the code clearer and better maintained;
axios
: Vue-resource alternatives officially recommended by vue;
mustache
: Template library used by the Project
In addition, the SDK maintained by the team is used:
@zz/zz-jssdk
: Provides interactive interfaces between Web pages and the App client.
@zz/perf
: Performance statistics Tool
Zookeeperaxios
Non-standardjsonp
Request, only supported for the existing partjsonp
The requested interface also needs to be introducedjsonp
Third-party open source library.
Zookeeper and above are project file dependencies. In the Development dependency, the third-party libraries used are basically related to Webpack, includingLess
File Parsing module. Project not introducedbabel-polyfill
ES6 Syntax Development, because it is easy to generate unnecessary additional packaging code.
File loading Rule Configuration
In the Webpack syntax, all project files are resources for JavaScript. Therefore, you only need to configure the appropriate loader when processing any resources. This section briefly describes the configuration of loading and parsing rules for different types of files in the project. The Webpack configuration details are not described here. For more information, see the official documentation.
Zookeeper is used to load general resource filesfile-loader
You can. Recommended image filesurl-loader
. This loader has an option: if the image is smaller than the specified value, it will be convertedDataUri
Embedded in the package file to reduce additional HTTP requests. The project setting value is 10 KB. The rules are as follows:
Style files in the project are used by default.Less
, Mainly uses the two features of this database:
CSS variables can be easily used, for example, defining the general pixel size;
Hierarchical style description;
The Webpack configuration retains the loading capability of css files and can be added later.SCSS
File support. The rules are as follows:
In the same projectCSS
/LESS
/SCSS
Files are dependent on each other, so we strongly recommend using the same technology. For a single component, it is unlikely to write a Webpack Loader that supports the. Vue type component format like vue. To load style files, you must explicitly introduce the. less file in the corresponding. js file, for example:
The Zookeeper Project template is used by default.Mustache
With the support of Webpack, the template content is placed in a separate file and.mst
As a custom suffix, the file content is still in HTML format, but the root tag is<template>
. Webpack selectedhtml-loader
The rule is as follows:
ZookeeperMustache
Automatic parsing and loading of templates, open-source on the Internetmustache-loader
Implementation, but its attention is too low, andhtml-loader
Sufficient to achieve the required functions:
Load the. mst file and compress the content;
In the fileimg:src
And other relative path attributes are automatically replaced with the absolute target address;
Zookeeper can also use this method for other template languages to flexibly use different template libraries in projects. However, it should be noted that it is best to use only one template language in the same project to facilitate management without increasing the size of the package file.
Zookeeper loads the. mst template to the page and the. less method is similar. Explicitly introduce in the corresponding. js file, and then useextractTemplate
Method to extract the template content:
One advantage of the explicit introduction of idea is that you can manually control different templates and styles. In actual product requirements, content and style changes are frequent, while functional logic changes are relatively slow. In this way, using js to reference templates and styles of different versions is more flexible. It would be nice to abstract the management mechanism and configure it separately.
The Zookeeper page file also exists as a template role in Webpack. The parsing method is the same as that of the template. For the rules, see the preceding section. Because it is a page entry file, you also need to use it in Webpack.HtmlWebpackPlugin
Plug-in for configuration. In the following configuration, the project has two different page entries, so twoHtmlWebpackPlugin
Instance:
Each time a user enters a Web page, the homepage is loaded, which reduces traffic. Refer to the Vue project'sindex.html
You will find that there is basically only one skeleton, and the specific content is in the component. However, the project configuration itself does not assume this, so it is feasible to write all the content on the home page.
Package
The main packaging configuration of the zookeeper project has been described earlier. For more information, see the official documentation. The final packaging result using the project structure. All deployment files, including images, cannot exceed 130 KB. In the browser, due to gzip, the network traffic for full page loading is less than 70 KB.
Data access layer
Zookeeper has previously mentioned that data requests are used as a separate layer to separate complex and variable data request interfaces. Another advantage is that the mock data interface can also be processed in a unified manner.
Interface Encapsulation
Zookeeper a project may request the same interface in many places. For a single interface request, there may be different methods, such as using ajax, fetch, jsonp, axios, and even jQuery libraries; some GET, some POST; some require cookie, while others do not; the format of the returned data may not be uniform. The JavaScript logic only cares about input and output. The request details are maintained separately in another place, which makes the main business logic more concise. For use in a project, you only needPromise
To call the method. The sample code for interface encapsulation is as follows:
Encapsulate mock data
When developing a consumer notebook on the frontend and backend, you must first define the interface and provide a mock data example. ThereforeDAL
The layer encapsulates mock data, which saves a lot of work. In the project, mock data is saved as a. json file, andimport
Import, and then use a factory method to provide external servicesmock
You can use mock data. The following is the code in the entry file:
Use the DAL Interface
Zookeeper hasDAL
The aggregation of each request interface at the layer is easy to use in other places, and the code is directly:
Componentized Development
Components and.vue
The file structure is similar, but it is divided into three files:
Style. The content and usage are basically the same;
Template. The latterVue
Has its own template syntax, and the former usesMustache
Other templates are also supported. IfVue
The template loaders are separated separately, which can be used theoretically;
Control logic. The JS logic is somewhat different,Vue
The Framework has its own unique and perfect two-way binding mechanism, and its interfaces and lifecycle are also designed around it (here only.vue
File for discussion, ClassReact
The usage is largely set to facilitate user pulling ). Because small Web pages are simple, the focus is on Component initialization and rendering;
The widget is clearly positioned on a small Web page, that is, onlyPage rendering and InteractionTherefore, the design of external interfaces is not complex. If the components adopt the MVC mode, it is difficult to discuss, because the Controller itself is the "boss" and there may be many actions. Presenter and ViewModel are relatively simple. The difference between them is that the internal mechanism is different, and the external behavior is similar. Large Web pages are not considered here. the interfaces of Components in small Web pages are two by default: accept pure data parameters (props
. Compared with a more advanced VueSlot
Slot function.
Use Components
Zookeeper uses components directly. Check the Code:
Componentinit
The method cannot meet all requirements, because the projectinit
The method not only contains the component rendering logic, but also the event binding logic. When the component data content is updated, you also need to extractrender
Orupdate
Method to update the interface. This is not like Vue's built-in bi- al data binding artifact, so it is troublesome.
Zookeeper uses the event provided by the component, and the code is as follows:
Here, the event handle parameter uses(Object data, Event e)
. Wheredata
Indicates the event source, which can be the clicked objectViewModel
Or simply, it is directly the raw data represented by the clicked object;e
It is the HTML event parameter.
Component parameter processing and rendering
The Zookeeper component is bound to a specific template as described in the previous example. When rendering the component content, you also need to process the parameter content and render it to the specified place on the page. The code is directly listed here:
In the constructor, first defineprops
Parameter format, and the default value is given. Ininit
Method, the parameters in data are assignedprops
The data conversion processing logic is generally used here.
Finally, render component rendering is performed directly. It can be found that it is easy to replace other template engines. If the SSR server Rendering component is used, all the template libraries can be put in, and a factory method can be used for automatic processing.
The parameter of the zookeeper component is namedprops
, Completely counterfeitedVue
/React
. Because their functions and positioning are basically the same, and the best practices officially recommended are also basically recommended here. The specific ideas for doing so are as follows:
Small projects cannot doVue
/React
Parameter verification function, but explicitlyprops
Parameters can be described in a self-describing document. What parameters and their types are required;
The constructor also providesprops
Default value. If no parameter exists, the component is displayed by default;
There is only one parameterdata
Object.Vue
Recommendation parameters all use basic types. However, when the content is large, there are many attributes. Splitting them into smaller components will not reduce the complexity of use;
props
Each attribute in cannot be an object, but can only beInteger
,String
,Boolean
,Array
And other basic types;
Event announcement
Zookeeper encapsulates event triggering into components to reduce business complexity. In many Web projects, page content is operated directly. User Interaction, content processing, and business logic are coupled. Here, components encapsulate user interaction and provide external event interfaces. The Code is as follows:
The component stores an Event Callback handle.clickCallback
When the component is initialized, it binds data to the user Click Event and triggers this callback.
Conclusion
This article briefly describes the positioning of small Web pages, explains the design ideas of the current project structure through exploration and evolution of small Web pages, and describes the details in detail, focuses on the data access layer and componentized development.
Zookeeper's current project is not the final form, but just the prototype of an alpha version. There are many improvements:
Optimize the time of the first screen, such as supporting SSR;
Continue to improve the packaging and deployment scheme, and flexibly support multi-page deployment to achieve or close to the effect of offline applications;
Some good ES6 syntaxes are worthy of support. You need to find a method to introduce specific syntaxes progressively at the packaging layer;
The Promise-based syntax is worth a wide range of use, which needs to be considered at the code level;
Webpack is good, but it is not good enough. I hope the plug-ins can be more mature and rich;
There may still be many points that have not been taken into consideration, but the actual demand is always the highest priority. As long as the reconstruction and improvement are ongoing, the software will remain alive ~