Skip to content

webpack 的核心概念

查看详情
  • entry:入口,webpack 构建第一步从 entry 开始
  • module:模块,在 webpack 中一个模块通常对应着一个文件,webpack 会从 entry 开始,递归找出所有依赖的模块
  • chunk:代码块,一个 chunk 由多个模块组合而成,用于代码的合并分割
  • loader:模块转换器,用于将模块的原内容按照需求转换为新的内容
  • plugin:扩展插件,在 webpack 构建流程中的特定时机会广播对应的事件,插件可以监听这些事件的发生,在特定的时机做对应的事情

webpack 工作的流程

查看详情
  • 初始化参数:从配置文件(默认 webpack.config.js)和 shell 语句中读取与合并参数,得出最终的参数
  • 开始编译:用上一步得到的参数初始化 compiler(编译器)对象,加载所有配置的 loader 和插件,通过执行对象的 run 方法开始执行编译
  • 确定入口:根据配置中的 entry 找到所有的入口文件
  • 编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,在递归本步骤直到所有入口依赖的文件都经过处理
  • 完成编译模块:经过编译模块之后,得到每个模块被翻译之后的最终内容以及他们之间的依赖关系
  • 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 chunk,在将每个 chunk 转换为一个单独的文件加入输出列表中,这可能是修改输出内容的最后机会
  • 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,将文件的内容写入文件系统中

注:在以上过程中,webpack 会在特定的时间点广播特定的事件,插件监听事件并执行相应的逻辑,并且插件可以调用 webpack 提供的 api 改变 webpack 的运行结果

webpack 的原理

查看详情

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器,当 webpack 处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将这些模块打包成为一个或者多个 bundle,供 HTML 使用。实质上,webpack 仅仅提供了打包的功能和一套文件处理机制,然后通过生态中的各种 Loader 和 Plugin 对代码进行处理。因此 webpack 具有高度的可扩展性。

如何提高 webpack 构建速度

查看详情

可视化构建分析的插件:webpack-bundle-analyzer、webpack-dashboard、webpack-jarvis

  • webpack 配置的优化:
    • 优化 loader 配置:loader 处理文件很耗时,所以可以将处理后的文件缓存,使用 cacheDirectory 开启转换结果缓存
    • 优化 resolve.modules 配置:resolve.modules 用于配置 webpack 去哪些目录下寻找第三方的模块,它会先从当前的目录下寻找 node_modules 找不到再去上一层目录寻找。。。当所安装的第三方模块都放在项目目录时可以直接指定存放的目录 path.resolve(__dirname, 'node_modules')
    • 优化 resolve.extensions 配置:resolve.extensions 的作用是给在导入文件的时候给没带后缀的文件加上后缀,所以可以将出现频率高的放在前面,尽量保持列表的短小
  • happypack 并行构建优化:将 webpack 中最耗时的 loader 文件转换操作任务,分解到多个进程中并行处理,从而减少构建时间
  • 代码压缩用 webpack-parallel-uglify-plugin 代替 uglify-js-plugin:uglify-js-plugin 是单线程执行的,而 webpack-parallel-uglify-plugin 可以并行执行
  • 使用 webpack 内置的 DllPlugin 优化:在使用 webpack 进行打包的时候,对于依赖的第三方库,如 react,react-dom 等不会经常修改的依赖,可以将它们和业务代码分开来打包。只要不升级依赖库的版本,之后 webpack 就只需要打包项目业务代码。

如何解决 webpack 打包体积过大的问题?

查看详情
  • 代码压缩
  • 提取第三方库
  • 去除不必要的插件
  • 提取通用模块文件
  • 路由懒加载

webpack 中的 loader

查看详情

webpack 只能够理解 JavaScript 和 JSON 文件,而 loader 让 webpack 能够去处理其他类型的文件(如:HTML,css,图片等等),并将它们转化为有效的模块(功能离散的 chunk),以供应用程序使用,以及被添加到依赖图中。

webpack 中的 plugin

查看详情
  • 插件是 webpack 的支柱功能,目的是解决 loader 无法实现的其他事情。在编译的整个生命周期中,webpack 会触发许多事件钩子,plugin 可以监听这些事件,根据需求在对应的时间对打包内容进行定向修改。
  • 插件实际就是一个具有 apply 方法的 JavaScript 类,apply 方法会被 webpack 编译器调用,并且 compiler 对象可在整个编译生命周期访问。

webpack HMR 的原理是什么?

查看详情

Webpack Dev Server启动一个WebSocket服务器,当webpack监听到源码发生变化时,会重新编译受影响的模块并通过WebSocket向浏览器推送更新信息。当浏览器接收到通知后会通过HTTP请求重新从Webpack Dev Server拉取最新的模块代码。

webpack 打包后的文件看过吗?

查看详情
  • webpack 定义了 webpack_require 函数,用于加载模块并处理依赖关系。
  • 被加载的模块会被缓存起来
  • Webpack 使用立即调用的函数(IIFE)来封装模块管理逻辑。模块被存储在一个对象中,键为模块的 ID,值为模块的导出内容。