一、webpack 的安装和使用
1. webpack 简介
webpack 是基于模块化的打包 (构建)工具,它把一切视为模块(包括 JS、CSS、图片等资源文件)。
- 工作原理:
-
- 以开发时态的入口模块为起点
- 递归分析所有依赖关系
- 经过压缩、合并等处理
- 最终生成运行时态的文件
- 如上图 webpack 官方首页图片;左边的代码不运行,只运行右边的代码。左边的代码和右边的功能是一样的,只不过浏览器喜欢右边的代码。
2. webpack 的特点:
-
- 工程化解决方案: webpack诞生于2012年,专注于解决前端工程化问题 ,尤其是浏览器端工程化遇到的问题(node 端也用 webpack 只不过用的少),让开发者专注业务代码,把工程化过程中的问题(比如开发兼容性、执行效率等)交给 webpack 来处理。
- 零配置使用:支持开箱即用,无需额外配置
- 生态扩展性: 虽然核心功能有限,但通过扩展机制支持丰富的第三方插件,形成活跃的生态系统(目前生态活跃度远超其他构建工具)。
- node.js :从入口文件开始要读取文件,读出来之后才能分析里边用了 require/import 语句分析依赖关系,如果是在浏览器环境是读取不了文件的。是图片中间的过程需要 node 环境。
- 基于模块化:webpack 在构建过程中要分析依赖关系,方式是通过模块化导入语句进行分析,它支持各模块化标准,包括但不限于 CommonJS、ES6 Module。
3. webpack 的安装
1) webpack 通过 npm 安装
- webpack:核心包,webpack 核心包包含构建过程中所需的所有 API ,用于处理模块依赖分析和打包过程。
- webpack-cli:提供命令行接口,通过调用 webpack 核心包的 api,来完成构建工程,开发者无需编写构建代码。
- 安装方式:必须用过 npm 安装,因为 webpack 运行在 Node.js 环境中。
2) 安装方式
- 全局安装与本地安装
-
- 全局安装特点:
-
-
- 优点:可在任意目录使用 webpack 命令
- 缺点:所有项目强制使用相同版本,无法满足不同项目的版本需求
-
-
- 本地安装优势:
-
-
- 每个项目独立管理 webpack 版本
- 配合 npx 工具使用,无需全局安装
- 推荐使用本地安装方式
-
- 本地安装步骤
-
-
- 初始化项目:
-
-
-
- 执行 npm init 创建 package.json 文件
- 注意项目名称需要符号 URL 规范(不含中文和特殊字符)
-
-
- 安装命令:
npm i -D webpack webpack-cli
为什么要加 -D 安装开发依赖呢,是因为运行代码时不需要 webpack ,从 webpack 首页图也能看出,webpack 是开发到运行的中间过程。
-
- 验证安装:
-
-
- 检查node_modules/.bin目录下的可执行文件
- 查看package.json中的devDependencies字段
-
说一下安装开发依赖时如何选择开发依赖,生产环境只需运行构建后的代码,不再需要 webpack,构建过程属于开发阶段的工作。我们想要区分就看运行时是否需要该依赖即可。
依赖类型有开发依赖和生产依赖,开发依赖仅在开发阶段需要的工具(如 webpack、测试工具等),而生产依赖是项目运行时必须的包(如 React、Vue 等)
3)使用
- webpack 的入口文件
webpack 要在开发时态分析依赖,那么就一定需要一个入口文件来分析,默认情况下,webpack 会以 ./src/index.js 作为入口文件分析依赖关系,打包到 ./dist/main.js 文件中(无论开发时有多少个模块文件,最终都会合并成一个 main.js),必须要有 src/index.js 文件才能正常进行打包。
src 表示源代码目录(source),是开发阶段代码存放位置
dist 表示目标吗目录(destination),是运行时态代码存放位置
从这张图片可以看出,在开发时怎么简便怎么来,不管是用 es 还是 common ,最终都会打包运行时转换为普通的 js 函数,不会出现 commonjs 和 es6 模块化。我们以后开发就可以集中精力开发 src ,dist 目录不用管就行,我们只需把 src 写好了运行一下 npx webpack 命令。
在之前写的前端工程化包管理器文章中提到的脚本,在package.json文件中有一个scripts对象,用于定义可运行的脚本命令,这里我们可以定义一个脚本命令用于打包。
在 package.json 中配置 build 脚本执行 webpack ,通过 npm run build 命令触发打包,开发时专注 src 目录代码,构建时运行打包命令生成 dist。
注意:为什么在脚本的值写 webpack 而不是 npx webpack,是因为配置在 package.son 中的命令,它会自动查找 node_modules 中 .bin 中的 wepack 执行命令。
4. 构建结果的运行环境
webpack 运行警告信息解释
-
- 警告原因:webpack 打包时缺少 mode 参数配置,默认会使用 production 模式
- 环境区分:
-
- 开发环境(development):代码未完成,用于测试调试阶段
- 生产环境(production):代码已完成,将部署到服务器运行
- 模式影响:
-
- 开发环境:保留代码格式和注释,便于调试
- 生产环境:进行代码压缩等优化,减小体积
- 配置方法:
-
- 命令行方式:npx webpack --mode=development 或 --mode==production
- npm 脚本配置:
- 重要概念:
-
- 开发阶段:
-
-
-
- 这是开发阶段而不是开发环境,开发阶段是编写和修改代码的过程
-
-
-
- 运行环境:
-
-
-
- 打包后代码实际执行的环境
-
-
-
- 环境差异:生产环境会进行更多优化,开发环境保留调试信息
二、模块化兼容性
由于 webpack 同时支持 CommonJS 和 ES6 module 模块化标准,也就是说我们无论是用 Common 还是 ES6 写的代码它都能识别它们的依赖,并且进行打包。在这里产生了一个问题,如果说一个模块,是用 ES6 导出,但用 CommonJS 导入,webpack 会怎么来处理呢?它导入的是什么?导出的又是什么?这个时候我们就需要理解在不同的模块化标准里边,它们互相操作的时候 webpack 是如何处理的。
1. 同模块化标准
当导出和导入使用同一种模块化标准时,webpack 的处理效果与原生模块化完全一致。
2. 不同模块化标准
- ES6 导出 + CommonJS 导入:
将 ES6 的基本导出和默认导出合并为一个对象,通过 require 直接获取该对象
- CommonJS 导出 + ES6 导入:
将 module.exports 内容作为默认导出
3. 模块化兼容性
选择一个模块化标准,避免混合使用不同模块化标准
项目开发中统一使用 ES6 或 CommomJS 中的一种
- 第三方库导入时:
-
- 大部分库使用 CommonJS 导出,可用 ES6 默认导入方式
- 遇到 ES6 导出的库时,注意默认导出在 default 属性中