1, talk about your initial understanding of engineering, combined with the problems you have encountered before name more than three engineering can solve the problem or bring value.

Engineering: that is, through the systematic, modular, standardized process to solve the project from development to the whole software software life cycle, in order to improve efficiency.

Problems to be solved for front-end engineering:

1. Choose an appropriate front-end framework to improve development efficiency

2. Use version management tools to manage code efficiently

3. Use coding specifications such as directory structure, code style, code detection, etc to normalize the process

4. Complete build scripts and build systems

2. What deeper purpose do you think scaffolding serves besides creating a project structure?

1. Improve the speed of project construction and reduce repetitive work, so that developers can better focus on software development

2. Built projects will have the same directory structure, module dependencies, and base configuration to improve code maintainability

3. Outline the scaffolding implementation process and use NodeJS to complete a custom small scaffolding tool
What is scaffolding?

Scaffolding the term scaffolding was first seen in the programming world when it was used in front of a frame. Many teams specify a front-end work plan that includes a scaffold template, and while the concept of front-end engineering varies from team to team, the scaffolding position is the same: create a project initialization file.

Why scaffolding, the nature of scaffolding?

What pain points have been solved using scaffolding:

  • Front-end project configuration is more and more tedious, time-consuming, there is a need to repeat meaningless work
  • The project structure is not standardized and unified
  • Different projects require different configurations, resulting in high management costs

Create the project infrastructure and provide project specifications and conventions

  • Same organizational structure
  • Same development paradigm
  • Same module dependencies
  • Same tool configuration
  • Same code base

Scaffolding can be used to build medium and large front-end projects out of the “rough behavior”, into a more standardized engineering construction thinking. After all, the first step in engineering is to use tools to reduce repetitive tasks and increase productivity

How to build a scaffold

Scaffolding implementation process

  • Ask the user questions through command line interaction
  • According to the user input information, combined with the template file, finally generate the project structure

Scaffolding implementation process:

  • Package. json Added bin field

    "bin": {
        "cli": "./bin/index"
     },
    Copy the code
  • /bin/index.js To compile a script file

  • The dependencies that need to be used by asking the user for input information are: Inquirer, EJS

    #! /usr/bin/env node
    // the initial contents of index.js
    
    // yarn add inquirer
    // yarn add ejs
    
    const path = require("path");
    const inquirer = require("inquirer");
    const fs = require("fs");
    const ejs = require("ejs");
    
    inquirer
      .prompt([
        {
          type: "input".name: "name".message: "Project name?",
        },
      ])
      .then((anwsers) = > {
        // console.log(anwsers); { name: '1' }
        const temDir = path.join(__dirname, "templates");
        const destDir = process.cwd();
        fs.readdir(temDir, (err, files) = > {
          if (err) throw err;
          files.forEach((file) = > {
            ejs.renderFile(path.join(temDir, file), anwsers, (err, result) = > {
              if (err) throw err;
              fs.writeFileSync(path.join(destDir, file), result);
            });
          });
        });
      });
    
    Copy the code
  • The dependencies used to build project templates from the command line are: Inquirer, EJS, Download-git-repo, and Commander

    #! /usr/bin/env node
    // do something
    // the initial contents of index.js
    
    // yarn add inquirer
    // yarn add ejs
    // yarn add download-git-repo
    
    const path = require("path");
    const inquirer = require("inquirer");
    const fs = require("fs");
    const ejs = require("ejs");
    // Require ('commander') will create a singleton within Commander and return program, which is already an instance
    const program = require("commander");
    const download = require("download-git-repo");
    
    // Parse parses the parameters of the command and executes the commands according to the rules defined above
    program.version("0.0.1"."-v --version");
    
    // option defines a parameter name and description
    program
      .option("-d, --debug"."output extra debugging")
      .option("-s, --small"."small pizza size")
      .option("-p, --pizza-type <type>"."flavour of pizza")
      .option("-t, --type <type>"."test type");
    
    //.command() is used to configure commands and parameters, where <> indicates that parameters are required and [] indicates that parameters are optional.
    //.description() Adds a command description
    //.action() is used to add action functions, whose input arguments are used to configure commands
    // program.parse(process.argv); Process command line arguments
    
    program
      .command("init <templateName> <projectName>")
      .action((templateName, projectName) = > {
        if (templateName === "vue") {
          console.log("clone template ...");
          download("github:vuejs/vue", projectName, function (err) {
            console.log(err ? "Error" : "Success");
          });
        } else if (templateName === "react") {
          console.log("clone template ...");
          download("github:facebook/react", projectName, function (err) {
            console.log(err ? "Error" : "Success");
          });
        } else {
          console.error("A template name that does not exist"); }}); program.parse(process.argv);Copy the code
4. Try to use Gulp to complete the automatic construction of the project

The perception of Gulp as the preferred front-end automation build tool is as follows:

  • Each gulp task (task) is an asynchronous javascript function
  • The gulp build code is in gulpfile.js
  • Build synchronous and asynchronous tasks

Gulp automatic build project scripts need to deal with the following problems: static resource files (images, text), style files, script files, page code:

Dependencies to install:

// yarn add gulp --dev // yarn add gulp-load-plugins --dev // yarn add gulp-babel --dev // yarn add @babel/core @babel/preset-env --dev // yarn add gulp-swig --dev // yarn add gulp-imagemin --dev // yarn add del --dev // yarn add browser-sync --dev // yarn add gulp-htmlmin gulp-uglify gulp-clean-css --dev // yarn add gulp-if --dev // yarn add gulp-scss --devCopy the code

The complete build code is as follows:

// Implement the build task for this project
const loadPlugins = require("gulp-load-plugins");
const browserSync = require("browser-sync");
const { src, dest, series, parallel, watch } = require("gulp");
const del = require("del");

const plugins = new loadPlugins();
const bs = browserSync.create();

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()};// Process resource files
const image = () = > {
  return src("src/assets/images/**", { base: "src" })
    .pipe(plugins.imagemin())
    .pipe(dest("dist"));
};

// Process resource files
const font = () = > {
  return src("src/assets/fonts/**", { base: "src" })
    .pipe(plugins.imagemin())
    .pipe(dest("dist"));
};

// Handle styles
const style = () = > {
  return src("src/assets/styles/*.scss", { base: "src" })
    .pipe(plugins.sass({ outputStyle: "expanded" }))
    .pipe(dest("dist"));
};

// Process js files
const script = () = > {
  return src("src/assets/scripts/*.js", { base: "src" })
    .pipe(plugins.babel({ presets: ["@babel/preset-env"] }))
    .pipe(dest("dist"));
};

/ / deal with HTML
const page = () = > {
  return src("src/*.html", { base: "src" })
    .pipe(plugins.swig({ data }))
    .pipe(dest("dist"));
};

// Clean up the temporary directory
const clean = () = > {
  return del(["dist"]);
};

const useref = () = > {
  return src("dist/*.html", { base: "dist" })
    .pipe(plugins.useref({ searchPath: ["dist"."."] }))
    .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"));
};

/ / compile
const compile = parallel(image, font, style, script, page);
/ / build
const build = series(clean, parallel(series(compile, useref)));

/ / to monitor
const serveWatch = () = > {
  watch("src/assets/styles/*.scss", style);
  watch("src/assets/scripts/*js", script);
  watch("src/*.html", page);

  watch(
    ["src/assets/images/**"."src/assets/fonts/**"."src/*.html"],
    bs.reload()
  );

  bs.init({
    port: 3000.notify: false.server: {
      baseDir: ["dist"."src"].files: "dist/**".routes: {
        "/node_modules": "node_modules",}}}); };const serve = series(compile, serveWatch);

const start = () = > {};

module.exports = {
  serve,
  clean,
  build,
};

Copy the code