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

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

webpack5从零开始,上手基础知识 一、安装、认识webpack

安装

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

npm install webpack webpack-cli --global
npm i webpack webpack-cli -D

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

第二种是在项目中安装

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

npx webpack --version

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

    "webpack": "^5.72.1",
    "webpack-cli": "^4.9.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  // 监听文件变化,保存时有变化就会自动打包

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

npx webpack-dev-server
npx webpack-dev-server --open  // 自动打开浏览器
npm run serve                  // 就相当于执行了npx webpack-dev-server
新建一个项目,利用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",
};

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

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

const HtmlWebpackPlugin = require("html-webpack-plugin");
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html",  // 模板是哪个html文件
      filename: "index.html",  // 打包后生成的html文件名称
      inject: "body",  // js文件的位置,这里放入了body标签中
    }),
  ],
处理css、less等样式文件(打包压缩)

样式文件的打包

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

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

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

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

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

  const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin");
  optimization: {
     minimizer: [new CssMinimizerWebpackPlugin()],
  },
四种资源文件

1》asset/resource

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

两种设置打包的方式

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

  output: {
    filename: "bundle.js",
    path: __dirname + "/test",
    clean: true,
    assetModuleFilename: "images/[contenthash][ext]", 
  },

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

  module: {
    rules: [
      {
        test: /\.jpg$/,
        type: "asset/resource",
        generator: {
          filename: "images/[contenthash][ext]",// 设置生成的目录即名称,根据文件名生成哈希值并保持原来的扩展名
        },
      },
    ],
  }

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

2》asset/inline

导出一个资源的 data URI

        module: {
    rules: [
      {
        test: /\.jpg$/,
        type: "asset/resource",
        generator: {
          filename: "images/[contenthash][ext]",// 设置生成的目录即名称,根据文件名生成哈希值并保持原来的扩展名
        },
      },
    ],
  }

3》asset/source

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

  module: {
    rules: [
      {
        test: /\.txt$/,
        type: "asset/resource",
        generator: {
          filename: "images/[contenthash][ext]",// 设置生成的目录即名称,根据文件名生成哈希值并保持原来的扩展名
        },
      },
    ],
  }

4》asset

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

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

font字体
module:{
  rules:[{
    test: /\.(woff|woff2|eot|ttf|otf)$/i,
    type:"asset/resource"
  }]
}
json5

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

npm i json5 -D
const json5=require("json5")
  {
    test: /\.json5$/,
    type: "json",
    parser: {
      parse: json5.parse,
    },
  },
处理js

es6代码处理

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

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

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"],
      },
    },
  },

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

npm i @babel/runtime -D
npm i @babel/plugin-transform-runtime -D

修改下配置

  {
   test: /\.js$/,
    exclude: /node_modules/,
    use: {
      loader: "babel-loader",
      options: {
        presets: ["@babel/preset-env"],
        plugins: [["@babel/plugin-transform-runtime"]],
      },
    },
  },

生产环境下js的压缩

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

npm i terser-webpack-plugin -D  // 由于webapack5已经内置这个插件了,所以不需要重新安装了
const TerserPlugin=require("terser-webpack-plugin")
    optimization:{
        minimizer:{
             new TerserPlugin()
        }
    }
代码分离

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

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

  entry: {
    index: "./src/index.js",
    es6: "./src/es6.js",
    sameJs: "./src/sameModule.js",
  },
  output:{
    filename: "[name].bundle.js",
  }

我们多个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",
}

写法2:splitChunks

entry: {
  index: "./src/index.js",
  es6: "./src/es6.js",
  sameJs: "/src/sameModule.js",
},

module中添加配置:

optimization: {
   minimizer: [new CssMinimizerWebpackPlugin()],
   splitChunks: {
    chunks: "all",
   },
},

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

懒加载、按需加载

预热加载模块

缓存

配置输出文件的重命名

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

  output: {
    filename: "[name].[contenthash].js"
}

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

缓存第三方库

  optimization: {
    splitChunks: {
      chunks: "all",
      cacheGroups: {
        vendor: {
          test: /[\/]node_modules[\/]/,
          name: "vendors",
          chunks: "all",
        },
      },
    },
  },

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

  output: {
    filename: "[name].[contenthash].js"
}

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

缓存第三方库

  optimization: {
    splitChunks: {
      chunks: "all",
      cacheGroups: {
        vendor: {
          test: /[\/]node_modules[\/]/,
          name: "vendors",
          chunks: "all",
        },
      },
    },
  },

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1321093.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-11
下一篇2022-06-11

发表评论

登录后才能评论

评论列表(0条)

    保存