sssong123

 

webpack基础

简介:

Webpack 是一个静态资源打包工具。

以一个或多个文件作为打包的入口,将我们整个项目所有文件编译组合成一个或多个文件输出出去。输出的文件就是编译好的文件,就可以在浏览器段运行了。

一、基本使用

  • 在项目根目录,初始化 package.json文件。此时会生成一个基础的 package.json 文件。

    需要注意的是 package.json 中 name 字段不能叫做 webpack, 否则下一步会报错

npm init -y
  • 下载依赖
// webpack 主文件
// webpack-cli 指令
// -D  下载到开发依赖包
npm i webpack webpack-cli -D
  • 启动 Webpack
    • 开发模式
npx webpack ./src/main.js --mode=development
    • 生产模式
npx webpack ./src/main.js --mode=production

注意:

  • npx webpack:是用来运行本地安装 Webpack 包的
  • ./src/main.js:指定 Webpack 从 main.js 文件开始打包,不但会打包 main.js,还会将其依赖也一起打包进来。
  • --mode=xxx:指定模式(环境)。
  • 默认 Webpack 会将文件打包输出到 dist 目录下
  • 但只能处理 js 资源

二、基本配置

通过 webpack.config.js 文件进行配置,来增强 Webpack 的功能

五大核心概念:

const path = require("path");

module.exports = {
    // 【入口】
    entry: './src/main.js',  //相对路径
    // 【输出】
    output: {
        // 文件的输出位置
        path: path.resolve(__dirname, "dist"), // 绝对路径
        // 文件名
        filename: 'main.js',
    },
    // 【加载器】。数组是复数加s,对象是单数不加s
    module: {
        rules: [
            // loader的配置
        ]
    },
    // 【插件】
    plugins: [
        // plugin的配置
    ],
    // 【模式】
    mode: "development"
}

三、处理样式资源

 Webpack 可以处理 Css、Less、Sass、Scss、Styl 样式资源

我们找 Loader 都应该去官方文档中找到对应的 Loader,然后使用官方文档找不到的话,可以从社区 Github 中搜索查询

Webpack 官方 Loader 文档

注意:想要 webpack 打包资源,必须引入该资源

例如:在main.js中引入css资源

import "./css/index.css";
只要配置了webpack.config.js 配置文件,运行指令:
npx webpack

 

1、处理 css 资源

  • 依赖
    // css-loader:负责将 Css 资源编译成 Webpack 能识别的common.js模块
    // style-loader 将 js中css通过创建 style标签添加html文件中生效
    npm i css-loader style-loader -D
  • 配置
    // 加载器。数组是复数加s,对象是单数不加s
        module: {
            rules: [   // loader的配置
                {  /* 处理css */
                    test: /\.css$/,  //只检测 .css文件
                    use: [  //  下面这些包的执行顺序,从下到上
                        "style-loader", // 将 js中css通过创建 style标签添加html文件中生效
                        "css-loader"  // 将 css资源编译成common.js的模块到js中
                    ],
                },
            ]
        },

2、处理 less资源

  • 依赖
    // less-loader:负责将 Less 文件编译成 Css 文件
    npm i less-loader style-loader css-loader -D
  • 配置
    // 加载器。数组是复数加s,对象是单数不加s
    module: {
        rules: [   // loader的配置
            {  /* 处理 less */
                 test: /\.less$/,  //只检测 .less文件
                 use: [  // 下面这些包的执行顺序,从下到上
                      "style-loader", // 将 js中css通过创建 style标签添加html文件中生效
                      "css-loader",  // 将 css资源编译成common.js的模块到js中
    "less-loader", ], }, ] },

3、处理 Sass 和 Scss资源

  • 依赖
    // sass-loader:负责将 Sass 文件编译成 css 文件
    // sass:sass-loader 依赖 sass 进行编译
    npm i sass-loader sass -D
  • 配置
    module: {
        rules: [   // loader的配置
            {  /* 处理 scss  sass*/
                 test: /\.s[ac]ss$/,  //只检测 .scss 和 .sass文件
                 use: [  // 下面这些包的执行顺序,从下到上
                      "style-loader", 
                      "css-loader", 
                      "sass-loader",  
                 ],
            },
        ]
    },

4、处理 styl 资源

  • 依赖
    npm i stylus-loader -D
  • 配置
    module: {
        rules: [   // loader的配置
            {   /* 处理stylus。 文件后缀名为 styl */
                 test: /\.styl$/,   //只检测 .styl 文件
                 use: [   // 下面这些包的执行顺序,从下到上
                      "style-loader", 
                      "css-loader", 
                      "stylus-loader",  
                 ],
            },
        ]
    },

四、处理图片,图标字体等其它资源

module: {
        rules: [
            {  // 处理图片资源
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                type: 'asset', // 转 base64
                parser: {  // 转 base64 的配置
                    dataUrlCondition: {
                        // 小于30kb的图片转 base64:
                        /* 优点:减少请求数量,降低服务器压力   缺点:体积会变大 */
                        maxSize: 30 * 1024 // 4kb
                    }
                },
                generator:{
                    // 输出图片名称:
                    /* [hash]:hash值,图片的ID,唯一的。 [hash:8]:hash值只取8位,图片的ID,不能有空格
                       [ext]:文件扩展名
                       [query]:携带参数
                     */
                    filename: "images/[hash:10][ext][query]"
                }
            },
            {  // 处理图标字体资源,和其它资源,例如视频啥的等
                test: /\.(ttf|woff2?|map3|map4|avi)$/, 
                type: 'asset/resource',  // 对文件原封不动的输出,不会转base64格式
                generator:{
                    // 输出图片名称:
                    /* [hash]:hash值,图片的ID,唯一的。 [hash:8]:hash值只取8位,图片的ID,不能有空格
                       [ext]:文件扩展名
                       [query]:携带参数
                     */
                    filename: "media/[hash:10][ext][query]"
                }
            }
        ]
    },

 

五、修改输出的文件目录

  • 在输出核心模块中设置主文件输出的位置
    // 输出
        output: {
            // 文件的输出位置
            path: path.resolve(__dirname, "dist"), // 绝对路径
            // 文件名
            filename: 'js/main.js',
            // 打包前,自动清空上次打包的内容,
            clean: true
        },
  • 增加 generator 配置,设置图片,图片等文件的输出目录
    module: {
            rules: [
                { 
                    test: /\.(png|jpe?g|gif|webp|svg)$/,
                    type: 'asset', // 转 base64
                    parser: {  // 转 base64 的配置
                        dataUrlCondition: {
                            maxSize: 30 * 1024 //
                        }
                    },
                    generator:{
                        // 输出图片名称:
                        /* [hash]:hash值,图片的ID,唯一的。 [hash:8]:hash值只取8位,图片的ID,不能有空格
                           [ext]:文件扩展名
                           [query]:携带参数
                         */
                        filename: "images/[hash:10][ext][query]"
                    }
                },
                {  // 处理图标字体资源,和其它资源,例如视频啥的等
                    test: /\.(ttf|woff2?|map3|map4|avi)$/, 
                    type: 'asset/resource',  // 对文件原封不动的输出,不会转base64格式
                    generator:{
                        // 输出图片名称:
                        /* [hash]:hash值,图片的ID,唯一的。 [hash:8]:hash值只取8位,图片的ID,不能有空格
                           [ext]:文件扩展名
                           [query]:携带参数
                         */
                        filename: "media/[hash:10][ext][query]"
                    }
                }
            ]
        },

六、处理 js 资源

Webpack 对 js 处理是有限的,只能编译 js 中 ES 模块化语法。不能编译其他语法,导致 js 不能在 IE 等浏览器运行,所以我们希望做一些兼容性处理。

其次开发中,团队对代码格式是有严格要求的,我们不能由肉眼去检测代码格需要使用专业的工具来检测。

    • 针对 js 兼容性处理,我们使用 Babel 来完成
    • 针对代码格式,我们使用 Eslint 来完成

我们先完成 Eslint,检测代码格式无误后,在由 Babel 做代码兼容性处理

1、Eslint

可组装的 JavaScript 和 JSX 检查工具。

这句话意思就是:它是用来检测 js 和 jsx 语法的工具,可以配置各项功能

我们使用 Eslint,关键是写 Eslint 配置文件,里面写上各种 rules 规则,将来运行 Eslint 时就会以写的规则对代码进行检查

  • 配置文件的方式
    // 方式一: 新建文件,位于项目根目录。以下三种配置方式任选一个
    .eslintrc
    .eslintrc.js
    .eslintrc.json
    区别在于配置格式不一样
    // 方式二 package.json 中 eslintConfig:不需要创建文件,在原有文件基础上写
    ESLint 会查找和自动读取它们,所以以上配置文件只需要存在一个即可
  • 在webpack 用法:
    • 下载插件
      npm install eslint-webpack-plugin eslint -D
    • 在根目录定义 Eslint 配置文件。我这使用 .eslintrc.js 方式
      module.exports = {
          // 继承 Eslint 规则
          extends: ["eslint:recommended"],
          env: { 
              node: true, // 启用node中全局变量
              browser: true, // 启用浏览器中全局变量
          },
          parserOptions: {
              ecmaVersion: 6,  // es6
              sourceType: "module",  // es module
          },
          rules: {
              "no-var": 2, // 不能使用 var 定义变量,不然报错
          },
      };
    • 在 webpack.config.js 文件中导入插件 
      const path = require("path");
      const ESLintWebpackPlugin = require("eslint-webpack-plugin");
      
      module.exports = {
          //  ...........
          plugins: [
              new ESLintWebpackPlugin({
                  // 指定检查src目录下的文件
                  context: path.resolve(__dirname, "src"),
              }),
          ], 
          //  ...........
      }
  • VScode 中有个 ESLint 插件,它会根据Eslint的配置项检测代码,并及时给出提示

注意:如果VScode安装了这个插件(ESLint:全局检查),点击编译后的dist文件会出现报错 !,

原因:编译后的代码不符合Eslint的配置。但打包后的dist目录是不需要检查的,

解决方案:在新目录中新建【.eslintignore】忽略文件。在文件里面,把需要忽略的文件目录写上去

 2、Babel

JavaScript 编译器。

主要用于将 ES6 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中

  • 配置文件的方式。Babel 会查找和自动读取它们,所以以下6种方法只需要存在一个即可
    // 方式一: 新建文件,位于项目根目录。
    babel.config.js
    babel.config.json
    // 方式二: 新建文件,位于项目根目录
    .babelrc
    .babelrc.js
    .babelrc.json
    // 方式三:
    package.json 中 babel:不需要创建文件,在原有文件基础上写
  • 具体配置:babel.config.js 配置文件为例
    module.exports = { // 都需要下载才能使用
        // @babel/preset-env:智能预设,能够编译ES6语法。可以把ES6语法编译成以前的旧语法
        // @babel/preset-react:一个用来编译 React jsx 语法的预设
        // @babel/preset-typescript:一个用来编译 TypeScript 语法的预设
        presets: ['@babel/preset-env','@babel/preset-typescript'] // presets:就是一组 Babel 插件, 扩展 Babel 功能 
    }

     

  • 在 webpack 的使用
    • 下载包
      // babel-loader:babel与webpack结合的工具(加载器)
      // @babel/core:babel核心包
      // @babel/preset-env:智能预设
      npm i babel-loader @babel/core @babel/preset-env webpack -D
    • 在webpack.config.js中使用
      module: {
              rules: [
                   {  /* 处理js文件 */
                      test: /\.js$/,  //只检测 .js文件
                      exclude: /node_modules/,  // 排除 node_modules中的js文件(这些文件不处理) 
                      loader: 'babel-loader',
                      // options: {   /* 也可以写在外部。在上面具体配置中简述了 */
                      //     presets: ['@babel/preset-env']
                      // }
                  }
              ]
          },

七、处理 html资源

官网文档:https://webpack.docschina.org/plugins/html-webpack-plugin/

该插件将为你生成一个 HTML5 文件, 在 body 中使用 script 标签引入你所有 webpack 生成的 bundle。 只需添加该插件到你的 webpack 配置中

  • 下载插件
    npm install --save-dev html-webpack-plugin
  • 基本用法:
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const path = require('path');
    
    module.exports = {
      entry: 'index.js',
      plugins: [
          // 生成 HTML页面并自动引入资源
            new HtmlWebpackPlugin({
                // 模板:以 public/index.html文件创建新的HTML文件
               /* 新的html文件的特点:1.结构一致,2自动引入打包输出的资源 */
                template: path.resolve(__dirname, "public/index.html")
            })
    ],
    };

八、开发服务器&自动化

webpack-dev-server会创建一个开发服务器,自动监视 src 目录下的文件,一旦发生变化自动重新打包。

1、下载包

npm i webpack-dev-server -D

 

2、配置 

  • webpack.config.js
    const path = require("path");
    
    module.exports = {// 【插件】
        plugins: [
        ],
        // 开发服务器:不会输出资源,在内存中编译打包的
        devServer: {
            host: "localhost", // 启动服务器域名
            port: "3000", // 启动服务器端口号
            open: true, // 是否自动打开浏览器
        },
        // 【模式】
        mode: "development"
    }

 

3、运行指令

npx webpack serve

注意运行指令发生了变化

并且当你使用开发服务器时,所有代码都会在内存中编译打包,并不会输出到 dist 目录下。

开发时我们只关心代码能运行,有效果即可,至于代码被编译成什么样子,我们并不需要知道。

 

九、生产模式的介绍

生产模式是开发完成代码后,我们需要得到代码将来部署上线。这个模式下我们主要对代码进行优化,让其运行性能更好。

从两个角度出发:

  • 优化代码运行性能
  • 优化代码打包速度

1、生产模式准备

  • 在根目录创建 config目录
  • 把之前的webpack.config.js文件保存一份,名称改为 webpack.dev.js(开发模式配置文件)并更改部分配置
    • 因为开发模式是没有输出的,不需要指定,它是在内存中编译的
    • 更改模式为 development
    • 因为是在根目录下运行项目的,所以绝对路径要回退到上一层(../)
      module.exports = {
          // 入口
          entry: './src/main.js',  //相对路径,因为是在最外层运行代码的,所以不要改
          // 输出
          output: {
              // path: path.resolve(__dirname, "../dist"), // 绝对路径,必要要回退下,到上一级目录
              /* 开发环境是没有输出的,不需要指定输出内容,因为是在内存中编译的 */
              path: undefined,
              // 文件名
              filename: 'js/main.js',
          },
          // 加载器。数组是复数加s,对象是单数不加s
          module: {
              rules: []
          },
          // 插件
          plugins: [],
          // 开发服务器:不会输出资源,在内存中编译打包的
          devServer: {
              host: "localhost", // 启动服务器域名
              port: "3000", // 启动服务器端口号
              open: true, // 是否自动打开浏览器
          },
          // 模式
          mode: "development"
      }

      // 运行开发模式的指令
      // webpack serve:启动webpack-dev-server配置(开发服务器)
      // --config:指定配置文件在哪里
      // ./config/webpack.dev.js:文件路径
      npx webpack serve --config ./config/webpack.dev.js
  • 把之前的webpack.config.js文件保存一份,名称改为 webpack.prod.js(生产模式配置文件)并更改部分配置

    • 因为开发模式是有输出的,需要指定输出内容
    • 更改模式为 production
    • 因为是在根目录下运行项目的,所以绝对路径要回退到上一层(../)
      const path = require("path");
      
      module.exports = {
          // 入口
          entry: './src/main.js',  //相对路径
          // 输出
          output: {
              // 文件的输出位置
              path: path.resolve(__dirname, "../dist"), // 绝对路径
              // 文件名
              filename: 'js/main.js',
              // 打包前,自动清空上次打包的内容,
              clean: true
          },
          // 加载器。数组是复数加s,对象是单数不加s
          module: {
              rules: []
          }
          // 插件
          plugins: [],
          // 模式
          mode: "production"
      }

      // 运行生产模式的指令
      // --config: 指定配置文件在哪里
      npx webpack --config ./config/webpack.prod.js
      //
       
       

2、配置运行指令

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

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

以后启动指令:

  • 开发模式npm start 或 npm run dev
  • 生产模式npm run build

 十、处理css

1、提取 Css 成单独文件

Css 文件目前被打包到 js 文件中,当 js 文件加载时,会创建一个 style 标签来生成样式。但对于网站来说,就会出现闪屏现象,用户体验不好,我们应该单独设立 Css 文件,通过 link 标签加载性能才好。

  •  下载包
    npm i mini-css-extract-plugin -D
  • webpack.prod.js 配置(生产环境)
    /* 【 把每一个 style-loader 改成 MiniCssExtractPlugin.loader】 */
    // 引入文件
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    
    module.exports = {
       module: {
            rules: [
                {  /* 处理css */
                    test: /\.css$/,  //只检测 .css文件
                    use: [  //  执行顺序,从下到上
                       // "style-loader", // 将 js中css通过创建 style标签添加html文件中生效
                       MiniCssExtractPlugin.loader, // 提取css成单独文件
                       "css-loader"  // 将 css资源编译成common.js的模块到js中
                    ],
                },
           ]
        },
        plugins: [
            // 提取css成单独文件
            new MiniCssExtractPlugin({
                filename: "css/index.css" //打包到dist目录下的输出路径
            })
        ],
    }

 

 

2、css 兼容性处理 

  • 下载包
    npm i postcss-loader postcss postcss-preset-env -D
  • 配置。注意:该配置项需要配置在 css-loader的后面,less-loader的前面
    module.exports = {
          // 加载器。数组是复数加s,对象是单数不加s
        module: {
            rules: [
                {  /* 处理css */
                    test: /\.css$/,  //只检测 .css文件
                    use: [  //  执行顺序,从下到上
                        MiniCssExtractPlugin.loader, // 提取css成单独文件
                        "css-loader",  // 将 css资源编译成common.js的模块到js中
                        {  // 该配置项,需要在 css-loader的后面
                            loader: "postcss-loader",
                            options: {
                                postcssOptions: {
                                    plugins: [
                                        "postcss-preset-env", // 能解决大多数样式兼容性问题
                                    ],
                                },
                            },
                        }
                    ],
                },
                {  /* 处理less */
                    test: /\.less$/,
                    use: [
                        MiniCssExtractPlugin.loader, // 提取css成单独文件
                        'css-loader',
                        {  // 该配置项,需要在 css-loader的后面,less-loader的前面
                            loader: "postcss-loader",
                            options: {
                                postcssOptions: {
                                    plugins: [
                                        "postcss-preset-env", // 能解决大多数样式兼容性问题
                                    ],
                                },
                            },
                        },
                        'less-loader',
                    ],
                }
          ]
       }
    }
  • 在 package.json 文件中添加 browserslist 来控制样式的兼容性做到什么程度。
    /* 例1 */
    {
      // 其他省略
      "browserslist": ["ie >= 8"]  // IE8或以上
    }
    
    /* 例2 */
     "browserslist":[
        "last 2 version",   // 所有浏览器最近的两个版本
        "> 1%",       // 覆盖99%的浏览器
        "not dead"   //  浏览器版本弃用了的,也不要
      ]

3、封装配置(合并配置)

// 用来获取处理样式的loader
function getStyleLoader(pre) {
    return [  //  执行顺序,从下到上
        MiniCssExtractPlugin.loader, // 提取css成单独文件
        "css-loader",  // 将 css资源编译成common.js的模块到js中
        {  // 该配置项,需要在 css-loader的后面
            loader: "postcss-loader",
            options: {
                postcssOptions: {
                    plugins: [
                        "postcss-preset-env", // 能解决大多数样式兼容性问题
                    ],
                },
            },
        },
        pre
    ].filter(Boolean)   //把pre为unidentified的值过滤掉
}


module.exports = {
     rules: [
            // loader的配置
            {  /* 处理css */
                test: /\.css$/,  //只检测 .css文件
                use: getStyleLoader()
            },
            {  /* 处理less */
                test: /\.less$/,
                use: getStyleLoader("less-loader")
            },
            {  /* 处理stylus。 文件后缀名是styl */
                test: /\.styl$/,
                use: getStyleLoader("stylus-loader")
            }
     ]
}

 

 

 4、css 压缩

  • 下载包
    npm i css-minimizer-webpack-plugin -D
  • 配置
    const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
    
    module.exports = {
        // 插件
        plugins: [
            // css压缩
            new CssMinimizerPlugin(),
        ],
       
        // 模式
        mode: "production"
    }

5、html 压缩

默认生产模式已经开启了:html 压缩和 js 压缩,不需要额外进行配置

十一、总结

本篇文章详解了 Webpack5 基本使用,掌握了以下功能:

  1. 两种开发模式
  • 开发模式:代码能编译自动化运行
  • 生产模式:代码编译优化输出
  1. Webpack 基本功能
  • 开发模式:可以编译 ES Module 语法
  • 生产模式:可以编译 ES Module 语法,压缩 js 代码
  1. Webpack 配置文件
  • 5 个核心概念
    • entry
    • output
    • loader
    • plugins
    • mode
  • devServer 配置
  1. Webpack 脚本指令用法
  • webpack 直接打包输出
  • webpack serve 启动开发服务器,内存编译打包没有输出

文章参考:尚硅谷课件

 

posted on 2022-10-23 19:24  叫兽~  阅读(53)  评论(0)    收藏  举报

导航