npm和webpack到底解决了什么问题

1,045 阅读3分钟

浏览器模块化的局限

前面一篇文章详细介绍了 ESModule 的使用和特点,现在各大主流浏览器都支持了 ESModule,因此可以直接在script标签中引入ESModule模块化的文件,只需要加上type = module即可。

<script type="module" src=""></script>

但是直接在浏览器中使用 ESModule 有很多局限。

必须引入所有文件

不能只引入入口文件,还需要把入口文件引入的依赖都要引入。入口文件 entry.js 引入了两个依赖文件,当在index.html 引入entry.js 的时候,也需要把依赖文件 api.js 和 sum.js 也引入。

// entry.js
import m from './api.js'
import sum from './sum.js'

index.html

<script type="module" src="./sum.js"></script>
<script type="module" src="./api.js"></script>
<script type="module" src="./entry.js"></script>

ESModule 不像 Commonjs 那样只需要引入入口文件即可。当模块文件变多的时候,而且模块是分散在各个目录当中,我们就非常不好管理。另外,在大型项目中,每次都要加载这么多文件,导致性能非常差,所以这种开发模式无法满足需求。

必须完整引入文件地址

// 错误
import handle from './handle'
// 正确 后缀不能省略
import handle from './handle.js'

针对上面的问题,于是就出现了npm和webpack。

npm

npm 的全称是Node Package Manager,是一个 NodeJS 包管理和分发工具。

  • npm 是由程序员 Lsaac 发明

image.png

  • 初步思路:
    • 集中管理所有的模块,所有的模块都上传到仓库(registry)
    • 模块内创建 package.json 标注模块的基本信息
    • 通过 npm publish 发布模块,上传到registry
    • 通过 npm install 安装模块,模块安装到node_modules目录
  • npm 于 2014 年商业化,2020年被 Github 收购

针对模块分散在各个项目中无法管理的问题,我们可以使用 npm 来解决。npm 解决的核心问题是模块管理的问题,npm 原理分析如下图:

5.png

首先通过 npm init 初始化一个项目,在这个项目中的 package.json 写上该项目的信息,比如name, version等,在项目中可以通过npm install 安装其他依赖,做完之后通过 npm publish 发布到仓库registry中,仓库主要分为 public 和 private 两个部分, npm 公司主要通过 private来收费的。公有仓库又分为 normal 和 organization(组织)。

npm 的局限

  • npm 只能解决模块的高效管理和获取问题
  • npm 无法解决性能加载的问题
  • 模块发明以后,制约其广泛使用的因素就是性能问题

webpack

性能加载慢的问题要由于模块太多,导致每次加载的时候发送很多请求。那能不能把模块全部打包到一个 bundle.js 文件中,然后进行加载,这样不是就可以解决性能慢的问题了吗?

因此,webpack 就这样诞生了。

  • webpack 2012年3月10号诞生,作者是Tobias(德国)
  • 移植了 GWT(Google Web Tookit) 的功能(code spliting)
  • 2014年 Instagram 团队分享性能优化时,提到使用 webpack 的 code spliting 特性
  • webpack 的出现模糊了任务和构建的边界,融为一体

最初 webpack 核心解决的问题就是代码的合并和拆分,它的核心理念是将资源都视为模块,统一进行打包和处理,它同时提供了 loader 和 plugins 进行功能的扩展。webpack 之所以能像今天这么火,是因为它提供了 loader 和 plugins 两个能力,让它的功能得到了极大的扩展。可以参考下图,webpack 具体做了什么。

6.png

我们可以看下 webpack 官网的图,就能知道 webpack 能做的事情只有两个,先打包,后分割。首先把不同的资源进行打包成一个文件,然后根据规则再拆分为js css 图片等。

image.png

一句话概括今天的内容就是: 模块化提升了开发效率,但是牺牲了访问性能,所以就出现了npm和webpack。