Webpack in Node: Front-end template development tool TDS

Webpack in Node: Front-end template development tool TDS

Introduction

A template development tool suitable for small pages, based on webpack, supports hot reloading, and packs css and js into a html template file.
The application scenarios of this gadget are not wide, but the design ideas can bring a lot of inspiration.

Specific steps can be moved: github.com/SP-Lyu/TDS
* It is just written as a summary of the work, in fact, many small but useful articles can be disassembled

Ad template tool

TDS is actually serving some small advertising templates. In those days, when we took over this one, we could only manually produce these templates. It was particularly troublesome to develop and maintain (yes, I just made a living by posting small ads) .

<!--   -->
<!-- Head -->
<style>
  /* Style Sheet */
</style>
<div id="{{ADID}}" class="wrapper">
  <img src="{{IMG}}"/>
  <img src="{{IMG}}"/>
  <img src="{{IMG}}"/>
  <div><a href="{{CLICK_URL}}">{{DESC}}</a></div>
  <div class="logo">
    <!-- LOGO logic -->
  </div>
  <script>
  //monitor
  //animate logic
  var id = {{ADID}};
  var conf = {
    showtime: {{TIME}}
    //...
  }
  //...
  </script>
</div>
<!-- Tail -->
 

In some search scenarios or network alliance scenarios, the advertising front-end logic often has the following characteristics:

  • High requirements for display and loading speed
  • Simple page, less interactive logic, but many common components
  • The iteration speed is fast, and the new template can often stimulate the increase in click-through rate
  • The back end will maintain a set of templates to fill in the materials, and the front and back ends are coupled and blocked during joint debugging.

So for the front-end development of commercial advertising, there are several points to pay attention to:

  • Optimize the display speed and remove unnecessary requests
  • Component development, batch package update
  • The front end needs to maintain a set of simulation data to facilitate development and testing

Start to optimize

According to the above appeal points, a template development tool was finally produced, which completed the template development environment initialization, development, packaging, and testing in the form of command lines.
Command Encyclopedia:

tpl -s    
tpl -l    
tpl -i <tpl_name>    
tpl -d <tpl_name> -p <port> [-q]    
tpl -b <tpl_name> [-q] [-u] [-c charset]  -u: HTML  -c:   
tpl -B [-q] [-u] [-c charset]    
tpl --delete    
 

Here are some pain points solved by this tool combined with practical applications:

Display and loading speed optimization

Usually, the front-end only keeps a simple html for page development, and introduces CSS and JS files through CDN, static files, caching, etc. However, this method is not completely suitable for the application scenarios of advertisement display . Advertising pages interactive small, simple logic , even if the css, js code is fully count, but also about the size of 15K, follow the download speed of 1MB/s, the transmission requires only 15ms to complete, and TTFB time on the request has been spent on general Greatly exceeded this value. So the most time-consuming thing is not the resource download, but the request itself .
Therefore, the optimization idea here should be: css and js are packaged into templates in a way of in-line introduction to reduce the number of resource requests and achieve the goal of fastest display speed.
In TDS, ejs is used as a template, and the packaged css and js are webpackintroduced into the template in the form of strings to achieve the purpose of in-line introduction. webpack configuration:

{
    //...
    plagins:[
        new MiniCssExtractPlugin({
            filename: "main.css",
        }),
        new HtmlWebpackPlugin({
            files:{
                "css":[`./main.css`],
                "js":[`./main.js`]
            },
            filename: `test.tpl`,
            inject: false,
            template: `test.ejs`,
            title: tpl
        }),
        new OptimizeCSSAssetsPlugin({})
    ]
    //...
}
 

Ejs template introduction:

CSS:
<style type="text/css"><%= compilation.assets[htmlWebpackPlugin.files.css[0]].source() %></style>
JS:
<script><%= compilation.assets[htmlWebpackPlugin.files.js[0]].source() %></script>
 

Component development

Component of the process, taking into account the module reusable and between modules operational independence

Module can be reused

Because some animation logic (lottery, pop-up window, carousel, etc.) is common in multiple sets of templates, and over time, if the requirements for batch changes of these logics are not handled well, a lot of development will be increased in vain. It is necessary to webpackcooperate with a certain script for batch packaging.
In TDS, packaging is carried out through Nodeintroduction webpack, and through commander.js, the Nodeprogram is commanded, so as to achieve the purpose of batch packaging.
You can see the detailed configuration introduction in packer.js .
During the development process, because I wanted to add hot reloading to the TDS tool, I investigated several existing methods, but finally found that it is possible to webpack-dev-serverstart hot reloading directly in the Node environment . The following is an example:

const webpack = require("webpack");
const WebpackDevServer = require("webpack-dev-server");

const compiler = webpack({
    //webpack conf
});

const s = new WebpackDevServer(,{
    quiet: false,
    contentBase: './'
});

s.listen(8808, '0.0.0.0', function(){});
 

The introduction of this method is much simpler than using webpack-dev-middleware+ webpack-hot-middleware(but I don t know why the official hides it so deeply, maybe because there are few application scenarios)
official example

Business independence

There will be multiple templates for different business needs. Here we have to consider the issue of business independence, so that TDS can be better applied to the development of multiple business lines. Due to the use of commander.jsthe TDS command, many customizations can be made, such as dividing the development block by business line, adding the workspaceconcept, you can tpl -sswitch the working area, and all subsequent operations (adding, deleting, packaging templates, etc.) , Are all based on the current working interval.
Each business has its own initialization template, which is stored in the templage_xxx folder, and the newly added template files are placed src/xxx/under, and the packaged templates are placed out/xxx/under, so as to ensure that each business is independent and does not interfere with each other. This is also very simple to implement. Just create a .user_configfile to record the business line of the current user, and use it as a working area to read and operate the template configuration.

//.user_config
{
    current_workspace: 'buns'
}
 

Mock data structure

The most painful problem encountered in the initial development and maintenance process is that the front-end needs to backfill the value of this template file before debugging, which is very unfriendly to the early compatibility, interaction, style and other tests. TDS maintains a set of simple test methods: When using the HtmlWebpackPluginpackaged ejs template, configure the current packaging options to distinguish the current development environment and the mock data that needs to be used:

//webpack 
new HtmlWebpackPlugin({
    files:{
        "css":['out/.tmp/main.css'],
        "js":['out/.tmp/main.js'],
    },
   // 
    dev: true,      
   // mock 
    mocks: get_files(`${tpl_path}/mocks/`),
   // mock 
    gmocks: get_files(`${tpl_path}/../Gmocks/`),
    filename: tpl + '.html',
    inject: false,
    template: tpl_path + '/' + tpl + '.ejs',
    name: tpl,
    workspace
})
 

The data source can be directly htmlWebpackPlugin.options.devdistinguished by the options in the ejs file .

<% const ejs_env = htmlWebpackPlugin.options; %>
<%/* */%>
<%= ejs_env.dev?ejs_env.gmocks['head.html'] : '' %>
<div id="current_show"></div>
<script>
<% if(ejs_env.dev){ %>
window.__g_ad_data = {
    title: ' ',
    img: './src/<%= ejs_env.workspace%>/<%= ejs_env.name%>/static/test.png',
    url: 'https://google.com'
};
<% } else {%>
    <!--  Google Ctemplate  -->
    window.__g_ad_data = {
        title: '{{TITLE}}',
        img: '{{IMG}}',
        url: '{{URL}}'
    };
<%}%>
</script>
<script>//handle window.__g_ad_data</script>
<%/* */%>
<%= ejs_env.dev ? ejs_env.gmocks['tail.html'] : '' %>
 

In this way, an effective set of mock data can be maintained during the development process. When project code is packaged, the purpose of packaging the back-end template fields can be achieved directly through the judgment of the environment.
The final package generated template:

<div id="current_show"></div>
<script>
    <!--  Google Ctemplate  -->
    window.__g_ad_data = {
        title: '{{TITLE}}',
        img: '{{IMG}}',
        url: '{{URL}}'
    };
</script>
<script>//handle window.__g_ad_data</script>
 

output

In the final overall output, due to the addition of the packaging logic of js, css, and html, the volume of the template is reduced by about 30% compared with the previous template, and the loading logic of css and js is removed, and the overall loading time of the page (not counting pictures) ) Is close to the time of an http request.
And for developers, the front-end and back-end development can be completely separated, eliminating the need for cumbersome communication costs.

data

commander.js
webpack NodeApi
webpack-dev-server NodeApi

* If you have any questions, please leave a message to exchange