总结

1、能够掌握 webpack 的基本使用
安装、 webpack.config.js 修改打包入口
2、了解常用的 plugin 的基本使用
webpack-dev-server、 html-webpack-plugin
3、了解常用的 loader 的基本使用
loader 的作用、loader 的调用过程
4、能够说出 Source Map 的作用
精确定位到 错误行并显示对应的源码
方便开发者调试源码中的错误

webpack 基础

隔行变色效果

1、新建项目空白目录, 并运行 npm init -y 命令, 初始化包管理配置文件 package.json
2、新建 src 源代码目录
3、新建 src -> index.html 首页和 src -> index.js 脚本文件
4、初始化首页基本的结构
5、运行 npm install jquery -S 命令, 安装 jQuery
6、通过 ES6 模块化的方式导入 jQuery, 实现列表隔行变色效果

  1. // html 页面
  2. <!-- 注意: index.js 中的代码存在兼容性问题 -->
  3. <!-- <script src="./index.js"></script> -->
  4. <script src="../dist/main.js"></script>
  5. </head>
  6. <body>
  7. <ul>
  8. <li>这是第1li</li>
  9. <li>这是第2li</li>
  10. <li>这是第3li</li>
  11. <li>这是第4li</li>
  12. <li>这是第5li</li>
  13. <li>这是第6li</li>
  14. <li>这是第7li</li>
  15. <li>这是第8li</li>
  16. <li>这是第9li</li>
  17. </ul>
  18. </body>
  19. // js 页面
  20. // 1、使用 ES6 模块化的语法导入 jQuery
  21. import $ from 'jquery'
  22. // 2、实现隔行变色的效果
  23. $(function() {
  24. $('li:odd').css('backgroundColor', 'red')
  25. $('li:even').css('backgroundColor', 'cyan')
  26. })

以上代码隔行变色报错 , 因为用了 高级语法 所以要用到 webpack
1、在终端运行如下的命令, 安装 webpack 相关的两个包:
npm install webpack@5.5.1 webpack-cli@4.2.0 -D
注: 开发阶段用到的东西, 项目上线就不在需要 webpack 所以要放到 -D
2、在项目根目录中, 创建名为 webpack.config.js 的 webpack 配置文件, 并初始化如下的基本配置

  1. module.exports = {
  2. mode: 'development' // mode 用来指定构建模式, 可选值有 development 和 production
  3. }

3、package.json 的 scripts 节点下, 新增 dev 脚本如下:

  1. scripts": {
  2. "test": "echo \"Error: no test specified\" && exit 1" //这个没用删除
  3. "dev": "webpack" // script 节点下的脚本, 可以通过 npm run 执行, 例如 npm run dev
  4. }

4、在终端执行 npm run dev 以后 会在根目录生成一个 dist 文件夹 里面是 兼容好的 文件 所以 在index.html 里面要导入这个 dist > main.js 文件 而不是自己的 index.js 文件

mode 的可选值(开发阶段、发布阶段)

mode 节点的可选值有两个, 分别是:

一、development (开发)

开发环境
不会对打包生成的文件进行代码压缩性能优化
打包速度快, 适合在开发阶段使用

二、production (上线)

生产环境
会对打包生成的文件进行代码压缩性能优化
打包速度很慢, 仅适合在项目发布阶级使用

webpack.config.js 文件的作用

webpack.config.js 是 webpack 的配置文件. webpack 在真正开始打包构建之前, 会 先读取这个配置文件, 从而基于给定配置, 对项目进行打包
注意: 由于 webpack 是基于 node.js 开发出来的 打包工具, 因此在它的配置文件中, 支持使用 node.js 相关的语法和模块进行 webpack 的个性化配置

webpack 中的默认约定

在 webpack 中 有如下的 默认约定
1、默认的打包入口文件为 src -> index.js
2、默认的输出文件路径为 dist -> main.js
注意: 可以在 webpack.config.js 中修改打包的默认约定

自定义打包的入口与出口

在 webpack.config.js 配置文件中, 通过 entry 节点指定打包的入口. 通过 output 节点指定打包的出口

  1. const path = require('path') // 导入 node.js 中专门操作路径的模块
  2. module.exports = {
  3. entry: path.join(__dirname, './src/index.js'), //打包入口文件路径
  4. output: {
  5. path: path.join(__dirname, './dist'), // 输出文件的存放路径
  6. filename: 'js/bundle.js', // 表示输出文件的名称
  7. }
  8. }

webpack 中的插件

通过安装和配置第三方的插件, 可以拓展 webpack 的能力, 从而让 webpack 用起来更方便. 最常用的 webpack 插件有如下两个:

一、修改代码,自动打包构建

  1. 安装** webpack-dev-server** ( 生成到了内存中 默认 放到了项目的根目录中, 虚拟的、不可见, 所以index.html 中就把调用的修改成 根目录的路径 ** /main.js** )<br /> 类似于 node.js 阶段用到的 nodemon 工具
  1. // 安装
  2. npm install webpack-dev-server@3.11.0 -D
  3. // 配置 修改 package.json -> scripts 中的 dev 命令如下:
  4. scripts": {
  5. "dev": "webpack serve" // script 节点下的脚本, 可以通过 npm run 执行
  6. }

二、自定制 index.html 内容 (复制)

html-webpack-plugin
webpack 中的 HTML插件 ( 类似于一个模版引擎插件 )
可以通过此插件自定制 index.html 页面的内容 ( 通过 8080端口打开 显示的是 全部文件夹 需要点击进去 src 文件里面 才能显示首页, 而这个插件是复制 src 文件夹里面的 index.html 在根目录, 直接显示 )
注意点:
(1) 复制到根目录的 index.html 是生成到了内存中, 虚拟的,看不到的
(2) 在 index.html 中最下面自动引入了一个 main.js
(3) 如果开启了实时打包功能 dist 目录就可以删除掉了

  1. // 安装
  2. npm install html-webpack-plugin@4.5.0 -D
  3. // 以下在 webpack.config.js文件配置
  4. // 1、导入 HTML 插件, 得到一个构造函数
  5. const HtmlPlugin = require('html-webpack-plugin')
  6. // 2、创建 HTML 插件实例对象
  7. const htmlPlugin = new HtmlPlugin ({
  8. template: './src/index.html', // 指定原文件的存放路径
  9. filename: './index.html', // 指定生成的文件的存放路径
  10. })
  11. module.exports = {
  12. mode: 'development',
  13. plugins: [htmlPlugin], // 3、通过 plugins 节点, 使 htmlPlugin 插件生效
  14. }

三、修改打包所使用的地址、端口及自动打开浏览器

  1. devServer:{
  2. open: true, // 初次打包完成后, 自动打开浏览器
  3. host: '127.0.0.1', // 实时打包所需要的主机地址
  4. port: '8080', // 实时打包所使用的端口号
  5. }

loader 加载器

webpack 默认只能打包处理以 .js 后缀结尾的模块. 如果要处理 非 .js 后缀 需要调用 loader 加载器
loader 加载器作用: 协助 webpack 打包处理特定的文件模块 比如:
● css-loader 可以打包处理 .css 相关文件
● less-loader 可以打包处理 .less 相关文件
● babel-loader 可以打包处理 webpack 无法处理的高级 JS 语法

css-loader 可以打包处理 .css 相关文件

1、在 src 目录下新建 index.css
2、把 src 下的 index.css 导入到 src 下的 index.js 文件里

  1. import './index.css' // 直接保存会报错 需要执行第 3 步

3、打包处理 css 文件
(1) 运行 npm i style-loader@2.0.0 css-loader@5.0.1 -D 命令, 安装处理 css 文件的 loader
(2) 在 webpack.config.js 的 module -> rules 数组中, 添加 loader 规则如下:

  1. module: { // 所以第三方文件模块的匹配规则
  2. rules: [ // 文件后缀名的匹配规则
  3. { test: /\.css$/, use: ['style-loader', 'css-loader']}
  4. ]
  5. }
  6. // 注: 上面的代码要和 mode、plugins、devServer 这几个类目平级

其中, test 表示匹配的 文件类型 $是表示结尾, use 表示对应 要调用的 loader

less-loader 可以打包处理 .less 相关文件

第一步第二步和上面的 .css 一样
3、打包处理 less 文件
(1) 运行 npm i less-loader@7.1.0 less@3.12.2 -D 命令, 安装处理 less 文件的 loader
(2) 在 webpack.config.js 的 module -> rules 数组中, 添加 loader 规则如下:

  1. module: { // 所以第三方文件模块的匹配规则
  2. rules: [ // 文件后缀名的匹配规则
  3. { test: /\.css$/, use: ['style-loader', 'css-loader']}, // 上面 css 的
  4. { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader']}
  5. ]
  6. }

打包处理样式表中与 URL 路径相关的文件

1、打包处理 url 文件
(1) 运行 npm i url-loader@4.1.1 file-loader@6.2.0 -D 命令
(2) 在 webpack.config.js 的 module -> rules 数组中, 添加 loader 规则如下:

  1. module: { // 所以第三方文件模块的匹配规则
  2. rules: [ // 文件后缀名的匹配规则
  3. { test: /\.css$/, use: ['style-loader', 'css-loader']}, // 上面 css 的
  4. { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader']},
  5. { test: /\.jpg|png|gif$/, use: 'url-loader?limit=22229'}
  6. // 第二种 url
  7. {
  8. test: /\.jpg|png|gif$/, // 匹配图片文件
  9. use:{
  10. loader: 'url-loader', // 通过 loader 属性指定要调用的 loader
  11. options: { // 通过 options 属性指定参数项
  12. limit: 22229
  13. }
  14. }
  15. }
  16. // 结束
  17. ]
  18. }

其中 ? 之后的是 loader 的参数项
● limit 用来指定图片的大小, 单位是字节(byte)
● 只有 ≤ limit 大小的图片, 才会被专为 base64 格式的图片

打包处理 js 文件中的高级语法

webpack 只能打包处理一部分高级的 javaScript 语法. 对于那些 webpack 无法处理的高级 js 语法 需要借助 babel-loader 进行打包处理. 例如 webpack 无法处理下面的 javaScript 代码:

  1. class Person {
  2. // 通过 static 关键字, 为 Person 类定义了一个静态属性 info
  3. // webpack 无法打包处理“ 静态属性 ” 这个高级语法
  4. static info = 'person info'
  5. }
  6. console.log(Person.info)

安装 babel-loader 相关的包
(1) 运行如下命令
npm i babel-loader@8.2.1 @babel/core@7.12.3 @babel/plugin-proposal-class-properties@7.12.1 -D
(2) 在 webpack.config.js 的 module -> rules 数组中, 添加 loader 规则如下:

  1. {
  2. test:/\.js$/,
  3. // exclude 为排除项
  4. // 表示 babel-loader 只需处理开发者编写的 js 文件, 不需要处理 node_modules 下的 js 文件
  5. exclude: /node_modules/,
  6. use: {
  7. loader: 'babel-loader',
  8. options: {
  9. // 声明一个 babel 插件, 此插件用来转化 class 中的高级语法
  10. plugins:['@babel/plugin-proposal-class-properties']
  11. }
  12. }
  13. }

打包发布

1、为什么要打包发布

项目开发完成之后, 使用 webpack 对项目进行打包发布的主要原因有以下2点
(1) 开发环境下, 打包生成的文件存放于内存中, 无法获取到最终打包生成的文件
(2) 开发环境下, 打包生成的文件不会进行代码压缩和性能优化

2、配置 webpack 的打包发布

在 package.json 文件的 scripts 节点下, 新增 build 命令如下

  1. "scripts": {
  2. "dev": "webpack serve", // 开发环境中, 运行 dev 命令
  3. "build": "webpack --mode production" // 项目发布时, 运行 build 命令
  4. }

—model 是一个参数项, 用来指定 webpack 的运行模式. production 代表生产环境, 会对打包生成的文件进行代码压缩和性能优化.
注意: 通过 —model 指定的参数项, 会覆盖 webpack.config.js 中的 model 选项

3、打包发布 把 js 文件 统一生成到 dist 目录下的 js 中

  1. output: {
  2. path: path.join(_dirname, 'dist'),
  3. // 明确告诉 webpack 把生成的 bundle.js 文件存放到 dist 目录下的 js 子目录
  4. filename: 'js/bundle.js'
  5. }

4、打包发布 把 图片 统一生成到 dist 目录下的 image 中

  1. {
  2. test:/\.jpg|png|gif$/,
  3. use: {
  4. loader: 'url-loader',
  5. options: {
  6. limit: 22228,
  7. //明确指定把打包生成的图片文件, 存放到 dist 目录下的 image 文件夹
  8. outputPath: 'image'
  9. }
  10. }
  11. }

5、自动清理 dist 目录下的旧文件

需要安装并配置 clean-webpack-plugin 插件:

  1. // 1、安装清理 dist 目录的 webpack
  2. npm install clean-webpack-plugin@3.0.0 -D
  3. // 2、按需导入插件, 得到插件的构造函数之后, 创建插件的实例对象
  4. const { CleanWebpackPlugin } = require('clean-webpack-plugin')
  5. const cleanPlugin = new CleanWebpackPlugin()
  6. // 3、把创建的 cleanPlugin 插件实例对象, 挂载到 plugins 节点中
  7. plugins: [htmlPlugin, cleanPlugin], // 挂载插件

6、企业级项目的打包发布 (以后项目中会讲解)

企业级项目在进行打包发布时, 远比刚才的方式要负责的多, 主要的发布流程如下:
● 生成打包报告, 根据报告分析具体的优化方案
● Tree-Shaking
● 为第三方库启用 CDN 加载
● 配置组件的按需加载
● 开启路由懒加载
● 自定制首页内容

SourceMap(报错和源代码保持一致)

webpack打包以后对压缩混淆之后的代码除错 ( debug ) 是一件极其困难的事情
● 变量被替换成没有任何语义的名称
● 空行和注释被剔除

1、解决默认 SourceMap

开发环境下, 推荐在 webpack.config.js 中添加如下配置, 即可保证运行时报错的行数与源代码的行数保持一致

  1. module.exports = {
  2. mode: 'development',
  3. // eval-source-map 仅限在“开发模式” 下使用, 不建议在 “ 生产模式 ” 下使用
  4. // 此选项生成的 Source Map 能够保证“运行时报错的行数”与“源代码的行数”保持一致
  5. devtool: 'eval-source-map',
  6. // 省略其它配置项...
  7. }

注: 对外暴露, 如果屏蔽了 devtool 则不对外暴露, 自己也找不到

2、Source Map 的最佳实践

(1) 开发环境下:
建议把 devtool 的值设置为 eval-source-map
好处: 可以精准定位到具体的错误行
(2) 生产环境下:
建议关闭 Source Map 或将 devtool 的值设置为 nosources-source-map
好处: 防止源码泄漏, 提高网站的安全性