webpack相关

news2024/10/5 15:27:35

简介

webpack 是一个静态模块打包器。
入口js文件(引入JQ、less等chunk块)-->less转为css/es6转为es5-->打包后输出为bundle。

1.1 五个核心概念

入口(Entry)

输出(Output)

Loader :webpack 去处理那些非 JavaScript 文件 (webpack 自 身 只 理 解 JavaScript)

插件(Plugins):可以用于执行范围更广的任务 

模式(Mode):development/production

1.2 基本使用

npm install webpack webpack-cli -D
开发环境指令 webpack src/js/index.js -o build/js/built.js --mode=development
        功能:webpack 能编译打包 js json 文件,并将 es6 的模块化语法转换成浏览器能识别的语法。
生产环境指令 webpack src/js/index.js -o build/js/built.js --mode=production
        功能:在开发配置功能上多一个功能,压缩代码。

开发环境的基本配置

2.1 配置

打包样式资源:less-loader  css-loader  style-loader

打包html资源: html-webpack-plugin

处理图片资源:url-loader  html-loader

处理其他资源:file-loader

devServer:webpack-dev-server

2.2 编码

/*
  开发环境配置:能让代码运行
    运行项目指令:
      webpack 会将打包结果输出出去
      npx webpack-dev-server 只会在内存中编译打包,没有输出
*/

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')// 输出路径:__dirname代表当前文件的目录绝对路径
  },
  module: {
    rules: [
      // loader的配置
      {
        // 处理less资源
        test: /\.less$/,// 匹配哪些文件
        //less-loader:将less文件编译成css文件
        //css-loader:将css文件变成commonjs模块加载js中
        //style-loader:创建style标签,将js中的样式添加到head中生效
        use: ['style-loader', 'css-loader', 'less-loader']// use数组中loader执行顺序:从右到左,从下到上依次执行
      },
      {
        // 处理css资源
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        // 处理图片资源
        test: /\.(jpg|png|gif)$/,
        loader: 'url-loader',//依赖于file-loader
        options: {
          limit: 8 * 1024,// 图片大小小于8kb,就会被base64处理;减少请求数量,图片体积会更大
          name: '[hash:10].[ext]',// [hash:10]取图片的hash的前10位 [ext]取文件原来扩展名
          esModule: false,// 关闭es6模块化:因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs
          outputPath: 'imgs'
        }
      },
      {
        // 处理html中img资源
        test: /\.html$/,
        loader: 'html-loader'//引入图片,从而被url-loader处理
      },
      {
        // 处理其他资源(如图标字体)
        exclude: /\.(html|js|css|less|jpg|png|gif)/,
        loader: 'file-loader',
        options: {
          name: '[hash:10].[ext]',
          outputPath: 'media'
        }
      }
    ]
  },
  plugins: [
    // plugins的配置
    new HtmlWebpackPlugin({//默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS)
      template: './src/index.html'// 复制 './src/index.html' 文件
    })
  ],
  mode: 'development',
  devServer: {// 开发服务器 devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~~)
    contentBase: resolve(__dirname, 'build'),// 项目构建后路径
    compress: true,// 启动gzip压缩
    port: 3000,
    open: true// 自动打开浏览器
  }
};

3 生产环境的基本配置

3.1 配置

提取css为单独文件:min-css-extract-plugin

css兼容性处理:postcss-loader  postcss-preset-env

压缩css:optimize-css-assets-webpack-plugin

js语法检查:eslint-loader  eslint  eslint-config-airbnb-base eslint-plugin-import

js兼容性处理

        babel-loader @babel/core @babel/preset-env(基本语法)core-js(高级语法按需加载)

        @babel/polyfill:promise可以,兼容性代码全部引入,体积太大。入口文件直接引入

压缩html: html-webpack-plugin

3.2 编码

const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

// 定义nodejs环境变量:决定使用browserslist的哪个环境,默认为生产环境
process.env.NODE_ENV = 'production';

// 复用loader
        /*
          "browserslist": {
              // 开发环境 --> 设置node环境变量:process.env.NODE_ENV = development
              "development": [
                "last 1 chrome version",
                "last 1 firefox version",
                "last 1 safari version"
              ],
              // 生产环境:默认是看生产环境
              "production": [
                ">0.2%",
                "not dead",
                "not op_mini all"
              ]
            }
          */
const commonCssLoader = [
  MiniCssExtractPlugin.loader,// 这个loader取代style-loader。作用:提取js中的css成单独文件。最终通过link引入,减小js文件的体积,还可以避免闪屏
  'css-loader',
  {
    // 还需要在package.json中定义browserslist
    loader: 'postcss-loader',
    options: {
      ident: 'postcss',
      plugins: () => [require('postcss-preset-env')()]//帮postcss找到package.json中browserslist里面的配置,通过配置加载指定的css兼容性样式
    }
  }
];

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [...commonCssLoader]
      },
      {
        test: /\.less$/,
        use: [...commonCssLoader, 'less-loader']
      },
      /*
        1.正常来讲,一个文件只能被一个loader处理。当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序:先执行eslint 在执行babel。
        2.在package.json中eslintConfig设置检查规则 --> airbnb--> eslint-config-airbnb-base  eslint-plugin-import eslint
              "eslintConfig": {
                "extends": "airbnb-base"
              }
      */
      {//js语法检查
        test: /\.js$/,
        exclude: /node_modules/,//只检查自己写的源代码
        enforce: 'pre',// 优先执行
        loader: 'eslint-loader',//依赖于eslint
        options: {
          fix: true// 自动修复eslint的错误
        }
      },
      {//js兼容性处理
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',//依赖于@babel/core
        options: {
          presets: [
            [
              '@babel/preset-env',//基本js兼容性处理
              {
                useBuiltIns: 'usage',// 按需加载
                corejs: {version: 3},// 指定core-js版本
                targets: {// 指定兼容性做到哪个版本浏览器
                  chrome: '60',
                  firefox: '50',
                  ie: '9',
                  safari: '10',
                  edge: '17'
                }
              }
            ]
          ],
           cacheDirectory: true// 开启babel缓存。第二次构建时,会读取之前的缓存
        }
      },
      {
        test: /\.(jpg|png|gif)/,
        loader: 'url-loader',
        options: {
          limit: 8 * 1024,
          name: '[hash:10].[ext]',
          outputPath: 'imgs',
          esModule: false
        }
      },
      {
        test: /\.html$/,
        loader: 'html-loader'
      },
      {
        exclude: /\.(js|css|less|html|jpg|png|gif)/,
        loader: 'file-loader',
        options: {
          outputPath: 'media'
        }
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({//提取css为单独文件
      filename: 'css/built.css'
    }),
    new OptimizeCssAssetsWebpackPlugin(),// 压缩css
    new HtmlWebpackPlugin({// 压缩html代码
      template: './src/index.html',
      minify: {
        collapseWhitespace: true,// 移除空格
        removeComments: true// 移除注释
      }
    })
  ],
  mode: 'production'// 压缩js
};

4 性能优化

开发:打包速度HMR、代码调试sourceMap

生产:打包速度oneOf、babel缓存、多进程打包、externals、dll、

           代码性能:文件资源缓存、tree shaking、code split、懒加载、pwa

4.1 开发环境

HMR: hot module replacement 热模块替换 / 模块热替换

问题:npx xxx 启动开发环境配置--->修改代码,整个页面会重新刷新
作用:devServer中开启hot--->一个模块发生变化,只会重新打包这一个模块

/*
  
      样式文件:可以使用HMR功能:因为style-loader内部实现了~
      js文件:默认不能使用HMR功能 --> 修改index.js中的代码,根据hot属性存在,监听模块文件变化更新
              注意:HMR功能只能处理非入口js文件 。
      html文件: 默认不能使用HMR功能,同时会导致问题:html文件不能热更新了~ (不用做HMR功能)
              解决:修改entry入口,将html文件引入
*/

const { resolve } = require('path');

module.exports = {
  entry: ['./src/js/index.js', './src/index.html'],
  output: {},
  module: {},
  plugins: [],
  mode: 'development',
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true,
    port: 3000,
    open: true,
    // 开启HMR功能
    // 当修改了webpack配置,新配置要想生效,必须重新webpack服务
    hot: true
  }
};

index.js

if (module.hot) {
  module.hot.accept('./print.js', function() {
    // 方法会监听 print.js 文件的变化,一旦发生变化,其他模块不会重新打包构建。
    // 会执行后面的回调函数
    print();
  });
}

source-map: 一种提供源代码到构建后代码映射技术,打包后生成js.map文件,快速定位源代码的错误位置。

开发环境:速度快,调试好 eval-source-map(内联)

生产环境:源代码隐藏,调试友好 source-map(外部js.map)

const { resolve } = require('path');

module.exports = {
  entry: ['./src/js/index.js', './src/index.html'],
  output: {
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: []
  },
  plugins: [],
  mode: 'development',
  devServer: {},
  devtool: 'eval-source-map'//source-map
};

4.2 生产环境

module中配置oneOf:同类型的文件只匹配一个loader,将eslint-loader提取出去。

const { resolve } = require('path');

// 复用loader
const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  'css-loader',
  {
    loader: 'postcss-loader',
    options: {
      ident: 'postcss',
      plugins: () => [require('postcss-preset-env')()]
    }
  }
];

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        // 优先执行
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
          fix: true
        }
      },
      {
        // 以下loader只会匹配一个
        // 注意:不能有两个配置处理同一种类型文件
        oneOf: [
          {
            test: /\.css$/,
            use: [...commonCssLoader]
          },
          {
            test: /\.less$/,
            use: [...commonCssLoader, 'less-loader']
          },
          {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
              presets: [
                [
                  '@babel/preset-env',
                  {
                    useBuiltIns: 'usage',
                    corejs: {version: 3},
                    targets: {
                      chrome: '60',
                      firefox: '50'
                    }
                  }
                ]
              ]
            }
          },
        ]
      }
    ]
  },
  plugins: [],
  mode: 'production'
};

babel缓存(第二次构建读取缓存)

文件资源缓存(上线):server.js用express搭建服务器引入built静态资源-->被强制缓存

        hash: 每次wepack构建时会生成一个唯一的hash值。

        问题: 因为js和css同时使用一个hash值。如果重新打包,会导致所有缓存失效 (只改动一个文件)

       chunkhash:根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样

       问题: js和css的hash值还是一样的。因为css是在js中被引入的,所以同属于一个chunk

       contenthash: 根据文件的内容生成hash值。不同文件hash值一定不一样

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.[contenthash:10].js',//js
    path: resolve(__dirname, 'build')
  },
  module: {},
  plugins: [
    new MiniCssExtractPlugin({
      filename: 'css/built.[contenthash:10].css'//css
    }),
  ],
  mode: 'production',
};

tree shaking:去除无用代码,减少代码体积

前提:1. 必须使用ES6模块化  2. 开启production环境

注意:package.json中配置sideEffects:false(所有代码都可以tree shaking,可能把打包后的css文件去掉)需要配置sideEffects:["*.css"]
code split:
a.入口文件有几个,就生成几个bundle;
b.配置了optimization中的chunks,将node_modules中代码单独打包一个chunk输出一个bundle;
c.import动态导入语法:能将某个文件单独打包成一个chunk。
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
//方式一:
module.exports = {
  // 单入口:输出一个bundle
  // entry: './src/js/index.js',
  entry: {
    // 多入口:输出两个bundle
    index: './src/js/index.js',
    test: './src/js/test.js'
  },
  output: {
    // [name]:取文件名
    filename: 'js/[name].[contenthash:10].js',
    path: resolve(__dirname, 'build')
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      minify: {
        collapseWhitespace: true,
        removeComments: true
      }
    })
  ],
  mode: 'production'
};

//方式二:
module.exports = {
  // 单入口:输出两个个bundle
  // entry: './src/js/index.js',//引入JQ
  entry: {
    // 多入口:输出三个bundle
    index: './src/js/index.js',//引入JQ
    test: './src/js/test.js'//引入JQ
  },
  output: {
    // [name]:取文件名
    filename: 'js/[name].[contenthash:10].js',
    path: resolve(__dirname, 'build')
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      minify: {
        collapseWhitespace: true,
        removeComments: true
      }
    })
  ],
  /*
    1. 可以将node_modules中代码单独打包一个chunk最终输出
    2. 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk
  */
  optimization: {
    splitChunks: {
      chunks: 'all'
    }
  },
  mode: 'production'
};

//方式三:
//在方式二的基础上,在入口文件中引入test.js
/*
  通过js代码,让某个文件被单独打包成一个chunk
  import动态导入语法:能将某个文件单独打包
*/
import(/* webpackChunkName: 'test' */'./test')
  .then(({ mul, count }) => {
    // 文件加载成功~
    console.log(mul(2, 5));
  })
  .catch(() => {
    console.log('文件加载失败~');
  });

懒加载:当文件需要使用时才加载~

预加载:文件使用之前提前加载,其他资源加载完毕,浏览器空闲时加载。兼容性较差

document.getElementById('btn').onclick = function() {//点击按钮的时候加载index.js中的test.js
  //预加载:webpackPrefetch: true
  import(/* webpackChunkName: 'test', webpackPrefetch: true */'./test').then(({ mul }) => {
    console.log(mul(4, 5));
  });
};

PWA: 渐进式网络开发应用程序(离线可访问)

1.安装workbox-webpack-plugin

2.入口文件注册配置文件

const { resolve } = require('path');
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');

/*
  PWA: 渐进式网络开发应用程序(离线可访问)
    workbox --> workbox-webpack-plugin
*/

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.[contenthash:10].js',
    path: resolve(__dirname, 'build')
  },
  module: { },
  plugins: [
    new WorkboxWebpackPlugin.GenerateSW({
      /*
        1. 帮助serviceworker快速启动
        2. 删除旧的 serviceworker

        生成一个 serviceworker 配置文件~
      */
      clientsClaim: true,
      skipWaiting: true
    })
  ],
  mode: 'production',
};

/*
  1. eslint不认识 window、navigator全局变量
    解决:需要修改package.json中eslintConfig配置
      "env": {
        "browser": true // 支持浏览器端全局变量
      }
   2. sw代码必须运行在服务器上
      --> nodejs
      -->
        npm i serve -g
        serve -s build 启动服务器,将build目录下所有资源作为静态资源暴露出去
*/
// index.js中注册serviceWorker
// 处理兼容性问题
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker
      .register('/service-worker.js')
      .then(() => {
        console.log('sw注册成功了~');
      })
      .catch(() => {
        console.log('sw注册失败了~');
      });
  });
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/127005.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++:STL:常用算法:遍历,查找,排序算法

概述&#xff1a; 算法主要是由头文件 <algorithm>&#xff0c;<functional>, <numeric> 组成。<algorithm> 是所有STL头文件中 最大的一个&#xff0c;范围涉及到&#xff1a;比较&#xff0c;交换&#xff0c;查找&#xff0c;遍历&#xff0c;复制…

JUC并发编程学习笔记(一)基本概念篇

1. 什么是 JUC 1.1 JUC 简介 在 Java 中&#xff0c;线程部分是一个重点&#xff0c;本篇文章说的 JUC 也是关于线程的。JUC就是 java.util .concurrent 工具包的简称。这是一个处理线程的工具包&#xff0c;JDK 1.5 开始出现的。 1.2 进程与线程 进程&#xff08;Process…

第三章 网页中的表格和表单

表格的结构 <table barder"1"> cellspacing"0" <tr>#行 <td>单元格-</td> <td>单元格-</td> </tr> <tr> <td>单元格-</td> …

智能家居创意DIY-智能触摸面板开关

触摸开关&#xff0c;即通过触摸方式控制的墙壁开关&#xff0c;其感官场景如同我们的触屏手机&#xff0c;只需手指轻轻一点即可达到控制电器的目的&#xff0c;随着人们生活品质的提高&#xff0c;触摸开关将逐渐将换代传统机械按键开关。 触摸开关控制原理 触摸开关我们把…

解决vscode使用markdown无法预览网络图片

解决vscode使用markdown无法预览网络图片一、问题描述二、本机环境三、解决方案3.1 需要修改预览安全策略3.2 配置github 域名解析一、问题描述 使用vscode&#xff0c;在markdown的预览模式下无法预览网络图片 二、本机环境 该问题与电脑硬件以及操作系统环境无关。 本机m…

数据结构初阶:链式二叉树的遍历解析及一些基本操作

目录 前置说明 一、 二叉树的遍历&#xff08;理论&#xff09; 1. 二叉树的拆解 2. 二叉树的前序&#xff08;先根&#xff09;遍历 3. 二叉树的中序&#xff08;中根&#xff09;遍历 4. 二叉树的后序&#xff08;后根&#xff09;遍历 5. 二叉树的层序遍历 二、 代码实操…

PostFix+Dovecot 部署邮件系统

Postfix 是一种电子邮件服务器是一个开放源代码的软件. Postfix 是MTA邮件传输代理软件.是sendmail提供替代品的一个尝试,在Internet世界中,大部分的电子邮件都是通过sendmail来投递的,大约有100万用户使用sendmail,每天投递上亿封邮件,Postfix试图更快、更容易管理、更安全,同…

【bp靶场portswigger-服务端2】身份认证-16个实验(全)

目录 一、身份验证定义 1、三个身份验证因素 2、身份验证和授权 3、身份验证漏洞的产生 4、实验的字典 二、基于密码的登录中的漏洞 1、强制策略 2、用户枚举 3、有缺陷的强力保护 实验1&#xff1a;通过不同响应的用户名枚举 实验4&#xff1a;通过细微不同的响应进…

BPF学习笔记(六)-- 使用bpf实现xdp的例子

本篇文章参考《Linux Observability with BPF》中第7章的例子&#xff0c;主要功能是借助于ip命令作为前端&#xff0c;对其他主机访问tcp的8000端口进行限制&#xff0c;这里需要使用较新版本的iproute2软件工具包. 1. 下载编译iproute2 工具包&#xff0c;使用最新的ip命令…

gRPC学习

首先什么了解什么是RPC? 不同于 TCP 和 HTTP&#xff0c;TCP 和 HTTP 是网络传输协议&#xff0c;而 RPC 是一种设计、实现框架&#xff0c;通讯协议只是其中一部分&#xff0c;RPC 不仅要解决协议通讯的问题&#xff0c;还有序列化和反序列化&#xff0c;以及消息通知。 一…

IDEA的使用技巧积累

本文主要是记录一些在使用IDEA过程中遇到的一些问题解决方法、以及快捷键等 添加框架支持 打开模块设置 (文件—>项目结构也是同理) 主要用于配置模块&#xff0c;例如web&#xff0c;springboot模块 设置 主要设置maven的一些信息 CtrlShiftF (java代码审计基础中出现…

WebSocket的基本使用

目录 为何使用websocket 1.后端搭建 2.搭建webSocket前后分离 1.配置跨域过滤器与初始化websocket 2.定义websocket服务 3.定义控制器进行测试webSocket向前端发送消息 2.前端准备 3.进行测试 向后端发送消息测试 后端向前端发送消息测试 为何使用websocket 在浏览器…

小型云台机械手红外搬运功能的实现

1. 功能说明 在小型云台机械手前方安装近红外传感器&#xff0c;如果近红外触发&#xff08;检测到有货物&#xff09;&#xff0c;机械手开始抓取货物&#xff0c;并将货物从一个区域搬运到另一个指定区域&#xff1b;否则&#xff0c;机械臂不动作。 2. 使用样机 本实验使用…

【LeetCode】从前序与中序遍历序列构造二叉树 [M](二叉树重构)

105. 从前序与中序遍历序列构造二叉树 - 力扣&#xff08;LeetCode&#xff09; 一、题目 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1&…

ASEMI整流桥MB10S,DB207S和ABS210有什么区别

编辑-Z ASEMI整流桥MB10S&#xff0c;DB207S和ABS210有什么区别&#xff1f;这几个型号从外观看都是很相似的&#xff0c;那么他们参数有什么不一样呢&#xff1f; MB10S参数&#xff1a; 型号&#xff1a;MB10S 封装&#xff1a;MBS-4 最大重复峰值反向电压&#xff08;VR…

缓冲区Buffer类的设计(参考Muduo实现)

Buffer的功能需求&#xff1a; Buffer类的设计目的是再创造一层应用层缓冲区。 其对外表现为一块连续的内存(char* p, int len)&#xff0c;以方便客户代码的编写。 size() 可以自动增长&#xf…

Java如何自定义一个变长数组?

文章目录思路分析实现代码测试结果首先需要声明的是&#xff0c; Java本身是提供了变长数组的&#xff0c;即 ArrayList。那么自定义一个变长数组有啥用&#xff1f;其实没啥用或者说用处不大&#xff0c;主要就是为了了解下变长数组的设计理念而已。实际工作中直接使用 ArrayL…

文华财经期货背离信号准确率高指标公式,单边趋势行情增仓上行多空共振策略

由“短线震荡波段王”和“三柱共振-高把握”指标合成 功能 : 1.红绿小波段黄蓝中波段粉青大波段 2.红绿中小波段 3.顶背底背提示 4.金叉死叉提示 5.多和空提示-金叉死叉改写 优点:宽幅震荡和窄幅震荡 弊端:单边行情(可结合多空趋势主图规避) 功能: 1.红绿波段 2.大中量仓-单…

MySQL索引详解

目录 1、为什么要有索引&#xff1f; 2、预备知识 3、为何IO交互要是 Page&#xff1f; 4、如何理解Page以及索引理解 5、索引操作 <1> 创建主键索引 <2> 创建唯一索引 <3> 普通索引的创建 <4> 全文索引的创建 <5> 查询索引 <5>…

Python图像识别实战(五):卷积神经网络CNN模型图像二分类预测结果评价(附源码和实现效果)

前面我介绍了可视化的一些方法以及机器学习在预测方面的应用&#xff0c;分为分类问题&#xff08;预测值是离散型&#xff09;和回归问题&#xff08;预测值是连续型&#xff09;&#xff08;具体见之前的文章&#xff09;。 从本期开始&#xff0c;我将做一个关于图像识别的…