• webpack5从零开始,到打包一个项目的基本配置


    webpack5从零开始,上手基础知识

    一、安装、认识webpack

    安装

    webpack基于node环境,所以安装webpack前先安装node

    npm install webpack webpack-cli --global
    npm i webpack webpack-cli -D
    
    • 1
    • 2

    第一种是全局安装,但是官方不建议我们使用全局安装,全局安装的话很可能更新不及时

    第二种是在项目中安装

    安装后可查看项目webpack版本信息

    npx webpack --version
    
    • 1

    我安装的版本是:后面的内容都是这个版本

        "webpack": "^5.72.1",
        "webpack-cli": "^4.9.2"
    
    • 1
    • 2

    webpack5默认情况下会以 ./src/index.js文件为入口文件开始打包,打包后输出到dist文件夹内,文件名为,main.js

    webpack五大核心概念

    1>entry入口

    以哪个文件为入口起点开始打包,分析构建内部依赖图

    2>output输出

    打包后的资源输出到哪里,打包后的文件如何命名

    3>loader预加载

    Webpack自身只能理解js/json文件,loader可以告诉webpack怎么处理非js文件

    4>plugins插件

    可以执行更广的任务,从打包优化和压缩,一直到重新定义环境中的变量等

    5>mode模式

    开发模式:development

    生产模式:production

    二、基本使用

    打包命令

    这个命令缺点是浏览器不能自动刷新

    npx webpack
    npx webpack --watch  // 监听文件变化,保存时有变化就会自动打包
    
    • 1
    • 2

    开发环境为了更加方便,我们借助webpack-dev-server

    npx webpack-dev-server
    npx webpack-dev-server --open  // 自动打开浏览器
    npm run serve                  // 就相当于执行了npx webpack-dev-server
    
    • 1
    • 2
    • 3

    新建一个项目,利用webpack打包一个js文件

    1> npm init -y,初始化项目文件

    2> npm i webpack webpack-cli -D 项目安装webpack

    3> 新建webpack.config.js文件,设置最基本的打包配置

    const path = require("path");
    module.exports = {
      entry: "./src/firstFile.js",
      output: {
        filename: "firstWebpack.js",
        path: path.resolve(__dirname, "dist"),
      },
      mode: "none",
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4> npx webpack打包

    打包结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vDTFzMp7-1653203689296)(C:\Users\lucas\Desktop\学习\图片\firstWebpack.jpg)]

    我们在index.html文件中引入打包后的js文件,浏览器打开,控制台输出this is my first webpack

    这样,我们就完成使用webpack打包一个js文件

    三、不同资源、文件的处理

    因为我们的webpack只支持js的打包处理,所以其他类型的文件资源就需要借助loader来处理了

    处理html

    安装插件

    npm i html-webpack-plugin -D
    
    • 1

    webpack.config.js中引入插件并进行相关配置

    const HtmlWebpackPlugin = require("html-webpack-plugin");
    
    • 1
      plugins: [
        new HtmlWebpackPlugin({
          template: "./src/index.html",  // 模板是哪个html文件
          filename: "index.html",  // 打包后生成的html文件名称
          inject: "body",  // js文件的位置,这里放入了body标签中
        }),
      ],
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    处理css、less等样式文件(打包压缩)

    样式文件的打包

    npm i style-loader css-loader less-loader -D
    
    • 1
      {
        test: /\.(css|less)$/,
        use: ["style-loader", "css-loader", "less-loader"],
      },
    
    • 1
    • 2
    • 3
    • 4

    style-loader将打包的样式文件通过style标签放入页面(body前面),css-loader打包时先处理css文件,然后style-loader将文件放到页面中

    链式调用,从后往前执行,数组中的顺序不能乱

    样式文件的抽离与压缩

    这个webpack5才支持有效,webpack4都不行

    npm i  mini-css-extract-plugin -D   2.42
    npm i css-minimizer-webpack-plugin -D    3.1.1
    
    • 1
    • 2

    mini-css-extract-plugin将css文件单独抽取出来,webpack默认是与js打包在一起的

    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
      plugins: [
        new MiniCssExtractPlugin({
          filename: "styles/[contenthash].css",
        }),
      ],
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
      {
        test: /\.(css|less)$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],
      },
    
    • 1
    • 2
    • 3
    • 4

    css-minimizer-webpack-plugin,用于css文件压缩

      const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin");
      optimization: {
         minimizer: [new CssMinimizerWebpackPlugin()],
      },
    
    • 1
    • 2
    • 3
    • 4

    四种资源文件

    1》asset/resource

    可以发送单独的一个文件,并导出url;

    两种设置打包的方式

    第一种方式:output配置中的assetModuleFilename

      output: {
        filename: "bundle.js",
        path: __dirname + "/test",
        clean: true,
        assetModuleFilename: "images/[contenthash][ext]", 
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    第二种方式:module中的module–rules–type、generator

      module: {
        rules: [
          {
            test: /\.jpg$/,
            type: "asset/resource",
            generator: {
              filename: "images/[contenthash][ext]",// 设置生成的目录即名称,根据文件名生成哈希值并保持原来的扩展名
            },
          },
        ],
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    第二种设置方式优先级高于第一种

    2》asset/inline

    导出一个资源的 data URI

            module: {
        rules: [
          {
            test: /\.jpg$/,
            type: "asset/resource",
            generator: {
              filename: "images/[contenthash][ext]",// 设置生成的目录即名称,根据文件名生成哈希值并保持原来的扩展名
            },
          },
        ],
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3》asset/source

    文本文件,比如我们的txt文件

      module: {
        rules: [
          {
            test: /\.txt$/,
            type: "asset/resource",
            generator: {
              filename: "images/[contenthash][ext]",// 设置生成的目录即名称,根据文件名生成哈希值并保持原来的扩展名
            },
          },
        ],
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4》asset

    通用资源,在导出一个资源data URI和发送一个单独的文件并导出URL之间做选择

    在inline和resource之间做选择,根据文件大小,自动决定是inline还是resource的打包方式

    font字体

    module:{
      rules:[{
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type:"asset/resource"
      }]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    json5

    json5文件和json很相似,可以当作json的升级版

    npm i json5 -D
    
    • 1
    const json5=require("json5")
    
    • 1
      {
        test: /\.json5$/,
        type: "json",
        parser: {
          parse: json5.parse,
        },
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    处理js

    es6代码处理

    因为有些老的浏览器不支持es6语法,所以我们要借助babel-load,将es6转为更低版本的es语法

    npm i babel-loder @babel/core @babel/presest-env -D
    
    • 1

    babel-loder: 解析es6的桥梁

    @babel/core:babel核心模块,babel-loader必须搭配它才能发挥作用

    @babel/presest-env: babel预设,一些babel插件的集合

      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"],
          },
        },
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    此时打包报错 regeneratorRuntime is not defined,原因是我们使用了promise,而转换它我们需借助其他插件

    npm i @babel/runtime -D
    npm i @babel/plugin-transform-runtime -D
    
    • 1
    • 2

    修改下配置

      {
       test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"],
            plugins: [["@babel/plugin-transform-runtime"]],
          },
        },
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    生产环境下js的压缩

    webpack5已内置,只需引入,添加配置

    npm i terser-webpack-plugin -D  // 由于webapack5已经内置这个插件了,所以不需要重新安装了
    
    • 1
    const TerserPlugin=require("terser-webpack-plugin")
        optimization:{
            minimizer:{
                 new TerserPlugin()
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    代码分离

    方法1:使用entry配置手动分离代码

    问题:公共的引用会被打包到不同的chunk,那么将导致重复的引用重复打包,而且包体积变大

      entry: {
        index: "./src/index.js",
        es6: "./src/es6.js",
        sameJs: "./src/sameModule.js",
      },
      output:{
        filename: "[name].bundle.js",
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    我们多个js文件打包,如果有相同的引用,那么会导致重复的打包

    方法2:使用Entry dependencies或者SplitChunksPlugin

    打包后多出一个chunk,是公共的lodash,不会重复

    写法1:

    entry: {
      index: {
        import: "./src/index.js",
        dependOn: "shared",
      },
      es6: "./src/es6.js",
      sameJs: {
      import: "./src/sameModule.js",
      dependOn: "shared",
      },
      shared: "lodash",
    }
    output:{
        filename: "[name].bundle.js",
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    写法2:splitChunks

    entry: {
      index: "./src/index.js",
      es6: "./src/es6.js",
      sameJs: "/src/sameModule.js",
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5

    module中添加配置:

    optimization: {
       minimizer: [new CssMinimizerWebpackPlugin()],
       splitChunks: {
        chunks: "all",
       },
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    方法3:通过模块化的内联函数调用来分离代码

    懒加载、按需加载

    预热加载模块

    缓存

    配置输出文件的重命名

    如果我们在打包输出的时候,更改了文件内容,而打包的文件名没有改,那么浏览器会走缓存,然后内容不会即使地得到更新,所以我们需要在打包时对修改了内容的文件重命名

      output: {
        filename: "[name].[contenthash].js"
    }
    
    • 1
    • 2
    • 3

    这种中括号表示不是写死的,contenthash如果文件内容发生变化,那么contenthash就会改变,否则是不会变的

    缓存第三方库

      optimization: {
        splitChunks: {
          chunks: "all",
          cacheGroups: {
            vendor: {
              test: /[\\/]node_modules[\\/]/,
              name: "vendors",
              chunks: "all",
            },
          },
        },
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    的文件名没有改,那么浏览器会走缓存,然后内容不会即使地得到更新,所以我们需要在打包时对修改了内容的文件重命名

      output: {
        filename: "[name].[contenthash].js"
    }
    
    • 1
    • 2
    • 3

    这种中括号表示不是写死的,contenthash如果文件内容发生变化,那么contenthash就会改变,否则是不会变的

    缓存第三方库

      optimization: {
        splitChunks: {
          chunks: "all",
          cacheGroups: {
            vendor: {
              test: /[\\/]node_modules[\\/]/,
              name: "vendors",
              chunks: "all",
            },
          },
        },
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    乌鸦喝水之谜
    Impala中replace和translate的用法和区别
    【Swift-Vapor服务器】0002、Swift-Vapor的基本使用-搭建一个属于自己歌曲的API
    下一代英伟达H100 GPU发布时,国产芯片能追上吗?
    AUTOSAR汽车电子嵌入式编程精讲300篇-基于 FIFO 和优先级序列 CAN 总线系统(续)
    K8s: 集群内Pod通信机制之DNS
    大语言模型比武
    03-瑞吉外卖关于菜品/套餐分类表的增删改查
    SoftwareTest8 - 怎样测试一个系统的性能 ?
    手把手教你搭建python+selenium自动化环境
  • 原文地址:https://blog.csdn.net/weixin_50576800/article/details/124911095