webpack


webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具
【 静态模块打包工具:将多个模块(JavaScript、CSS、图片等)打包到一个或多个输出文件中的工具。通过对模块进行静态分析和转换,可以有效地管理模块之间的依赖关系、进行代码优化和资源处理。打包后的输出内容被认为成 静态资源

打包方式

wepack会以一个或多个文件作为打包的入口,将我们整个项目所有文件编译组合成一个或多个文件输出出去。
当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles(包),它们均为静态资源,用于展示你的内容。

为什么打包

我们会用各种语言进行开发,但是浏览器智能只能html、js、css。通过打包可以将我们的开发语言转换成浏览器识别的语言。

打包的功能:

  • 编译:将开发语言转换成浏览器能够识别的语言
  • 压缩:打包后的文件体积减小,可以提高网页的加载速度
  • 多个文件合并成一个文件:打包后合并成一个文件,页面只需请求一次,这样能在一定程度上提升页面渲染效率
  • 缓存静态资源:可以指定打包文件中的静态资源路径为CDN的域名,将这些资源上传到CDN上,从而实现cdn缓存

配置文件

weback的一个重点内容就是通过各种配置将各种语言编译成浏览器能够解析的语言。
从 v4.0.0 开始,webpack 可以不用再引入一个配置文件来打包项目。传统的方式是指定一个配置文件webpack.config.js进行打包。

webpack的配置文件一般名为:webpack.config.js ,同时不同的开发模式下可以配置不同的打包文件,不同模式下调用不同的文件进行打包,开发模式的配置文件一般名为: webpack.config.dev.js;生产模式的配置文件一般名为: webpack.config.prod.js

开发模式

webpack.config.dev.js

const path = require("path")//nodejs核心模块主要用于处理路径问题
//引入eslint插件
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
// 引入HtmlWebpack插件
const HtmlWebpackPlugin = require("html-webpack-plugin");
// loader:直接下载对应的包就可以使用
// plugins:下载对应的包后需要引入使用

module.exports = {
    //入口
    entry: "./src/main.js",//相对路径
    //输出
    output: {
        //文件的输出路径(默认输出目录:dist)
        // path.resolve()方法返回一个绝对路径
    	// __dirname 当前文件的文件夹绝对路径
        path: path.resolve(__dirname, "dist"),//绝对路径
        //文件名
        filename: "static/js/main.js",
        clean: true, // 自动将上次打包目录资源清空
        /*打包输出目录:
        ├── dist
		   └── static
		         ├── imgs
		         │    └── 7003350e.png
		         └── js
		              └── main.js
        */
            }
    // 加载器
    module: {
        rules: [
            //loader的配置
			//--------------样式start----------
			  //css文件处理
			  {
		        test: /\.css$/,
		        // use 数组里面 Loader 执行顺序是从右到左
		        use: ["style-loader", "css-loader"],
		      },
		       //less文件处理
		      {
		        test: /\.less$/,
		        use: ["style-loader", "css-loader", "less-loader"],
		      },
		       //sass文件处理
		      {
		        test: /\.s[ac]ss$/,
		        use: ["style-loader", "css-loader", "sass-loader"],
		      },
		      //styl文件处理
		      {
		        test: /\.styl$/,
		        use: ["style-loader", "css-loader", "stylus-loader"],
		      },
		      //--------------样式end----------
		      //--------------图片start----------
		      {
		        test: /\.(png|jpe?g|gif|webp)$/,
		        type: "asset",
		        // “asset” 相当于url-loader, 将文件转化成 Webpack 能识别的资源,同时小于某个大小的资源会处理成 data URI 形式
		        parser: {
		          dataUrlCondition: {
		            //转换成base64,优点:减少请求数量  缺点:体积会变大
		            maxSize: 10 * 1024 // 小于10kb的图片会被base64处理
		          }
		        },
		        generator: {
		          // 将图片文件输出到 static/imgs 目录中
		          // 将图片文件命名 [hash:8][ext][query]
		          // [hash:8]: hash值取8位
		          // [ext]: 使用之前的文件扩展名
		          // [query]: 添加之前的query参数
		          filename: "static/imgs/[hash:8][ext][query]",
		        },
		        
		      },
		      //--------------图片end----------
		      //--------------字体start----------
			  {
		      //处理字体图标资源
		        test: /\.(ttf|woff2?)$/,
		        type: "asset/resource",
		        //“asset/resource” 相当于file-loader, 将文件转化成 Webpack 能识别的资源,其他不做处理
		        generator: {
		          filename: "static/media/[hash:8][ext][query]",
		        },
		      },
		      //--------------字体end----------
		      //--------------其他文件start---------
		      {
		        test: /\.(map4|map3|avi)$/,
		        type: "asset/resource",
		        generator: {
		          filename: "static/media/[hash:8][ext][query]",
		      },
		      //--------------其他文件end----------
		      //--------------js代码兼容性处理(babel,需要配置对应的babel文件)---------
		      {
		        test: /\.js$/,
		        exclude: /node_modules/, // 排除node_modules代码不编译
		        loader: "babel-loader",
		      },
		      //--------------js代码兼容性处理end---------
        ],
    },
    // 插件
    plugins: [
        // plugins的配置
        //----------代码格式Eslint配置start(需要配置对应的eslint文件)-----------
         new ESLintWebpackPlugin({
	     // 指定eslint检查文件的根目录
	      context: path.resolve(__dirname, "src"),
	    }),
	    //----------代码格式Eslint配置end-----------
	    //-------------html资源start----------------
	    // 我们可以将打包好的内容直接注入到某个html文件中,这样html文件就无需引入我们所写的js文件
	    new HtmlWebpackPlugin({
	      // 以 public/index.html 为模板创建文件
	      // 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
	      template: path.resolve(__dirname, "public/index.html"),
	    }),
	    //-------------html资源end----------------
	    
    ],
    // 模式
    mode: "development",
    hot: true, // 开启HMR功能(修改某个模块代码,就只有这个模块代码需要重新打包编译,其他模块不变,这样打包速度就能很快)
}

生产模式

相比于开发模式来讲,生产模式的一些打包规则更注重用户体验:

  • 白屏现象:
    使用"style-loader"的时候,css 文件被打包到 js 文件中是以style 标签来生成样式的,这样对于网站来说,会出现 闪屏现象,用户体验不好。最好使用单独的 Css 文件,link标签加载,此时我们就需要使用mini-css-extract-plugin
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
  • css样式不兼容问题
    postcss-preset-env能解决大多数样式兼容性问题
npm i postcss-loader postcss postcss-preset-env -D
  • 压缩
    样式文件压缩 npm i css-minimizer-webpack-plugin -D
    webpack 默认生产模式已经开启了:html 压缩和 js 压缩,不需要额外进行配置

webpack.config.prod.js

const path = require("path");
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

module.exports = {
  entry: "./src/main.js",
  output: {
    path: path.resolve(__dirname, "../dist"), // 生产模式需要输出
    filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
    clean: true,
  },
  module: {
    rules: [
      {
        // 用来匹配 .css 结尾的文件
        test: /\.css$/,
        // use 数组里面 Loader 执行顺序是从右到左
        use: [MiniCssExtractPlugin.loader, "css-loader",
	          {
	            loader: "postcss-loader",
	            options: {
	              postcssOptions: {
	                plugins: [
	                  "postcss-preset-env", // 能解决大多数样式兼容性问题
	                ],
	              },
	            },
	          },
          ],
      },
      {
        test: /\.less$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", 
        {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  "postcss-preset-env", // 能解决大多数样式兼容性问题
                ],
              },
            },
          },
       "less-loader"],
      },
      {
        test: /\.s[ac]ss$/,
        use: [MiniCssExtractPlugin.loader, "css-loader",
        {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  "postcss-preset-env", // 能解决大多数样式兼容性问题
                ],
              },
            },
          },
       "sass-loader"],
      },
      {
        test: /\.styl$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", 
        {
            loader: "postcss-loader",
            options: {
              postcssOptions: {
                plugins: [
                  "postcss-preset-env", // 能解决大多数样式兼容性问题
                ],
              },
            },
          },
        "stylus-loader"],
      },
      {
        test: /\.(png|jpe?g|gif|webp)$/,
        type: "asset",
        parser: {
          dataUrlCondition: {
            maxSize: 10 * 1024, // 小于10kb的图片会被base64处理
          },
        },
        generator: {
          // 将图片文件输出到 static/imgs 目录中
          // 将图片文件命名 [hash:8][ext][query]
          // [hash:8]: hash值取8位
          // [ext]: 使用之前的文件扩展名
          // [query]: 添加之前的query参数
          filename: "static/imgs/[hash:8][ext][query]",
        },
      },
      {
        test: /\.(ttf|woff2?)$/,
        type: "asset/resource",
        generator: {
          filename: "static/media/[hash:8][ext][query]",
        },
      },
      {
        test: /\.js$/,
        exclude: /node_modules/, // 排除node_modules代码不编译
        loader: "babel-loader",
      },
    ],
  },
  plugins: [
    new ESLintWebpackPlugin({
      // 指定检查文件的根目录
      context: path.resolve(__dirname, "../src"),
    }),
    new HtmlWebpackPlugin({
      // 以 public/index.html 为模板创建文件
      // 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
      template: path.resolve(__dirname, "../public/index.html"),
    }),
    // css压缩
    new CssMinimizerPlugin(),
  ],
  // devServer: {
  //   host: "localhost", // 启动服务器域名
  //   port: "3000", // 启动服务器端口号
  //   open: true, // 是否自动打开浏览器
  // },
  mode: "production",
};

webpack的优化配置

参照这里:https://blog.youkuaiyun.com/mantou_riji/article/details/125998059

打包命令

配置好webpack的文件之后就可以通过该配置文件进行项目的打包了。
格式: webpack --config 配置文件

eg:

webpack --config ./webpack.config.js

在package.json文件中配置打包命令

配置运行指令
为了方便运行不同模式的指令,我们将指令定义在 package.json 中 scripts 里面。
package.json

{
  // 其他省略
  "scripts": {
    "start": "npm run dev",
    "build:dev": "webpack serve --config ./config/webpack.dev.js",
    "build:prod": "webpack --config ./config/webpack.prod.js"
  }
}

以后打包指令:

开发模式:npm run dev
生产模式:npm run build

打包命令的参数

大部分可以参数直接在配置文件中配置。

  1. --config <config>:指定使用的配置文件,默认为 webpack.config.js。
  2. --mode <mode>:指定打包的模式,可选的值有 development 和 production
  3. --entry <entry>:指定入口文件。
  4. --output <output>:指定输出文件的路径和文件名。
  5. --watch:监视文件改动并实时重新编译。
    示例:
npx webpack --watch

使用 --watch 参数时,webpack会监视配置文件和入口文件以及它们所依赖的文件的变化,并在这些文件有修改时重新编译。

配置文件: webpack.config.js
入口文件:通过配置文件指定的入口文件
所依赖的文件:如果在配置文件中定义了其他文件的依赖,webpack也会监视这些依赖文件,如样式文件、模板文件、自定义模块等。
webpack会检测通过配置文件显式指定或间接引用的文件变化
6. --devtool <devtool>:用于指定生成 source map 的方式(即打包后的代码和打包前的代码之间的映射方式),以方便在调试过程中定位源代码。

示例:npx webpack --devtool source-map

几种取值:

  • source-map:生成独立的 Source Map 文件(.map文件)。
    当使用 devtool 配置项设置为 source-map 时,Webpack 会生成独立的 Source Map 文件(.map 文件),其将打包前后的代码关联起来。这样,在浏览器的开发者工具中,当出现代码问题时,会显示真实的源码位置,而不是打包后的代码位置。
    但是source-map会增加构建时间和构建大小,所以在生产环境下,通常会将 devtool 设置为 cheap-module-source-map 或 hidden-source-map,以提高性能并降低生成的 Source Map 文件的大小。
  • cheap-module-source-map:生成 Source Map 文件,但不包含列信息
  • eval-source-map:每个模块都使用 eval 执行,并生成 Source Map 数据,最快但不支持调试转换后的代码。
  • cheap-module-eval-source-map:组合使用 cheap-module 和 eval 执行方式,生成 Source Map 数据。
  • cheap-module-inline-source-map:以行内的方式生成 Source Map 数据,可以定位源文件内容(行和列)。相比于source-map具有较好的性能,适用于开发环境中进行调试。但这种方式的 Source Map 数据相对简单,可能对于复杂的转换和加载器链可能不够准确。因此,在生产环境中不建议使用这种方式生成 Source Map。

也可以在配置文件中配置:

module.exports = {
  // 其他省略
  mode: "development",
  devtool: "cheap-module-source-map",
};
  1. --module-bind <module>:指定特定类型文件的加载器。
    示例
npx webpack --module-bind css=style-loader!css-loader js=babel-loader 
  1. npx webpack --help 命令查看所有的可用命令参数及其说明。

webpack的非文件配置

vue.config.js中配置webpack

如果您不想单独设置一个文件来配置webpack,Vue CLI提供了一个默认的配置文件,可以在项目根目录中的vue.config.js文件中进行配置。

在vue.config.js文件中,可以使用module.exports导出一个包含配置选项的对象。在module.exports对象中添加不同的配置选项。
以下是一些常见的配置选项示例:

  • publicPath:指定应用程序所在的基本 URL。在开发环境和生产环境中,将使用不同的值。
  • outputDir:指定构建输出的目录,默认为dist。
  • devServer:配置开发服务器的行为,比如设置监听的端口和代理等。
  • configureWebpack:用于修改webpack的配置对象,可以通过此选项添加额外的webpack插件或自定义配置。
    以下是一个示例配置:
module.exports = {
  publicPath: process.env.NODE_ENV === 'production' ? '/my-app/' : '/',
  outputDir: 'dist',
  devServer: {
    port: 8080,
    proxy: {
    //代理地址
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true
      }
    }
  },
  configureWebpack: {
    plugins: [
      // 添加自定义的插件
      new MyCustomPlugin()
    ]
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值