Working people! For the soul! It’s the front end! This series is summed up in the process of learning in the road of big front attack. If there is something wrong in the article, I hope you can criticize and correct it and make progress with each other. Please indicate the source and attach the original address.

What is front-end engineering?

Front-end engineering refers to following certain standards and specifications within the team, using tools to improve developer productivity, reduce maintenance costs, and reduce uncontrollable factors caused by manual errors.

What problem has it solved for us?

Let’s start with a list of some of the most common problems encountered during daily development (and not just that) :

  1. We would like to use Less/Sass to enhance the programmability of CSS, but the runtime environment does not support it directly, requiring us to do repetitive work such as compiling.
  2. We have compatibility issues when we want to use new ECMAScript features.
  3. If you want to use a modular approach to improve project maintainability, the runtime environment does not directly support it.
  4. The resource files need to be manually compressed before the project deployment goes online, and the code needs to be manually uploaded to the server during the process, which is prone to problems.
  5. Multi-person collaborative development, everyone’s code style is not the same, can not be rigid unity of everyone’s code style.
  6. .

We summarize these problems as follows:

  • Disadvantages of traditional language and grammar
  • Modularity or componentization cannot be used
  • Repetitive mechanical work
  • The code style and format cannot be rigidly unified
  • Warehouse code quality cannot be guaranteed
  • Depends on back-end service interface support
  • Overall reliance on back-end projects

Specific Solutions

Let’s take a simple project development process as an example and look at the role of front-end engineering in this process. Let’s first get an overview of front-end engineering from a holistic perspective. From project creation, coding, preview, submission and deployment, we can improve work efficiency through front-end engineering.

  1. The process of creating a project can be done automatically using the scaffolding tool.
  2. During the coding process, we can use some new features in advance through compilation or transformation tools. Use formatting and code review tools to automatically detect and fix basic problems in your code.
  3. You can preview automatically through the Web Server and enjoy hot updates, and you can Mock out specific business functions without completing the back-end service interface.
  4. When it comes to code submission, Git Hook can be used to automate project checking before submission to ensure that no problematic code is submitted, and even the submitted logs can be formatted strictly.
  5. Finally, in the deployment phase, you can replace the traditional manual FTP upload with a single command, or even deploy to the server automatically after the code has been submitted.

Engineering ≠ tools

Now Webpack is powerful, many people think that the front-end engineering is Webpack, with Webpack is engineering, but in fact it is not the case, tools can not be code engineering, engineering should be the core of a project planning or architecture, tools are just a means of implementation.

Taking a common project as an example, the first thing to implement engineering is to plan the workflow architecture of the overall project, including:

  1. Organizational structure of files
  2. Source code development paradigm
  3. A language or grammar specification
  4. Front and rear end separation mode
  5. Other requirements for the development phase

Once you have this overall plan in place, consider which tools to use and which options to configure. This is an engineering process.

Scaffolding tool

After a preliminary understanding of front-end engineering, start with scaffolding and see how front-end engineering performs in the project creation process.

What is scaffolding?

Scaffolding can be simply understood as a tool that automatically helps us create the project’s base files, and more importantly provides developers with conventions or specifications, including:

  • Same file organization structure
  • Same code development paradigm
  • Same module dependencies
  • Same tool module configuration
  • Same basic code

Scaffolding can be used to avoid a lot of rework that we would have to do to build a new project during actual development. Scaffolding work is used to quickly build the basic skeleton structure of a specific type of project, such as VUe-CLI, on which subsequent development work is based.

Implement a small scaffolding tool of our own

Train of thought

The working process of scaffolding:

  1. The user uses scaffolding, which asks the user questions through command line interaction
  2. The scaffold generates files based on the user’s answers

The implementation process

  1. Create a directory my-cli

  2. Create package. Json

    npm iniy -y
    Copy the code
  3. Add the bin field to package.json to specify the scaffolding entry file cli.js

    {
      "name": "my-cli"."version": "1.0.0"."description": ""."main": "index.js"."bin": "cli.js"."scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      }
    Copy the code
  4. Install the dependent plug-ins inquirer and EJS

    npm i inquirer // Used to ask developers questions
    npm i ejs      // Template engine
    Copy the code
  5. Create the cli.js file

    #! /usr/bin/env node
    // The Node CLI application entry file must have such a header.
    // Let the system dynamically find node to solve the problem of different machine and different user Settings are inconsistent
    const fs = require("fs");
    const path = require("path");
    const inquirer = require("inquirer");
    const ejs = require("ejs");
    
    // Ask the user
    inquirer
      .prompt([
        {
          type: "input".name: "name".message: "Your Project Name?",
        },
      ])
      .then((anwsers) = > {
        // Template directory
        const tmplDir = path.join(__dirname, "templates");
        // process.cwd() returns the current working directory, the target directory
        const destDir = process.cwd();
        // fs.readdir() gets the names of all files in the template directory
        fs.readdir(tmplDir, (err, files) = > {
          if (err) throw err;
          // Iterate over the file name
          files.forEach((file) = > {
            // Render files through the template engine
            ejs.renderFile(path.join(tmplDir, file), anwsers, (err, result) = > {
              if (err) throw err;
              // console.log(result);
              // Write the result to the destination file path
              fs.writeFileSync(path.join(destDir, file), result);
            });
          });
        });
      });
    
    Copy the code
    // templates/index.html
    <! DOCTYPEhtml>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
        <title><%= name %></title>
    </head>
    <body>
        
    </body>
    </html>
    Copy the code
  6. Associate scaffolding to the global

    npm link
    Copy the code
  7. test

    MY-CLI
    Copy the code

    Run the command in the testcli folder and enter name according to the command line query to generate the corresponding template file in the folder.

Gulp automated build

demand

Build the project using gulp tools. The main tasks include converting SCSS files, ECMAScript new features, swig template pages, and dist packages online. Optimize the construction process and improve the development efficiency of the development process. Image, font files, HTML, JS, CSS file compression.

Implementation steps

  1. Install gulp as a development dependency and create gukpfile.js.
  2. Implement compilation of style files. The plugin used is gulp-sass. Since we need to use gulp-useref file reference processing, we first put the compiled files in the temp folder, and the code after useref processing is put in the dist folder.
  3. To compile the script file, new ECMAScript features need to be compiled using gulp-babel, @babel/core, and @babel/preset-env. Gulp-bale is just a conversion platform, so @babel/core and @babel/preset-env are required to compile.
  4. Template file compilation, using gulp-swig plug-in.
  5. The plug-in for other files and file removal is del. We need to transfer some additional public files directly into the dist folder. Remove the dist folder first with each build.
  6. Image and font file conversion compression, using the plugin gulp-Imagemin. Since multiple gulp plugins were used, it was cumbersome to introduce them one by one, so we used gulp-load-plugins.
  7. We need a development server that supports hot updates to debug our project, and gulP to manage the server so that we can automatically compile and refresh the browser page when we modify the code, improving our development efficiency and reducing repetitive operations. Here we need to use gulp’s Watch method to monitor our files and perform corresponding tasks if there are updates to achieve the purpose of hot update.
  8. Optimize our build process. In the development stage, image, font and other resources can directly use the files in the original directory, which can speed up the construction efficiency in the development process. Is the Develop task in your code for use in development.
  9. Also need to create the online version of the compiled task, need to clear, and then compile the style, script, page files using useref to build comments to solve the problem of online version file reference, while the online version of THE HTML CSS JS file compression. Compile compressed images, font files, and other public files into the dist folder. Specifically for the build task in the code, build online version used.
  10. Test complete.

Specific plug-in

gulp-sass gulp-babel gulp-clean gulp-clean gulp-swig gulp-imagemin gulp-load-plugins gulp-useref browser-sync Gulp-htmlmin gulp-uglify gulp-clean-css gulp-if

Implement complete code

// gulpfile.js
const { src, dest, series, parallel, watch } = require("gulp");
const loadPlugins = require("gulp-load-plugins");
const plugins = loadPlugins();
const del = require("del");
const browserSync = require("browser-sync");

const bs = browserSync.create();
// Simulate data
const data = {
  menus: [{name: "Home".icon: "aperture".link: "index.html"}, {name: "Features".link: "features.html"}, {name: "About".link: "about.html"}, {name: "Contact".link: "#".children: [{name: "Twitter".link: "https://twitter.com/w_zce"}, {name: "About".link: "https://weibo.com/zceme"}, {name: "divider"}, {name: "About".link: "https://github.com/zce",},],},],pkg: require("./package.json"),
  date: new Date()};// Clear the dist folder
const clean = () = > {
  return del(["dist"."temp"]);
};

// Style compilation
const style = () = > {
  // Read all SCSS files below SRC, set the base path to SRC, keep the directory structure after SRC
  return src("src/assets/styles/*.scss", { base: "src" })
    .pipe(plugins.sass({ outputStyle: "expanded" })) // Compile SCSS file with sass, output style is fully expanded
    .pipe(dest("temp"))
    .pipe(bs.reload({ stream: true })); // Call the BS reload method after each compilation as a stream
};
// Script compilation
const script = () = > {
  return src("src/assets/scripts/*.js", { base: "src" })
    .pipe(plugins.babel({ presets: ["@babel/preset-env"] }))
    .pipe(dest("temp"))
    .pipe(bs.reload({ stream: true }));
};
// Template compilation
const page = () = > {
  return src("src/*.html", { base: "src" })
    .pipe(plugins.swig({ data, defaults: { cache: false } }))
    .pipe(dest("temp"))
    .pipe(bs.reload({ stream: true }));
};
// Image compression
const image = () = > {
  return src("src/assets/images/**", { base: "src" })
    .pipe(plugins.imagemin())
    .pipe(dest("dist"));
};
/ / font
const font = () = > {
  return src("src/assets/fonts/**", { base: "src" })
    .pipe(plugins.imagemin())
    .pipe(dest("dist"));
};
// Additional files
const extra = () = > {
  return src("public/**", { base: "public" }).pipe(dest("dist"));
};

// The development server starts the task
const serve = () = > {
  // Monitor the path if the file changes to perform the corresponding task
  watch("src/assets/styles/*.scss", style);
  watch("src/assets/scripts/*.js", script);
  watch("src/*.html", page);
  watch(
    ["src/assets/images/**"."src/assets/fonts/**"."public/**"],
    bs.reload
  );
  / / initialization
  bs.init({
    notify: false.port: 2080.// Monitor all folders under the dist folder to automatically update the page
    // files: "dist/**",
    server: {
      // Set the root directory of the website
      baseDir: ["temp"."src"."public"].BaseDir = baseDir = baseDir = baseDir
      routes: {
        "/node_modules": "node_modules",}}}); };const useref = () = > {
  return (
    src("temp/*.html", { base: "temp" })
      .pipe(plugins.useref({ searchPath: ["temp"."."]}))// Compress HTML JS CSS
      .pipe(plugins.if(/\.js$/, plugins.uglify()))
      .pipe(
        plugins.if(
          /\.html$/,
          plugins.htmlmin({
            collapseWhitespace: true.minifyCSS: true.minifyJS: true,
          })
        )
      )
      .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
      .pipe(dest("dist"))); };// SRC the files below are compiled
const compile = parallel(style, script, page);
// All tasks
const build = series(
  clean,
  parallel(series(compile, useref), image, font, extra)
);

const develop = series(compile, serve);
module.exports = {
  develop,
  build,
  clean,
  compile,
  useref,
};

Copy the code

History article portal

  • Big front – end approach (a) functional programming
  • Big front – end approach (two)JavaScript asynchronous programming
  • Hand write promises
  • New ECMAScript features
  • Getting started with TypeScript

reference

Pull hook big front end training camp