Vue3学习之旅--之webpack基础-进阶--webpack5?拿来吧你!


vue3一路的笔记
vue3学习之旅–邂逅vue3-了解认识Vue3
vue3学习之旅–邂逅vue3-了解认识Vue3(二)
Vue3学习之旅–爱上Vue3–Vue3基础语法(一)–以及vscode基本使用和快速生成代码片段
Vue3学习之旅–爱上Vue3–Vue3的Options-API
vue3学习之旅–vue的表单和开发模式–组件化开发初识
Vue3学习之旅–初识webpack–webpack打包js,css,less等文件以及兼容性处理

Webpack打包其他资源

加载图片案例准备

为了演示我们项目中可以加载图片,我们需要在项目中使用图片,比较常见的使用图片的方式是两种:

  1. img元素,设置src属性;
  2. 其他元素(比如div),设置background-image的css属性;
.image-bg {
  background-image: url("../image/3.jpg");
  width: 300px;
  height: 300px;
}
// 导入背景图片的样式
import '../css/index.css'
import myImg from '../image/1.JPG'
// 设置背景图片
const bgDiv = document.createElement('div');
bgDiv.className = 'image-bg';

// 设置img标签的src属性
const img = document.createElement('img');
img.src = myImg;

document.body.appendChild(bgDiv);
document.body.appendChild(img);

这个时候,打包会报错

image-20210728191425399

报错了,并且提示我们可以需要一个loader来解决图片的问题。

file-loader

要处理jpg、png等格式的图片,我们也需要有对应的loader:file-loader

  1. file-loader的作用就是帮助我们处理import/require()方式引入的一个文件资源,并且会将它放到我们输出的文 件夹中;
  2. 当然我们待会儿可以学习如何修改它的名字和所在文件夹;

安装file-loader:

npm i file-loader -D

配置处理图片的Rule:

// 配置打包图片资源的规则
{
    test: /\.(jpg|png|jpeg|JPG)$/,
    use: 'file-loader'
}

image-20210728191711488

我们会发现图片也被打包了。

image-20210728191748775

image-20210728191838557

文件的命名规则

有时候我们处理后的文件名称按照一定的规则进行显示:

  • 比如保留原来的文件名、扩展名,同时为了防止重复,包含一个hash值等;

这个时候我们可以使用PlaceHolders来完成,webpack给我们提供了大量的PlaceHolders来显示不同的内容:

  1. https://webpack.js.org/loaders/file-loader/#placeholders
  2. 我们可以在文档中查阅自己需要的placeholder;

我们这里介绍几个最常用的placeholder:

  • [ext]: 处理文件的扩展名;
  • [name]:处理文件的名称;
  • [hash]:文件的内容,使用MD4的散列函数处理,生成的一个128位的hash值(32个十六进制);
  • [contentHash]:在file-loader中和[hash]结果是一致的(在webpack的一些其他地方不一样,后面会讲到);
  • [hash:length]:截图hash的长度,默认32个字符太长了;
  • [path]:文件相对于webpack配置文件的路径;
设置文件的名称

那么我们可以按照如下的格式编写:这个也是vue的写法;

{
        test: /\.(jpg|png|jpeg|JPG)$/,
        use: {
          loader: 'file-loader',
          // file-loader的参数配置
          options: {
            // 打包后图片文件所在的路径
            // outputPath: 'image',
            // 打包后生成文件的名称
            // [name] 源文件的名称(不含拓展名)
            // 我们发现不写配置时,文件的名称过长(且文件名是通过hash算法算出来的,为了防止重名)
            // [hash:6] 默认生成文件名称的hash算法,32位,取前六位
            // [ext] 使用原来文件的拓展名
            // name: '[name]_[hash:6].[ext]'

            // 当然:我们也可以把图片存放的路径和图片名称合在一起
            name: 'image/[name]-[hash:6].[ext]'
          }
        }
      }

image-20210728192329730

设置文件的存放路径

当然,我们刚才通过 img/ 已经设置了文件夹,这个也是vue、react脚手架中常见的设置方式:

  1. 其实按照这种设置方式就可以了;
  2. 当然我们也可以通过outputPath来设置输出的文件夹;

image-20210728192445432

url-loader

url-loader和file-loader的工作方式是相似的,但是可以将较小的文件,转成base64的URI。

安装url-loader:

npm i url-loader -D
{
        test: /\.(jpe?g|JPG|png)$/,
        use: {
          loader: 'url-loader',
          options: {
            name: 'image/[name]-[hash:6].[ext]',
            // 设置图片大小的限制,只有小于多少kb的图片我们才会转为base64格式
            // 如果大于这个限制 我们就不会转为base64格式。而是继续采用上面的path和name的形式打包,还是保持图片的形式不变
            limit: 100 * 1024 // 小于100kb的文件才会转为base64格式
          }
        }
      }

image-20210728192652383

显示结果是一样的,并且图片可以正常显示;

但是在dist文件夹中,我们会看不到 大于100kb 图片文件:

image-20210728192839738

  1. 这是因为我的两张图片的大小分别是38kb和129kb;
  2. 默认情况下url-loader会将所有的图片文件转成base64编码。但是配置了limit以后就可以限制小于多少kb的图片才会转为base64格式。

可以看见bundle.js文件里面的确有base64格式的字符串

image-20210728193159584

url-loader的limit

但是开发中我们往往是小的图片需要转换,但是大的图片直接使用图片即可

  1. 这是因为小的图片转换base64之后可以和页面一起被请求,减少不必要的请求过程;
  2. 而大的图片也进行转换,反而会影响页面的请求速度;

那么,我们如何可以限制哪些大小的图片转换和不转换呢?

  1. url-loader有一个options属性limit,可以用于设置转换的限制;
  2. 下面的代码38kb的图片会进行base64编码,而129kb的不会;

image-20210728193333744

asset module type

认识asset module type

我们当前使用的webpack版本是webpack5:

  1. 在webpack5之前,加载这些资源我们需要使用一些loader,比如raw-loader 、url-loader、file-loader;
  2. 在webpack5开始,我们可以直接使用资源模块类型(asset module type),来替代上面的这些loader;

资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader:

  1. asset/resource :发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现;
  2. asset/inline :导出一个资源的 data URI。之前通过使用 url-loader 实现;
  3. asset/source :导出资源的源代码。之前通过使用 raw-loader 实现;
  4. asset: 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader,并且配置资源体 积限制实现;
asset module type的使用

比如加载图片,我们可以使用下面的方式:

image-20210728193636774

发现依然打包成功!

image-20210728193748026

但是,如何可以自定义文件的输出路径和文件名呢?

方式一:修改output,添加assetModuleFilename属性; (了解即可)

image-20210728193854459

方式二:在Rule中,添加一个generator属性,并且设置filename;

{
        test: /\.(JPG|jpe?g|png)$/,
        // 这里不在使用use属性 而是type属性
        // 使用asset/resource 来代替 file-loader
        // type:'asset/resource'

        // 比较常用的我们一般直接写成 asset
        type: 'asset',
        // 下面的配置也可以放在 output里面(了解)
        // generator属性 生成 也就是打包后的图片存放时相关的配置
        generator: {
          // 配置图片名称和图片位置 
          // 这里的 [ext] 拿到的文件拓展名包含 .
          filename: 'image/[name]-[hash:6][ext]'
        }
      }

image-20210728194023352

url-loader的limit效果

我们需要两个步骤来实现:

  1. 将type必须使用asset属性值;
  2. 添加一个parser属性,并且制定dataUrl的条件,添加maxSize属性;
{
        test: /\.(JPG|jpe?g|png)$/,
        // 比较常用的我们一般直接写成 asset
        type: 'asset',
        // 配置相关的asset参数 使用parser属性
        parser: {
          // 数据url条件
          dataUrlCondition: {
            // 最大不超过多少kb的图片 我们转为 base64格式
            maxSize: 100 * 1024
          }
        },
        generator: {
          filename: 'image/[name]-[hash:6][ext]'
        }
      }

image-20210728194251709

发现打包的只有一个图片文件了。较小的那个已经转为base64格式了

image-20210728194347840

加载字体文件

如果我们需要使用某些特殊的字体或者字体图标,那么我们会引入很多字体相关的文件,这些文件的处理也是一样 的

首先,我从阿里图标库中下载了几个字体图标:

image-20210728195048166

然后在font.js里面引入,并设置一个 i标签用于显示字体图标

// 引入并使用字体图标

// 加载字体图标的文件
import '../font/iconfont.css'

// i标签
const i = document.createElement('i');
i.className = 'iconfont icon-ashbin';

document.body.appendChild(i);

然后我们开始打包

image-20210728195219912

毫无疑问,必然报错,因为我们使用了webpack并不认识的模块。并且webpack也提醒我们需要使用一个loader来解决。

字体的打包

这个时候打包会报错,因为无法正确的处理eot、ttf、woff等文件

我们可以选择使用file-loader来处理,也可以选择直接使用webpack5的资源模块类型来处理;

// 配置字体和字体图标等文件打包时的规则
      {
        test: /\.(eot|ttf|woff2?)$/,
        use:{
          loader: 'file-loader',
          options:{
            name: 'font/[name]-[hash:6].[ext]'
          }
        }
      }

打包之后,发现不会报错,字体图标正常显示。

image-20210728200328258

使用webpack5提供的资源模块类型也可以。

// 也可以使用webpack提供的资源模块类型
{
    test: /\.(eot|ttf|woff2?)$/,
    type: 'asset/resource',
    generator:{
        filename: 'font/[name]-[hash:6][ext]'
    }
}

webpack的plugin

认识plugin

Webpack的另一个核心是Plugin,官方有这样一段对Plugin的描述:

While loaders are used to transform certain types of modules, plugins can be leveraged to perform a wider range of tasks like bundle optimization, asset management and injection of environment variables.

上面表达的含义翻译过来就是:

  1. Loader是用于特定的模块类型进行转换
  2. Plugin可以用于执行更加广泛的任务,比如打包优化、资源管理、环境变量注入等;

image-20210728205205354

CleanWebpackPlugin

前面我们演示的过程中,每次修改了一些配置,重新打包时,都需要手动删除dist文件夹:

我们可以借助于一个插件来帮助我们完成,这个插件就是CleanWebpackPlugin;

首先,我们先安装这个插件:

npm i clean-webpack-plugin -D

之后在插件中配置:

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
  // 提供 plugins属性来配置插件
  // plugins属性是数组,数组元素是一个个的插件对象
  plugins: [
    new CleanWebpackPlugin()
  ]
}

image-20210728205459482

然后可以发现每次都会帮我们把上次打包的文件夹先删除,然后在进行重新打包。

HtmlWebpackPlugin

另外还有一个不太规范的地方:

  1. 我们的HTML文件是编写在根目录下的,而最终打包的dist文件夹中是没有index.html文件的。
  2. 在进行项目部署的时,必然也是需要有对应的入口文件index.html;
  3. 所以我们也需要对index.html进行打包处理;

对HTML进行打包处理我们可以使用另外一个插件:HtmlWebpackPlugin;

npm i html-webpack-plugin -D

image-20210728205744529

image-20210728205754385

生成index.html分析

我们会发现,现在自动在build文件夹中,生成了一个index.html的文件:

该文件中也自动添加了我们打包的bundle.js文件;

image-20210728210054115

image-20210728205905823

这个文件是如何生成的呢?

  1. 默认情况下是根据ejs的一个模板来生成的;
  2. 在html-webpack-plugin的源码中,有一个default_index.ejs模块;
自定义HTML模板

如果我们想在自己的模块中加入一些比较特别的内容:

  1. 比如添加一个noscript标签,在用户的JavaScript被关闭时,给予响应的提示;

  2. 比如在开发vue或者react项目时,我们需要一个可以挂载后续组件的根标签

这个我们需要一个属于自己的index.html模块:

下面是模板代码(使用Vue-cli脚手架开发时的默认的模板就是这个)

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

但是:使用这个模板直接进行打包的时候:会发现打包失败!!(使用html-webpack-plugin插件的时候需要指定该模板)

image-20210728211538093

image-20210728212035161

自定义模板数据填充

上面的代码中,会有一些类似这样的语法**<% 变量 %>**,这个是EJS模块填充数据的方式。

在配置HtmlWebpackPlugin时,我们可以添加如下配置:

  1. template:指定我们要使用的模块所在的路径;
  2. title:在进行htmlWebpackPlugin.options.title读取时,就会读到该信息;

image-20210728212132479

但是,我们会发现,即使配置了模板啊,标题啊,仍然打包还是报错。

不要着急,我们可以使用webpack内置的一个插件来进行解决。

DefinePlugin
DefinePlugin的介绍

我们上面指定了模板以后,发现仍然还是报错。报错的原因是什么呢?

因为在我们的模块中还使用到一个BASE_URL的常量:

image-20210728212410783

这是因为在编译template模块时,有一个BASE_URL

<link rel="icon" href="<%= BASE_URL %>favicon.ico">

但是我们并没有设置过这个常量值,所以会出现没有定义的错误;

这个时候我们可以使用DefinePlugin插件

DefinePlugin的使用

DefinePlugin允许在编译时创建配置的全局常量,是一个webpack内置的插件(不需要单独安装):

image-20210728213427918

image-20210728213438757

// 导入 DefinePlugin 插件 解决常量 BASE_URL 的问题
const { DefinePlugin } = require('webpack');
module.exports = {
  // 提供 plugins属性来配置插件
  // plugins属性是数组,数组元素是一个个的插件对象
  plugins: [
    // 使用 DefinePlugin 插件来定义 常量
    new DefinePlugin({
      BASE_URL: "'./'"
    })
  ]

这个时候,编译template就可以正确的编译了,会读取到BASE_URL的值;

DefinePlugin的注意点
new DefinePlugin({
      // BASE_URL 会根据后面给的属性值 去本文件上下文中找这个变量
      // 比如我这里给的是字符串 "filepath"
      // 也会去上下文中找叫做 filepath 的变量
      // 如果我们想直接给一个字符串的值
      // 我们需要在双引号里面嵌套单引号赋值
      // 当然 单引号里面嵌套双引号赋值也是可以的
      // BASE_URL: "filepath",
      BASE_URL: "'./'"
    })

CopyWebpackPlugin

在vue的打包过程中,如果我们将一些文件放到public的目录下,那么这个目录会被复制到dist文件夹中。这个复制的功能,我们可以使用CopyWebpackPlugin来完成;

安装CopyWebpackPlugin插件:

npm i copy-webpack-plugin -D

接下来配置CopyWebpackPlugin即可:

  1. 复制的规则在patterns中设置;
  2. from:设置从哪一个源中开始复制;
  3. to:复制到的位置,可以省略,会默认复制到打包的目录下;
  4. globOptions:设置一些额外的选项,其中可以编写需要忽略的文件:
    • .DS_Store:mac目录下回自动生成的一个文件;
    • index.html:也不需要复制,因为我们已经通过HtmlWebpackPlugin完成了index.html的生成;
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
    plugins:[
        // 其他省略
        new CopyWebpackPlugin({
            patterns: [
        {
          // 复制的来源
          from: 'public',
          to: '',
          // 全局配置  globOptions
          globOptions: {
            ignore: '**/index.html'
          }
        }
      ]
        })
    ]
}

可以看到效果和我们的配置的一样。

image-20210728215659702

Mode配置

前面我们一直没有讲mode。

Mode配置选项,可以告知webpack使用响应模式的内置优化:

  1. 默认值是production(什么都不设置的情况下);
  2. 可选值有:‘none’ | ‘development’ | ‘production’;
选项描述
development会将 DefinePluginprocess.env.NODE_ENV 的值设置为 development. 为模块和 chunk 启用有效的名。
production会将 DefinePluginprocess.env.NODE_ENV 的值设置为 production。为模块和 chunk 启用确定性的混淆名称,FlagDependencyUsagePluginFlagIncludedChunksPluginModuleConcatenationPluginNoEmitOnErrorsPluginTerserPlugin
none不使用任何默认优化选项

如果没有设置,webpack 会给 mode 的默认值设置为 production

如果 mode 未通过配置或 CLI 赋值,CLI 将使用可能有效的 NODE_ENV 值作为 mode。当然这是后话了。我们学习CLI的时候再来说。

image-20210728221004362

Mode配置代表更多

只要设置了mode属性,webpack就会默认帮我们设置很多属性。不需要我们手动再去配置。

image-20210728221656536

image-20210728221716634

devtool配置

这里顺手补充一波devtool

devtool也是和mode同级别的配置。默认值是eval。设置开发时的工具

此选项控制是否生成,以及如何生成 source map

eval

在默认值的情况下:默认会使用 eval函数对源代码进行包裹

// devtool 属性 :设置开发时的工具 默认值是 eval
// 默认会使用 eval函数对源代码进行包裹
devtool: 'eval'

image-20210728223158431

发现我们的打包后的代码全都被eval函数包裹

source-map

把属性设置为source-map。出现错误就可以定位源码。

// 如果想查看源码:可以设置值为 source-map
// 设置为这个属性 会生成对应的打包后的代码和源码映射的文件
// 出现错误可以映射到我们书写的源代码
devtool: 'source-map'

image-20210728223248505

image-20210728223306610

两种方式出现错误后的对比
eval配置代码出现错误时

image-20210728223827751

image-20210728223842559

发现代码并不是我们自己写的源码。不好辨别具体是那个文件出现错误。

source-map配置代码出现错误时

image-20210728223957836

image-20210728224005593

出现错误,可以直接定位到具体是哪一个源文件。很nice。

附上devtool的各种配置
devtoolperformanceproductionqualitycomment
(none)build: fastest rebuild: fastestyesbundleRecommended choice for production builds with maximum performance.
evalbuild: fast rebuild: fastestnogeneratedRecommended choice for development builds with maximum performance.
eval-cheap-source-mapbuild: ok rebuild: fastnotransformedTradeoff choice for development builds.
eval-cheap-module-source-mapbuild: slow rebuild: fastnooriginal linesTradeoff choice for development builds.
eval-source-mapbuild: slowest rebuild: oknooriginalRecommended choice for development builds with high quality SourceMaps.
cheap-source-mapbuild: ok rebuild: slownotransformed
cheap-module-source-mapbuild: slow rebuild: slownooriginal lines
source-mapbuild: slowest rebuild: slowestyesoriginalRecommended choice for production builds with high quality SourceMaps.
inline-cheap-source-mapbuild: ok rebuild: slownotransformed
inline-cheap-module-source-mapbuild: slow rebuild: slownooriginal lines
inline-source-mapbuild: slowest rebuild: slowestnooriginalPossible choice when publishing a single file
eval-nosources-cheap-source-mapbuild: ok rebuild: fastnotransformedsource code not included
eval-nosources-cheap-module-source-mapbuild: slow rebuild: fastnooriginal linessource code not included
eval-nosources-source-mapbuild: slowest rebuild: oknooriginalsource code not included
inline-nosources-cheap-source-mapbuild: ok rebuild: slownotransformedsource code not included
inline-nosources-cheap-module-source-mapbuild: slow rebuild: slownooriginal linessource code not included
inline-nosources-source-mapbuild: slowest rebuild: slowestnooriginalsource code not included
nosources-cheap-source-mapbuild: ok rebuild: slownotransformedsource code not included
nosources-cheap-module-source-mapbuild: slow rebuild: slownooriginal linessource code not included
nosources-source-mapbuild: slowest rebuild: slowestyesoriginalsource code not included
hidden-nosources-cheap-source-mapbuild: ok rebuild: slownotransformedno reference, source code not included
hidden-nosources-cheap-module-source-mapbuild: slow rebuild: slownooriginal linesno reference, source code not included
hidden-nosources-source-mapbuild: slowest rebuild: slowestyesoriginalno reference, source code not included
hidden-cheap-source-mapbuild: ok rebuild: slownotransformedno reference
hidden-cheap-module-source-mapbuild: slow rebuild: slownooriginal linesno reference
hidden-source-mapbuild: slowest rebuild: slowestyesoriginalno reference. Possible choice when using SourceMap only for error reporting purposes.

本次使用过的配置代码展示

plugin以前的配置
const path = require('path');

module.exports = {
  entry: path.join(__dirname, "./src/index.js"),
  output: {
    path: path.join(__dirname, "./build"),
    filename: 'bundle.js',
    // 使用asset打包的图片不转为base64格式的时候,图片存放的位置以及名称
    // assetModuleFilename: 'image/[name]-[hash:6][ext]'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader'
        ]
      },
      {
        test: /\.less$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader',
          'less-loader'
        ]

      },
      // 配置打包图片资源的规则
      // {
      //   test: /\.(jpg|png|jpeg|JPG)$/,
      //   use: 'file-loader'
      // }
      /* {
        test: /\.(jpg|png|jpeg|JPG)$/,
        use: {
          loader: 'file-loader',
          // file-loader的参数配置
          options: {
            // 打包后图片文件所在的路径
            // outputPath: 'image',
            // 打包后生成文件的名称
            // [name] 源文件的名称(不含拓展名)
            // 我们发现不写配置时,文件的名称过长(且文件名是通过hash算法算出来的,为了防止重名)
            // [hash:6] 默认生成文件名称的hash算法,32位,取前六位
            // [ext] 使用原来文件的拓展名
            // name: '[name]_[hash:6].[ext]'

            // 当然:我们也可以把图片存放的路径和图片名称合在一起
            name: 'image/[name]-[hash:6].[ext]'
          }
        }
      } , */

      // 注意: 使用file-loader就不要使用url-loader
      // 使用url-loader也不需要使用file-loader
      // 配置url-loader 设置图片大小的限制,小于某个范围的图片转为base64格式
      // {
      //   test: /\.(jpe?g|JPG|png)$/,
      //   use: {
      //     loader: 'url-loader',
      //     options: {
      //       name: 'image/[name]-[hash:6].[ext]',
      //       // 设置图片大小的限制,只有小于多少kb的图片我们才会转为base64格式
      //       // 如果大于这个限制 我们就不会转为base64格式。而是继续采用上面的path和name的形式打包,还是保持图片的形式不变
      //       limit: 100 * 1024 // 小于100kb的文件才会转为base64格式
      //     }
      //   }
      // }


      // webpack5开始 可以不在使用file-loader和url-loader来进行打包图片了
      // 我们直接使用 asset module type 资源模块类型 来替换上面loader
      // 注意:asset是webpack5自带的
      {
        test: /\.(JPG|jpe?g|png)$/,
        // 这里不在使用use属性 而是type属性
        // 使用asset/resource 来代替 file-loader
        // type:'asset/resource'

        // 比较常用的我们一般直接写成 asset
        type: 'asset',
        // 配置相关的asset参数 使用parser属性
        parser: {
          // 数据url条件
          dataUrlCondition: {
            // 最大不超过多少kb的图片 我们转为 base64格式
            maxSize: 100 * 1024
          }
        },
        // 下面的配置也可以放在 output里面(了解)
        // generator属性 生成 也就是打包后的图片存放时相关的配置
        generator: {
          // 配置图片名称和图片位置 
          // 这里的 [ext] 拿到的文件拓展名包含 .
          filename: 'image/[name]-[hash:6][ext]'
        }
      },
      // 配置字体和字体图标等文件打包时的规则
      // {
      //   test: /\.(eot|ttf|woff2?)$/,
      //   use:{
      //     loader: 'file-loader',
      //     options:{
      //       // 这里是name属性 不是filename
      //       name: 'font/[name]-[hash:6].[ext]'
      //     }
      //   }
      // },

      // 也可以使用webpack提供的资源模块类型
      {
        test: /\.(eot|ttf|woff2?)$/,
        type: 'asset/resource',
        generator: {
          // 这里使用的是filename属性 别忘了!!!!!
          filename: 'font/[name]-[hash:6][ext]'
        }
      }
    ]
  }
}
plugin开始及以后的配置
const path = require('path');

// 注意:所有的插件都需要导入的,loader不需要
// 导入 clean-webpack-plugin 插件
// 该插件导出的是一个对象,我们需要从对象里面按需获取 CleanWebpackPlugin 这个类
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

// 导入 html-webpack-plugin插件 这个插件导出的就是一个类 不需要解构
const HtmlWebpackPlugin = require('html-webpack-plugin')

// 导入 DefinePlugin 插件 解决常量 BASE_URL 的问题
const { DefinePlugin } = require('webpack');

// 导入 CopyWebpackPlugin 插件 该插件导出的也是一个类
// 用来完成文件的复制工作
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {

  // 模式配置 mode
  // development 生产模式 打包的代码不会压缩 易于阅读
  mode:"development",
  // 开发模式 代码会被压缩 减小体积
  // mode:"production",

  // devtool 属性 :设置开发时的工具 默认值是 eval
  // 默认会使用 eval函数对源代码进行包裹
  // devtool: 'eval',
  // 如果想查看源码:可以设置值为 source-map
  // 设置为这个属性 会生成对应的打包后的代码和源码映射的文件
  // 出现错误可以映射到我们书写的源代码
  devtool: 'source-map',

  // 提供 plugins属性来配置插件
  // plugins属性是数组,数组元素是一个个的插件对象
  // 插件是书写没有先后顺序!!!!!!!!!!
  plugins: [
    // 使用 CleanWebpackPlugin 插件对象 
    // 因为 CleanWebpackPlugin 是一个class类,我们需要 new 实例化成对象
    // CleanWebpackPlugin 插件会删除我们生成的打包后的那么文件夹,然后重新打包
    new CleanWebpackPlugin(),
    // 使用 HtmlWebpackPlugin 插件
    // new HtmlWebpackPlugin(),

    // 使用 HtmlWebpackPlugin 插件 并指定html的模板
    new HtmlWebpackPlugin({
      // 按照这个html文件的模板来进行打包,生成的index.html和这个模板一样
      template: './public/index.html',
      title: 'webpack-plugin 的学习'
    }),
    // 使用 DefinePlugin 插件来定义 常量
    new DefinePlugin({
      // BASE_URL 会根据后面给的属性值 去本文件上下文中找这个变量
      // 比如我这里给的是字符串 "filepath"
      // 也会去上下文中找叫做 filepath 的变量
      // 如果我们想直接给一个字符串的值
      // 我们需要在双引号里面嵌套单引号赋值
      // 当然 单引号里面嵌套双引号赋值也是可以的
      // BASE_URL: "filepath",
      BASE_URL: "'./'"
    }),

    // 使用 CopyWebpackPlugin 插件
    new CopyWebpackPlugin({
      // patterns属性: 匹配规则 数组
      patterns: [
        {
          // 复制的来源
          from: 'public',
          // 复制后放到哪里
          // 不写,或者给空字符串 最后都是把拷贝的文件放在打包后的根目录下
          to: '',
          // 全局配置  globOptions
          globOptions: {
            // 忽略那些文件
            // ignore: ['**/index.html'],
            // 只有一个忽略的规则时 可以直接写一个字符串
            ignore: '**/index.html'
          }
        }
      ]
    })
  ],
  entry: path.join(__dirname, "./src/index.js"),
  output: {
    path: path.join(__dirname, "./build"),
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader'
        ]
      },
      {
        test: /\.less$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader',
          'less-loader'
        ]
      },
      // webpack5开始 可以不在使用file-loader和url-loader来进行打包图片了
      // 我们直接使用 asset module type 资源模块类型 来替换上面loader
      // 注意:asset是webpack5自带的
      {
        test: /\.(JPG|jpe?g|png)$/,
        // 这里不在使用use属性 而是type属性
        // 使用asset/resource 来代替 file-loader
        // type:'asset/resource'

        // 比较常用的我们一般直接写成 asset
        type: 'asset',
        // 配置相关的asset参数 使用parser属性
        parser: {
          // 数据url条件
          dataUrlCondition: {
            // 最大不超过多少kb的图片 我们转为 base64格式
            maxSize: 100 * 1024
          }
        },
        // 下面的配置也可以放在 output里面(了解)
        // generator属性 生成 也就是打包后的图片存放时相关的配置
        generator: {
          // 配置图片名称和图片位置 
          // 这里的 [ext] 拿到的文件拓展名包含 .
          filename: 'image/[name]-[hash:6][ext]'
        }
      },

      // 也可以使用webpack提供的资源模块类型
      {
        test: /\.(eot|ttf|woff2?)$/,
        type: 'asset/resource',
        generator: {
          // 这里使用的是filename属性 别忘了!!!!!
          filename: 'font/[name]-[hash:6][ext]'
        }
      }
    ]
  }
}
  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尤雨东

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值