搞懂 webpack ! 淦

背景

最近在面试,面试官们问一个东西都是 XXX 是啥,XXX 有啥用, XXX 原理是啥,XXX 有哪些优缺点, XXX 为啥要这样 😓

哈哈。所以学一个东西,连它的前世今生都得知道,知其然,知其所以然,我正好要去了解一下 webpack, 快上车!!!

Webpack 是啥

它是一个打包工具 😊

原始社会

先让我们回忆一下,没有它之前的前端资源是怎么编译上传的。
以前,他们都写 css+html+js, 最多就压缩一下代码了,把资源传上去浏览器就可以执行了。不知道你们写过这么老的页面不

// index.html 
<html>
	<head>
		<link rel="stylesheet" href="styles.css">
	</head>
	<body>
			/ ** 完整的 hmlt 标签 **/
	</body>
	// 手动引入所有依赖
	<script src="a.js"></script>
	<script src="b.js"></script>
	<script src="c.js"></script>
</html>
模块化

随着 js 框架的出现 以及 js 的模块化兴起(js 依赖 js 资源),我们看看 2010 年还没有 webpack 时,是怎么构建前端资源的呢

eg

// index.html  哦!只有一个 bundle.js 了,看来是对 js 文件有所处理了。
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My Project</title>
</head>
<body>
  <h1>Check the console for output</h1>
  <script src="dist/bundle.js"></script>
</body>
</html>

// html 需要用到的 js 资源有:
- js/
  - module1.js
  - module2.js


// 这里 js 的模块打包工具,像是 gulp . grunt 。 都是给一个 js 入口文件,然后对其模块依赖进行打包。 可以看这里的配置,都是需要自己去手动配置的。
module.exports = function(grunt) {
  grunt.initConfig({
    concat: {
      dist: {
        src: ['src/module1.js', 'src/module2.js', 'src/app.js'],
        dest: 'dist/app.js'
      }
    },
    uglify: {
      dist: {
        files: {
          'dist/bundle.js': ['dist/app.js']
        }
      }
    }
  });

与此同时,对项目的css 资源、js 的模块依赖资源,都是手动配置去针对文件进行对应处理,需要手动去编写大量配置。

webpack 来了!

2014年 webpack 1.0 版本发布了。它通过简单的入口配置,自动分析依赖模块资源,对资源进行转化、压缩处理,输出构建后的资源在浏览器上使用。

配置示例

module.exports = {
  entry: './src/index.js', // 入口文件
  output: {
    filename: 'bundle.js', // 输出文件名
    path: path.resolve(__dirname, 'dist') // 输出目录
  },
  module: {
    rules: [
      {
        test: /\.js$/, // 匹配 .js 结尾的文件
      },
      {
        test: /\.css$/, // 匹配 .css 结尾的文件
      }
    ]
  }
};

不同与 gulp / grunt 需要手动编排不同文件的处理步骤和优化手段。webpack 只需要你提供入口文件,分析所有依赖的模块,并内部实现了基础的优化能力。并且内置能力在不断优化中。从 2014年到现在,已经是 webpack 5.0 ,相信大家也经常看到 webpack 的许多优点:

文件处理多样性
jsx / image / js / ts / css / json / svg …

资源大小
模块化: 文件的模块化处理, chunk 的重复利用
按需加载: 模块的依赖关系分析,页面按需引入所需要资源

优化能力
内置的优化能力: 压缩、treeShaking
配合生态插件:浏览器的兼容性处理

构建速度的优化:
增量构建
多线程构建
cache 缓存使用

自定义能力
通过 loader / plugin 实现自定义的文件处理

现在呢

看起来, webpack 真好是吧。但前端发展是多样化的、迅速的。 webpack 也随着不断的迭代,前端模块的多样性,前端框架的快速发展,支持不同的框架(react/ vue)、js 语法、 ts 等,更好的优化性能,webpack 也逐渐变得庞大,配置也变得更多。

现在都有哪些构建工具呢?

Parcel

一个快速、零配置的打包工具。

<html>
  <body>
    <script src="./index.js"></script>
  </body>
</html>

parcel index.html

它支持一些资源类型的打包构建,所以不用手动额外配置。甩手掌柜真不错呀。 但也因为不能自定义配置和目前支持类型不算丰富,所以还是不能和webpack 相比的

rspack

Rspack 是一个2023年新兴的前端构建工具,由字节跳动开发和维护。其核心是通过基于 rust 编写的 swc 编译器,实现的类似 webpack 工具。

因为基于 rust(擅长并发性和内存管理) 语言处理 js 的语法转换、代码编译,所以在运行运行速度上可以提高10倍以上。

但是因为 swc 所支持的语法还不完善 ,加上 rspack 还有很多要补齐的能力,所以目前并不算稳定。

esbuild

esbuild 是一个快速的 JavaScriptTypeScript 打包器,它由 Go 语言编写而成。其编译速度可以超过 Webpack 和 Rollup 等传统工具 10-100 倍。这主要得益于 Go 语言的高性能特性。

const esbuild = require('esbuild');

esbuild.build({
  entryPoints: ['src/index.js'],
  outfile: 'dist/index.js',
  bundle: true,
  minify: true,
  sourcemap: true,
  format: 'esm', // 或者 'cjs' 用于 CommonJS 格式
}).catch(() => process.exit(1));

虽然 esbuild 也可以配合其他插件,对 css 、md 等其他文件进行处理,但都是手动编写配置去执行,并且生态系统也不算完整。

所以,我们可以用 esbuild 去构建 js、ts 工具包,对于业务项目可能就不那么合适啦

总结

好了,现在我们回过头来看上面那些问题,你会回答了吗?
快总结以下给我评论,我将按你的答案去面试!希望本文对你有用~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值