Although Vue,React, and Angular dominate the front end, template engines are rarely used. But it’s important to understand how this works. Maybe you’ll meet him in your next interview. Please give him a thumbs up if it helps

Generic structure code for the template engine

   <div>
     <%= a %> // Add '=' to print the variable directlyThe < %for(let i=0; i < supplies.length; i++) { %> 
         <li><%= supplies[i] %></li>The < %} % >// Write any JavaScript expression without '='
   </div>
Copy the code

Template compilation

 const compile = function (template) {
      if(! template) {return;
      }
      const EvalExpr = / < % = (. +?) %>/g;
      const expr = /<%([\s\S]+?) %>/g;
      //$1 represents the first matched content
      $2,$3,$4... Represents the NTH match
      let compileTemplate = template
      // Replace the template variables directly
       .replace(EvalExpr, "`); \n echo( $1 ); \n echo(`")
       // Can be used to output JavaScript expressions
       .replace(expr, "`); \n $1 \n echo(`");
     return "echo(`" + compileTemplate + "`);";
  }
Copy the code

Call the template compilation method

 const render = compile(
    `
      
<%= a %> <% for(let i=0; i < supplies.length; i++) { %>
  • <%= supplies[i] %>
  • <% } %>
    `
    ); Copy the code

    The resulting compilation template

    Template rendering

    We need to return a render function when we call compile function to handle the compiled template’s render function needs to render the data provided by the user

    const compile = function (template) {
       if(! template) {return;
      }
      const EvalExpr = / < % = (. +?) %>/g;
      const expr = /<%([\s\S]+?) %>/g;
    
      //$1 represents the first matched content
      $2,$3,$4... Represents the NTH match
      let compileTemplate = template
        // Replace the template variables directly
        .replace(EvalExpr, "`); \n echo( $1 ); \n echo(`")
        // Can be used to output JavaScript expressions
        .replace(expr, "`); \n $1; \n echo(`");
    
      compileTemplate =  "echo(`" + compileTemplate + "`);";
      
      const parseDataSource = function (dataSource) {
        let variables = "";
        if (dataSource instanceof Object) {
          variables = "let ";
          const dataKeys = Object.keys(dataSource);
          if (dataKeys.length === 0) {
            return "";
          }
          dataKeys.forEach((item, index) = > {
            return (variables += `${item}=The ${JSON.stringify(
              dataSource[item]
            )}${index === dataKeys.length - 1 ? ";" : ","}`);
          });
        }
        return variables;
      };
              
      return function (data) {
         / / echo output HTML
        let script = `(function parse(dataSource) {
          'use strict';
          let output = '';
          ${parseDataSource(data)}
          function echo(html) {
            output += html;
          }
          ${compileTemplate}return output; `} ());
        return eval(script);
      };
    Copy the code

    Use template rendering methods

     const render = compile(
        `
          
    <%= a %> <% for(let i=0; i < supplies.length; i++) { %>
  • <%= supplies[i] %>
  • <% } %>
    `
    ); render({ a:1.supplies: [1.2.3]})Copy the code

    The script string generated by the render function

    The HTML returned by the render function

    conclusion

    Write any issue in a hurry and leave a message in the comment section