带你入门前端工程(五):构建工具

构建工具就是指能自动对代码执行检验、转换、压缩等功能的工具。从目前市场上流行的构建工具来看,常见的功能有:

  1. 代码转换,例如将 ts 文件转换为 js 文件。
  2. 代码打包,将有关联的代码打包在一起。
  3. 代码压缩、文件压缩、gzip 压缩等。
  4. 热加载,修改代码后自动刷新页面。
  5. 代码检验,检查代码格式是否符合规范。

在开发中使用构建工具,能够大大的提升了开发效率。

由于前端构建工具比较多,所以本章选取了其中的三个 webpackrollupvite 来进行讲解。

webpack

webpack 是目前最火的构建工具,它具有非常多的实用功能:

  1. 热加载:开发环境下修改代码,页面实时刷新。
  2. 按需加载:每次打开页面时,只加载当前页面所需要的资源。在切换到其他页面时,再加载对应的资源。
  3. 代码打包:打包、压缩、分割代码等等。
  4. tree-shaking:打包过程中自动剔除没有使用的代码。
  5. 可以通过 loader 和 plugin 处理各种各样的资源依赖。

下面让我们简单的了解一下 webpack 的 loaderplugin 和自定义模块加载系统。

loader

什么是 loader?它是一个转换器,用于对源代码进行转换。例如使用 babel-loader 可以将 ES6 代码转换为 ES5 代码;sass-loader 将 sass 代码转换为 css 代码。

其实 loader 并不复杂,很容易就能写一个 loader。下面就是一个简单的 loader,它的作用是将代码中的 var 关键词替换为 const

module.exports = function (source) {
    return source.replace(/var/g, 'const') // var a = 1; 将被转换为 const a = 1;
}

plugin

webpack 在整个编译周期中会触发很多不同的事件,plugin 可以监听这些事件,并且可以调用 webpack 的 API 对输出资源进行处理。

这是它和 loader 的不同之处,loader 一般只能对源文件代码进行转换,而 plugin 可以做得更多。plugin 在整个编译周期中都可以被调用,只要监听事件。

例如 html-webpack-plugin 插件在编译完成后自动的将资源 URL 插入到 html 文件。

自定义模块系统

在 webpack 里,每一个文件都是一个模块。

无论你开发使用的是 CommonJS 规范还是 ES6 模块规范,打包后的文件都统一使用 webpack 自定义的模块规范来管理、加载模块。

如何学习 webpack

在 webpack 中我认为比较值得学习的是以下 4 项:

  1. 写一个 loader 和 plugin,了解 webpack 是如何通过 loader 和 plugin 处理文件的(《实现一个 webpack loader 和 webpack plugin》)。
  2. 学习 webpack 的模块加载原理,知道它是怎么加载文件的,知道按需加载的原理是什么(《深入了解 webpack 模块加载原理》)。
  3. 学习如何用 webpack 做性能优化(《三十分钟掌握Webpack性能优化》)。
  4. 学习 webpack 的热加载原理(《搞懂webpack热更新原理》)。

以上 4 项学会了,基本上 webpack 就掌握得差不多了。不管是在工作中,还是面试中,遇到 webpack 的问题都能轻松解决。

rollup

相比于 webpack,它没有热加载,也没有按需加载等非常实用的功能。但 rollup 依然能得到广大开发者的喜爱,依靠的就是它的打包功能。

rollup 打包功能为什么这么优秀?主要有以下两个原因:

  1. 对于使用原生 ESM 模块编写的代码,rollup 会静态分析代码中的 import,并将排除任何未实际使用的代码。
  2. 支持程序流分析,能更加正确的判断项目本身的代码是否有副作用(配合 tree-shaking)。

从 webpack 提供的 tree-shaking 官方 DEMO,也能看出 webpack 的 tree-shaking 并不完美:

// math.js
export function square(x) {
  return x * x;
}

export function cube(x) {
  return x * x * x;
}

// main.js
import { cube } from './math.js';

function component() {
    const element = document.createElement('pre');

    element.innerHTML = [
        'Hello webpack!',
        '5 cubed is equal to ' + cube(5)
    ].join('\n\n');

    return element;
}

document.body.appendChild(component());

打包后的代码:

/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
  'use strict';
  /* unused harmony export square */
  /* harmony export (immutable) */ __webpack_exports__['a'] = cube;
  function square(x) {
    return x * x;
  }

  function cube(x) {
    return x * x * x;
  }
});

可以看到没有使用的 square() 函数也打包进来了。对于这一点,webpack 的解释如下:

rollup 就不会有这种问题,它基于原生 ESM 模块,在编译时就能分析出哪些是没有使用的代码(webpack 还要额外配置)。所以 rollup 打包出来的代码非常干净。

另外 webpack 打包还需要注入自己的模块加载系统,所以还会有一部分“多余”的代码,不够干净。

如何学习 rollup

我建议学习一下 rollup 是如何打包的,也就是它是怎么做到 tree-shaking 的。这一点建议看一下我的文章《从 rollup 初版源码学习打包原理》

vite

vite 是一个最近兴起的构建工具,它的作者是 vue 之父尤雨溪。vite 对标的构建工具是 webpack,基本上 webpack 有的功能它都有。vite 和 webpack 的不同点主要有以下两点:

  1. 开发环境下,使用原生 ESM 模块进行开发。同时拦截资源请求,根据请求找到对应的文件,作少许改动后返回代码。因此无需进行打包,直接按需编译,启动非常快。相比之下,webpack 的热加载在每次更改代码时都需要重新打包所有代码才能刷新页面,特别是代码很多时,打包非常缓慢。
  2. 生产环境下使用 rollup 打包。

如何学习 vite

建议了解一下 vite 的按需编译是怎么做的。

小结

从构建工具的发展历史来看,使用原生 ESM 模块是大势所趋,未来所有的构建工具都会基于 ESM 设计。如果你还不熟悉 ESM 模块,建议看一下阮一峰老师的《Module 的语法》,或者看一下《JavaScript高级程序设计(第4版)》的《模块》一章。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值