前端工程化===Webpack?No,我来告诉你什么是前端工程化!

简介: 前端工程化===Webpack?No,我来告诉你什么是前端工程化!

前端工程化概述


前端工程化定义和主要解决的问题


由于现在开发中,前端可以负责的范围越来越大,早已不是仅限制于网页。像 App、小程序、甚至桌面应用,都可以使用前端技术来开发。

所以原来通过前端写 Demo,后端套数据的模式早就无法支持现代多元化前端开发。

前端工程化就是在这个背景下成为了受人重视的技术,并且是目前前端开发必备的技术之一。

技术是为了解决问题而存在的,前端工程化解决了很多问题。比如 ES6 新语法、Less/Sass/PostCss 等 CSS 工具和模块化。它们都是无法被运行环境直接支持的。但是使用前端工程化以后,就可以将它们转换为运行环境支持的代码。

还有一些部署项目时所需要做的操作,比如压缩代码及资源文件,将代码上传至服务器等。如果让人来手动处理这些任务,会很容易出现操作失误。这种情况下,让机器自动来完成这些任务更为合理。

多人协作时,代码风格、代码质量都需要得到保证。

开发过程中需要等待后端接口提前完成。

这些都是前端工程化负责的范畴。

总结起来,前端工程化解决的问题主要有 6 个部分。

  1. 传统语言或语法的弊端。(ES6+语法、TypeScript、Sass)
  2. 无法使用模块化/组件化(ES Modules、Components)
  3. 重复的机械式工作(Build、Publish)
  4. 代码风格统一、质量保证(git、ESLint)
  5. 依赖后端服务接口支持(Mock)
  6. 整体依赖后端项目(DevServer)


工程化表现


一切以提高效率、降低成本、质量保证为目的的手段都属于工程化。

一切重复的工作都应该被自动化。

一个常规前端项目的整体环节大约有 5 步:

创建项目-编码-预览/测试-提交-部署

1.创建项目阶段:

借助脚手架工具自动创建项目目录结构和特定类型的文件。

2.编码阶段:

借助工具实现代码格式化、校验代码风格,还可以使用新的特性来编写源代码,通过编译/构建/打包生成运行环境支持的运行时代码。

3.预览/测试阶段

开发过程,需要 Mock 服务,需要使用基础的 Web 服务器来托管项目,比如 Nginx、Apatch 等。但这些服务都不提供热更新的体验,所以需要借助现代化的工具来提高开发体验。

在编译转换后,如果发生异常,需要定位源代码的位置。这是就需要使用 Source Map 技术来映射运行代码和源代码。

4.代码提交阶段

使用 git hooks 对项目整体进行检查,包括代码风格的检查和项目质量的检查,确保不会将有问题的代码提交到 git 仓库中,这样 git 仓库的代码永远都是可用的。除此以外,还可以对 git log 的格式进行限制,这样在代码分支合并和回滚时有很大的价值。

主要借助的工具有 Lint-staged 和持续集成等。

5.部署阶段

CI/CD、自动发布。

可以通过一行命令自动的将项目打包上传至 ftp 服务器。


工程化不等于工具


现在有些工具非常强大,像 Webpack,以至于很多人认为前端工程化就是指 webpack。

实际上,工具不是工程化的核心,工程化的核心是对项目的整体规划和架构。工具只是实现这种规划和架构的一种手段。

一个项目的工程化,首先要规划出一个项目整体的工作流架构。

如文件组织结构(按作用分层、按业务分层)、代码开发范式(语法、规范、标准、语言,如 ES6+、TypeScript 等)、前后端分离方式(Ajax 和中间层)。

规划完工作流整体架构以后,再来考虑使用哪些工具来实现这套规划。

可以借鉴目前业界成熟的工程化方案中的思路,如 create-react-app、vue-cli、angluar-cli、gatsby-cli 等。

它们并不是一个简单的项目生成脚手架,而是工程化工具的集成。


工程化与 Node.js


目前前端的工程化很大程度上都归功于 Node.js。

Node.js 是继 Ajax 后有一次颠覆式的前端工业革命,没有 Node.js 就没有今天的前端。

目前绝大多数工程化工具都是由 Node.js 开发的,所以前端工程化是由 Node.js 强力驱动的。

总之,工程化是为了解决问题而存在的。


脚手架工具


概要


脚手架工具是前端工程化的发起者,它是自动帮助我们创建项目基础结构、提供项目规范和约定的工具。

在开发相同类型的项目时,会有很多相同的东西,包括:

组织结构

开发范式

模块依赖

工具配置

基础代码

...

这些相同的东西不需要人为创建,可以使用脚手架工具快速创建项目骨架。然后基于这个骨架来开发。

比如使用大型的 IDE,如 IDEA 和 Visual Studio 等来创建项目的过程就是一个脚手架的工作流程。

前端的脚手架和服务端项目、移动端项目不太一样。因为技术选型过于多样化,所以不会集中在某一个特定的 IDE 中,目前流行的做法是在命令行中来完成项目的创建。


常用的脚手架工具


React 项目: create-react-app

Vue 项目: vue-cli

Angular 项目: angular-cli

它们根据用户选择的信息创建对应的项目基础结构,不过它们只能服务于本身的框架,并不通用。

另一类是通用型脚手架工具,代表像 Yeoman。优点是灵活易扩展。

还有一类是在项目开发过程中会使用到的,比如 Plop。它可以创建某种特定类型的文件。比如某个模块或是某个组件的基础代码。


Yeoman


yeoman 是最老牌、最强大、最通用的脚手架工具之一,基于 node.js 开发。

不同于常规的脚手架工具,yeoman 更像是一个脚手架的运行平台。

我们可以自己定义 Generator 来创建属于自己的项目脚手架。

Yeoman 的缺点就是它的优点,因为不够专注,所以在专注于某项框架的脚手架创建过程中不如 vue-cli 这类工具。


基本使用


1.全局安装 yeoman。


npm i -g yo

安装完 yo 之后,可以查看版本号来确认安装是否成功。


yo --version


2.安装 Generator。


只安装 yo 是不够的,它只是一个 Generator 运行模块,还需要安装特定的 Generator。

比如一个 node 项目,就需要安装generator-node


npm i -g generator-node


3.通过 yo 命令运行 generator。


安装完成之后,就可以创建 node 项目了。

命令是 yo 加上 generator 的名字。(node 包名去掉 generator-)



         

在项目创建过程中,yeoman 会提问一些问题,通过用户提交的答案来创建不同的项目结构。


Sub Generator


每个 generator 都可以提供 sub generator,用于生成特定的文件或者基础代码。但也不是每一个 generator 都提供了 sub generator,具体可以去 generator 的官方文档查看。

运行 sub generator 也比较简单,就是 yo 加上 generator 的名字,再加上冒号(:),最后加上 sub generator 的名字。

比如在 node.js 项目中创建一个命令。


yo node:cli

Yeoman 使用步骤总结


大致上分为 6 步。

  1. 明确项目需求。
  2. 找到合适的 Generator。
  3. 全局安装 Generator。
  4. 通过 yo 运行对应的 Generator。
  5. 通过命令行交互填写生成选项。
  6. 生成所需要的项目结构。


自定义 Generator


因为官方的 generator 在某些场景下作用会非常局限,所以我们有必要自定义自己的 generator。


创建 Generator 模块


generator 本质上就是一个 npm 模块,只需要符合特定的结构即可。

generator 的名字必须是 generator-<name> 的格式。

generator 需要有一个生成器的基类。

整体的的操作步骤如下。

创建项目根目录。


mkdir generator-sample

初始化项目。


npm init -y

安装 yeoman-generator。


npm i yeoman-generator

按照项目结构要求,创建特定的文件夹。

入口文件是 generators/app/index.js

这个文件需要导出一个继承自 Yeoman Generator 的 class。Yeoman Generator 在工作时会自动调用这个 class 中的生命周期函数。

在这个导出的类中,可以调用父类提供的工具方法实现一些具体的功能。

比如在 writing 生命周期函数中可以创建一些文件。


const Generator = require("yeoman-generator");
module.exports = class extends Generator {
  writing() {
    // 模版文件路径
    const tmpl = this.templatePath("foo.txt");
    // 输出目标路径
    const output = this.destinationPath("foo.txt");
    // 模板数据上下文
    const context = { title: "Hello", success: false };
    this.fs.copyTpl(tmpl, output, context);
  }
};

操作文件可以使用父类中提供的 this.fs 模块下的方法。这个 fs 和 nodejs 原生的 fs 不一样,是高度封装过的,所以功能更加强大。


根据模板创建文件


如果一个项目所需要的文件过多,挨个文件创建会很麻烦,这时候使用模板的方式来创建文件更加方便。

在 generators/app 目录下创建 templates 文件夹,该文件夹下的文件都是模板文件。可以被 this.templatePath 方法获取到。

模板文件完全遵循 EJS 语法,即尖括号百分号的写法。

<%= name %>

EJS 模板官网:https://ejs.co/

最终使用 this.fs.copyTpl 方法将模板拷贝到目标目录下。

相对于手动创建每个文件,模板的方式大大提高了效率。


接收用户输入数据


模版中的动态数据需要用户来输入,一般会在命令行中发起询问。

promting 生命周期函数中可以调用父类的 prompt 方法来发起询问,这个询问返回的是一个异步函数。


const Generator = require("yeoman-generator");
module.exports = class extends Generator {
  prompting() {
    // prompt 的参数是一个数组,可以发起多个问题
    // 每个问题都是以一个对象的形式体现
    // type 是问题的类型,input 代表需要用户来输入,除此以外还有单选、多选等。
    // name 是问题的 key
    // message 是问题的提示
    // default 是用户不做输入时的默认值
    return this.prompt([
      {
        type: "input",
        name: "name",
        message: "Your project name",
        default: this.appname,
      },
    ]).then((answers) => {
      // answers 会以一个对象的形式返回
      // { name: 'user input value' }
      // 将这个对象挂载到 this.answers
      this.answers = answers;
    });
  }
  writing() {
    // 模版文件路径
    const tmpl = this.templatePath("foo.txt");
    // 输出目标路径
    const output = this.destinationPath("foo.txt");
    // 将上下文对象替换为用户输入对象
    const context = this.answers;
    this.fs.copyTpl(tmpl, output, context);
  }
};


Vue Generator 项目案例


首先可以通过 vue-cli 生成一个基础的 vue 项目骨架,然后将这个骨架作为基础模板来使用。需要被变量替换的地方都使用 EJS 的语法替换掉。

在 writing 生命周期函数中通过遍历的方式将模板中所有文件都调用一遍 this.fs.copyTpl。

具体步骤就不演示了。


发布 Generator


generator 的发布流程和 npm 普通的包是一样的,通过 npm publish 命令去发布。

如果想要被 yeoman 官方收录,那么就需要在关键词中添加 yeoman-generator。


Plop


除了 yeoman 这类大型的脚手架工具外,还有很多小而美的脚手架工具,比如 Plop。

Plop 常用于在项目开发过程中创建某类类型的文件,优点类似于 Yeoman 中 sub generator 的概念。


应用场景


比如在 React 项目的开发过程中,开发一个组件需要创建 1 个目录,该目录下需要 3 个文件。


.
|____Footer
| |____Footer.tsx
| |____Footer.scss
| |____Footer.test.ts

如果我们手动的创建这些文件,并编写通用的代码,过程会非常繁琐,所以可以使用 Plop 来实现这个功能。


Plop 用法


首先将 plop 添加到项目中。


npm install --save-dev plop

在项目根目录下创建 plopfile.js 文件,它是 plop 工作所需要的入口文件。

一个简单的 plopfile.js 配置如下:


// 导出一个函数
// 该函数需要接收一个 plop 对象参数
module.exports = (plop) => {
  // 调用 setGenerator 方法
  // 第一个参数是命令名,第二个参数是配置对象
  plop.setGenerator("component", {
    description: "create a component", // 说明
    // 询问
    prompts: [
      {
        type: "input",
        name: "name",
        message: "component name",
        default: "MyComponent",
      },
    ],
    // 动作
    actions: [
      {
        type: "add", // 添加文件
        // 使用 {{ }} 语法拿到上面询问的值
        path: "src/components/{{name}}/{{name}}.tsx",
        // 模板的文件路径
        templateFile: "plop-templates/component.hbs",
      },
      // 添加 scss 文件和 test 文件
      {
        type: "add", // 添加文件
        // 使用 {{ }} 语法拿到上面询问的值
        path: "src/components/{{name}}/{{name}}.scss",
        // 模板的文件路径
        templateFile: "plop-templates/component.scss.hbs",
      },
      {
        type: "add", // 添加文件
        // 使用 {{ }} 语法拿到上面询问的值
        path: "src/components/{{name}}/{{name}}.test.ts",
        // 模板的文件路径
        templateFile: "plop-templates/component.test.ts.hbs",
      },
    ],
  });
};

上面这种 hbs 文件遵循 handlebars 的语法,具体参考:https://handlebarsjs.com/

模板一般存放在根目录下的 plop-templates 文件夹下。

最后就可以通过命令运行 plop 脚本。


npx plop component

总结一下,plop 的使用步骤共有 5 步。

  1. 将 plop 模块作为项目开发依赖安装。
  2. 在项目根目录下创建一个 plopfile.js 文件。
  3. 在 plopfile.js 文件中定义脚手架任务。
  4. 编写用于生成特定类型文件的模板。
  5. 通过 Plop 提供的 CLI 运行脚手架任务。


脚手架的工作原理及简单 Demo 开发


脚手架的工作原理相对简单,大致上都是在启动时询问用户一些问题,通过得到的答案配合模板生成对应的文件。

开发脚手架的思路:

  1. 通过命令行交互询问客户问题。
  2. 根据用户回答的结果生成文件。

创建脚手架项目文件夹。


mkdir sample-scaffolding

初始化项目。


npm init -y

在 package.json 中添加 bin 字段,定义 cli 的入口文件。


{
  "bin": "cli.js"
}

创建 cli.js。


touch cli.js

因为需要在控制台对用户发起询问,所以要借助一个 nodejs 的库,inquirer。


npm i --save-dev inquirer

除此之外,还需要借助模板引擎来给模板文件注入变量,所以需要借助 ejs。


npm i ejs

现在可以在 cli.js 中编写逻辑。


#!/usr/bin/env node
const fs = require("fs");
const path = require("path");
const inquirer = require("inquirer");
const ejs = require("ejs");
// 执行命令后,直接发起询问。
inquirer
  .prompt([
    {
      type: "input",
      name: "name",
      message: "Project name?",
    },
  ])
  .then(
    // 返回值 anwsers 是一个对象
    (anwsers) => {
      // 模板目录
      const tmplDir = path.join(__dirname, "templates");
      // 目标目录
      const destDir = process.cwd();
      // 将模板目录下的所有模板文件通过模板引擎转换后复制到目标目录中
      fs.readdir(tmplDir, (err, files) => {
        if (err) throw err;
        // 遍历所有模板文件
        files.forEach((file) => {
          // 通过 ejs 渲染文件
          ejs.renderFile(path.join(tmplDir, file), anwsers, (err, result) => {
            if (err) throw err;
            // 将 ejs 渲染后的文件写入目标文件中
            fs.writeFileSync(path.join(destDir, file), result);
          });
        });
      });
    }
  );

第一行的 #!/usr/bin/env node 是告诉系统,该文件通过 node 来执行。

接下来创建模板文件夹。


mkdir templates

创建模板文件 index.html 和 style.css。

index.html 内容:


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title><%= name %></title>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    hello, world!
  </body>
</html>

style.css 内容:


body {
  background-color: #ddffdd;
  color: #060606;
}

将命令链接到全局。


npm link

到这里,简单的脚手架 demo 就开发完成了。

现在开始测试,到其他目录创建一个项目目录。


mkdir test-project

进入该目录,执行脚手架命令。


sample-scaffolding

此时命令行会出现询问,输入项目名,就可以看到生成后的文件了。


? Project name? hello

写在最后


脚手架工具是前端工程化的第一块内容,到此讲解结束,接下来会发布另外几篇关于前端工程化的文章,敬请期待。

- END -


相关文章
|
监控 前端开发 JavaScript
前端工程化和传统前端开发的区别是什么?
前端工程化相比传统前端开发,在开发模式、代码组织与管理、构建与部署流程、团队协作、性能优化以及技术选型等方面都有了显著的改进和提升,能够更好地应对现代前端应用开发的复杂性和高要求。
|
JSON 前端开发 JavaScript
不会webpack的前端可能是捡来的,万字总结webpack的超入门核心知识
该文章提供了Webpack的基础入门指南,涵盖安装配置、基本使用、加载器(Loaders)、插件(Plugins)的应用,以及如何通过Webpack优化前端项目的打包构建流程。
不会webpack的前端可能是捡来的,万字总结webpack的超入门核心知识
|
前端开发 JavaScript 持续交付
揭秘!前端大牛们如何巧妙利用前端工程化,提升团队协作效率!
【10月更文挑战第30天】前端工程化是将前端开发视为工程项目,通过工具、方法和流程优化开发过程,提升代码可维护性、可扩展性和可测试性,降低团队协作成本。核心工具如Webpack、Git和CI,帮助实现自动化构建、版本控制和持续集成,显著提高开发效率和项目稳定性。
368 6
|
缓存 监控 前端开发
前端工程化:Webpack与Gulp的构建工具选择与配置优化
【10月更文挑战第26天】前端工程化是现代Web开发的重要趋势,通过将前端代码视为工程来管理,提高了开发效率和质量。本文详细对比了Webpack和Gulp两大主流构建工具的选择与配置优化,并提供了具体示例代码。Webpack擅长模块化打包和资源管理,而Gulp则在任务编写和自动化构建方面更具灵活性。两者各有优势,需根据项目需求进行选择和优化。
476 7
|
前端开发 JavaScript 开发者
工程化(webpack+vite)
在现代前端开发中,工程化是提高开发效率和项目质量的关键。UniApp 结合 Webpack 和 Vite,提供强大的工程化支持。Webpack 功能强大,支持复杂项目的构建;Vite 则利用现代浏览器的 ESM 特性,提供快速的开发体验。开发者可根据项目需求选择合适的工具,显著提升开发效率和项目质量。
|
缓存 前端开发 JavaScript
前端性能优化:Webpack与Babel的进阶配置与优化策略
【10月更文挑战第28天】在现代Web开发中,Webpack和Babel是不可或缺的工具,分别负责模块打包和ES6+代码转换。本文探讨了它们的进阶配置与优化策略,包括Webpack的代码压缩、缓存优化和代码分割,以及Babel的按需引入polyfill和目标浏览器设置。通过这些优化,可以显著提升应用的加载速度和运行效率,从而改善用户体验。
438 6
|
缓存 前端开发 JavaScript
前端工程化:Webpack与Gulp的构建工具选择与配置优化
【10月更文挑战第27天】在现代前端开发中,构建工具的选择对项目的效率和可维护性至关重要。本文比较了Webpack和Gulp两个流行的构建工具,介绍了它们的特点和适用场景,并提供了配置优化的最佳实践。Webpack适合大型模块化项目,Gulp则适用于快速自动化构建流程。通过合理的配置优化,可以显著提升构建效率和性能。
355 2
|
前端开发 JavaScript 开发者
工程化(webpack+vite)
工程化(webpack+vite)
207 3
|
前端开发 JavaScript 开发者
构建工具对比:Webpack与Rollup的前端工程化实践
【10月更文挑战第11天】本文对比了前端构建工具Webpack和Rollup,探讨了它们在模块打包、资源配置、构建速度等方面的异同。通过具体示例,展示了两者的基本配置和使用方法,帮助开发者根据项目需求选择合适的工具。
565 3
|
前端开发 JavaScript Shell
深入解析前端构建利器:webpack核心概念与基本功能全览
深入解析前端构建利器:webpack核心概念与基本功能全览—
529 1

热门文章

最新文章

  • 1
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
    1280
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    586
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    445
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    446
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    568
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    744
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    1454
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    324
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    1177
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    518