前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
  • React专栏

    • React组合式开发实战

      • 前端开发的四个时代
      • 企业管理系统的前世今生
      • 可视化页面搭建工具
      • 实战篇 01:开发前准备
      • 实战篇 02:项目脚手架
      • 实战篇 03:页面布局方案
      • 实战篇 04:权限管理机制
      • 实战篇 05:菜单匹配逻辑
      • 实战篇 06:消息通知设计
      • 实战篇 07:多语言支持
      • 继往开来:可视化页面搭建工具
    • React Hooks与Immutable实战

    • React SSR服务端渲染与同构实践

    • IM聊天系统前端开发实践

    • 微前端开发实战

    • React进阶实践

  • Vue专栏

  • 移动端专栏

  • Node专栏

  • 前端工程化专栏

  • 算法专栏

  • Typescript专栏

  • 其他专栏

完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

下面,我们讲一下如何将工程化能力应用在构建阶段,主要介绍几种常见的构建工具以及 polyfill、Babel。最后针对目前最流行的构建工具 webpack 的配置优化。

# 为什么需要构建

既然要了解在构建过程中的工程化手段,那么首先我们要知道什么是构建,为什么在前端项目中需要构建。

在编程领域,我们普遍认为编译是将源代码经过一系列处理转换为机器语言(汇编)的过程。构建指的是将我们在开发环境写的代码,转换成可交付的生产环境的代码的过程,其中包括了编译。

记得大学时候《网页开发》这门课的时候,老师给我们讲,网页开发的一大优势就是开发便捷,HTML\JavaScript\CSS 不需要编译就可以直接在浏览器中运行,我们甚至可以使用记事本来进行前端开发,所以,最原始的前端是不需要编译过程的。

在 JQuery 之前的时代,浏览器厂商还没有多,不需要处理各种各样的兼容性问题。前端所做的工作只是写一些简单的 HTML\JS\CSS 代码,也不需要编译,可以直接打开 .html文件在浏览器中运行。

到了 JQuery 时代,虽然市面上已经有各种各样的浏览器,但是 JQuery 已经帮我们解决了绝大多数的兼容性问题,我们只需要引入 JQuery 的源码就可以忽略浏览器兼容性带来的问题,也可以直接将开发的代码在浏览器环境下运行。

那么为什么现代前端开发,我们就需要构建过程呢?

首先是在现代前端开发中,我们需要使用最新的 ES6\7\8 语法、我们需要使用 TS 来进行类型管理,我们需要使用 Less/Sass 辅助我们开发 CSS。这些新技术在提升开发效率的时候,会有一个共同的问题:无法直接在浏览器中解析(或者部分浏览器不支持)。所以,我们就需要在开发的时候加入编译的环节,将我们开发的代码编译为浏览器可识别、可运行的代码。

其次是在模块化发展起来之后,我们将模块\组件的粒度拆分的更细,方便开发的同时也引入了新的问题,每一个文件都会被引入到 HTML 文件中,用户在使用浏览器访问页面的时候就会增加请求数量。想象一下,一个中型项目的开发,拆分出来的组件少则几十个,多则上百个。如果不进行文件合并,那么在性能上,会严重增加用户的等待时长。 所以我们为了减少请求次数,还需要将所有小文件“打包”为一个或多个大文件。

最后在我们项目发布上线的时候,我们需要保证项目整体的可交付性和可维护性。可交付性主要需要进行单元测试来保证代码质量、需要使用 ESLint 等代码规范约束工具对代码进行检查;可维护性主要需要对代码压缩、混淆、合并来减少代码体积和请求数量来保证性能问题。

所以构建就是将我们平时开发的源代码转换为可交付的代码,主要的过程有以下几点:

  • 编译:将源代码转化为浏览器可执行代码,例如 .jsx、.vue文件转换、.sass文件转换为 css 文件。
  • 代码校验:使用例如 ESLint 等工具自动检测代码格式是否符合团队要求。
  • 文件优化:删除未引用代码(tree-shaking)、压缩文件体积、合并文件、制作“雪碧图”、代码混淆等。
  • 自动化测试:自动化执行测试用例,进行单元测试或快照对比。

工程化在构建的过程要做的事情就是将这一系列的流程用代码控制,自动执行这一系列负责且耗时的重复劳动。在发展的过程中,也涌现出了一系列的前端构建工具,比如 Gulp、Grunt、Webpack、Rollup 等,下面我们就分析下几种常见的构建工具及其优缺点。

# npm script

在前面《探索 npm 安装机制》中,我们简单的介绍了 npm 相关的内容。npm 是 nodeJS 内置的包管理工具,而 npm script 是 npm 内置的自定义脚本执行命令。其允许你在 package.json 中使用 script 字段定义脚本。比如,我们想在开发时运行 dev.js 文件,我们就可以这样设置:

{
  "scripts": {
    "dev: "node dev.js",
  },
}
@前端进阶之旅: 代码已经复制到剪贴板

然后在终端中运行 npm run dev,就会对应执行 dev.js 中的内容。

在 package.json 的 script 对象中,每个属性对应一个 shell 脚本,每当执行 npm run xxx的时候,都会新创建一个新的 Shell 执行对应的命令。

npm scripts 的优点是方便快捷,只要是 Shell 可以执行的命令,都可以写在 npm scripts 中。并且不需要安装其他依赖。但是缺点也很明显,功能单一,无法进行一些复杂的功能。

# Grunt

img

Grunt 和 npm script 类似,都可以认为是 JavaScript 的任务运行器。和 npm scripts 不同的是,Grunt 有丰富的插件体系,可以使用其内置的或者社区中的封装了常见任务的插件。Grunt 还可以管理任务之间的依赖关系,自动化执行任务。

Grunt 需要在配置文件 gruntfile.js 中配置每个任务具体的执行代码和依赖关系。例如,我们创建一个 jshint任务,对 Gruntfiles.js 和 src源码以及测试用例 test 文件夹下所有的 .js 文件进行监听,如果有变动的话就执行 jshint这个任务(task)。需要的插件依赖有:grunt-contrib-jshint、grunt-contrib-watch,在启动 gunt 的时候就默认注册 jshint任务。

我们可以做如下配置:

module.exports = function(grunt) {
  // 插件的配置信息
  grunt.initConfig({
    jshint: {
      files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
      options: {
        globals: {
          jQuery: true
        }
      }
    },
    watch: {
      files: ['<%= jshint.files %>'],
      tasks: ['jshint']
    }
  });
	// 使用到的插件
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');

  // 启动 Grunt 时需要注册哪些任务
  grunt.registerTask('default', ['jshint']);

};
@前端进阶之旅: 代码已经复制到剪贴板

然后在根目录下执行 grunt dev就会启动 grunt 并执行注册的 task。

Grunt 的优点和 npm scripts 一样,方便快捷,并且社区也有丰富的插件资源,Grunt 已经到了发展

fe
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
  • React专栏

    • React组合式开发实战

      • 前端开发的四个时代
      • 企业管理系统的前世今生
      • 可视化页面搭建工具
      • 实战篇 01:开发前准备
      • 实战篇 02:项目脚手架
      • 实战篇 03:页面布局方案
      • 实战篇 04:权限管理机制
      • 实战篇 05:菜单匹配逻辑
      • 实战篇 06:消息通知设计
      • 实战篇 07:多语言支持
      • 继往开来:可视化页面搭建工具
    • React Hooks与Immutable实战

    • React SSR服务端渲染与同构实践

    • IM聊天系统前端开发实践

    • 微前端开发实战

    • React进阶实践

  • Vue专栏

  • 移动端专栏

  • Node专栏

  • 前端工程化专栏

  • 算法专栏

  • Typescript专栏

  • 其他专栏