前端工程化第三章:webpack5基础(下)

文章目录

  • 1. TypeScript支持(ts-loader)
    • 1.1. ts-loader
      • 1.1.1. webpack.config.js
      • 1.1.2. tsconfig.json
      • 1.1.3. src/index.ts
    • 1.2. 使用babel-loader将ts转换为js
      • 1.2.1. webpack.config.js
      • 1.2.2. src/index.ts
  • 2. 代码规范检查(Eslint)
    • 2.1. webpack.config.js
    • 2.2. .eslintrc
    • 2.3. src/index.ts
  • 3. 图片处理(png/jpg/gif/svg等)
    • 3.1. asset模块
      • 3.1. webpack.config.js
      • 3.1.2. .eslintrc
      • 3.1.3. src/index.js
    • 3.2. 图片压缩(优化)
      • 3.2.1. 安装 `image-webpack-loader`
      • 3.2.2. webpack.config.js
    • 3.3. 响应式图片
      • 3.3.1. 安装
      • 3.3.2. webpack.config.js
      • 3.3.3. src/index.js
    • 3.4. 雪碧图
      • 3.4.1. 安装
      • 3.4.2. src/images/icons
      • 3.4.3. webpack.config.js
      • 3.4.4. src/index.js
      • 3.4.5. icon.less

1. TypeScript支持(ts-loader)

TypeScript 是一种静态类型的编程语言,是 JavaScript 的一个超集。它由 微软开发,提供了许多 JavaScript 不支持的功能,比如类型检查接口和类

1.1. ts-loader

ts-loaderWebpack 中的一个加载器,用于将 TypeScript 代码转换成 JavaScript 代码。它是基于 typescript 编译器实现的,支持所有 TypeScript 的语法和特性,可以帮助开发者在 Webpack 中使用 TypeScript 进行开发。

1.1.1. webpack.config.js

将入口文件改为index.ts, 在module中配置ts-loader:

前端工程化第三章:webpack5基础(下)_第1张图片
具体代码如下

const path = require("path"); // nodeJs 的 path 模块
const HtmlWebpackPlugin = require("html-webpack-plugin"); // 生成html的插件,并自动将打包后的 JS、CSS 文件引入 HTML 文件中
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 将css代码从js文件中拆分出来

module.exports = {
  mode: "development", // 模式为开发模式
  devtool: false, // 不生成sourcemap
  entry: "./src/index.ts", // entry:默认的路径是src/index.js,也可以自定义
  output: {
    path: path.resolve(__dirname, "dist"), // 打包文件的输出位置
    filename: "main.js", // 打包后的文件名
    clean: true, // 在新的打包之前清除历史文件
  },
  devServer: {
    static: path.join(__dirname, "public"), // 静态资源路径
    compress: true, // 是否开始gzip压缩
    host: "localhost", // 服务器主机名
    port: 80, // 服务器端口名
    open: true, //启动项目后是否自动打开浏览器
    hot: true, // 是否启动模块热替功能
    historyApiFallback: true, // 处理单页应用的路由问题
    watchFiles: ["src/**/*.js", "src/**/*.css"], // 需要监听的文件列表,当这些文件发生变化时,自动重启服务器
  },
  module: {
    rules: [
      {
        test: /\.ts$/, // 匹配以 .ts 结尾的文件
        use: ["ts-loader"],
        exclude: /node_modules/, // 不匹配的文件。排除 node_modules 文件夹,不进行 ts 匹配
      },
      {
        test: /\.js$/, // 匹配以 .js 结尾的文件
        use: [
          {
            loader: "babel-loader",
            // options: { // 可以直接在这里配置预设,也可以在 .babelrc 文件中配置,也可以在babel.config.js 中配置
            //	 presets: ["@babel/preset-env"]
            // }
          },
        ],
      },
      {
        test: /\.css$/, // 匹配以 .css 结尾的文件
        use: [
          process.env.NODE_ENV === "development"
            ? "style-loader"
            : MiniCssExtractPlugin.loader,
          "css-loader",
          "postcss-loader",
        ], // 注意:loader执行顺序是从后往前执行,顺序不能改变
      },
      {
        test: /\.less$/, // 匹配以 .less 结尾的文件
        use: [
          process.env.NODE_ENV === "development"
            ? "style-loader"
            : MiniCssExtractPlugin.loader,
          "css-loader",
          "postcss-loader",
          "less-loader",
        ],
      },
      {
        test: /\.scss$/, // 匹配以 .scss 结尾的文件
        use: [
          process.env.NODE_ENV === "development"
            ? "style-loader"
            : MiniCssExtractPlugin.loader,
          "css-loader",
          "postcss-loader",
          "sass-loader",
        ],
      },
    ],
  },
  plugins: [
    // 插件使用时,像构造函数一样直接 new 即可
    // template:模板文件的路径
    // filename:打包后生成的文件名
    // chunk:代码块
    new HtmlWebpackPlugin({ template: "./src/index.html" }),
    new MiniCssExtractPlugin(),
  ],
};

1.1.2. tsconfig.json

要使用ts,必须配置tsconfig.json文件
前端工程化第三章:webpack5基础(下)_第2张图片
具体代码如下

{
  "compilerOptions": {
    "noImplicitAny": true, // 不能有隐藏的 any 类型
    "moduleResolution": "node" // 使用 nodeJs 的模块规则
  }
}

1.1.3. src/index.ts

新建一个ts文件,随便写点ts代码:

前端工程化第三章:webpack5基础(下)_第3张图片
具体代码如下

let arr: number[] = [1, 2, 3];
console.log(arr);

运行 npm run build,查看main.js文件,可以看到ts代码已经被转换成了js代码:

前端工程化第三章:webpack5基础(下)_第4张图片
注意:此处如果编译报以下错误,那么需要安装parse-json
在这里插入图片描述

npm install --save parse-json

1.2. 使用babel-loader将ts转换为js

  • @babel/preset-typescript 是一个babel的一个预设,用于将ts代码转换为js代码

1.2.1. webpack.config.js

配置@babel/preset-typescript:

前端工程化第三章:webpack5基础(下)_第5张图片
具体代码如下

{
  test: /\.ts$/, // 匹配以 .ts 结尾的文件
  // use: ["ts-loader"], // 由于ts-loader存在一定的性能问题,因此这里我们可以配置 @babel/preset-typescript 来转换ts代码
  use: [
    {
      loader: "babel-loader",
      options: {
        presets: ["@babel/preset-typescript"],
      },
    },
  ],
  exclude: /node_modules/, // 不匹配的文件。排除 node_modules 文件夹,不进行 ts 转换
},

1.2.2. src/index.ts

添加一点ts代码:
前端工程化第三章:webpack5基础(下)_第6张图片
具体代码如下

let arr: number[] = [1, 2, 3];
console.log(arr);

type Add = () => void;

let add: Add = () => {
  console.log("这是一个函数");
};
add();

运行 npm run build 后,可以看到刚添加的ts代码已经被转换成js代码了:

前端工程化第三章:webpack5基础(下)_第7张图片

2. 代码规范检查(Eslint)

  • ESLint 是一款 JavaScript 代码检查工具,它可以帮助开发者在编写代码时检查错误、保持一致的风格和避免常见的陷阱。ESLint 可以使用预定义的规则,也可以通过自定义规则来满足特定的项目需求。

  • ESLint 可以与各种编辑器集成,包括 Visual Studio Code、Sublime Text 和 Atom 等。它还可以与构建工具集成,例如 Webpack 和 Gulp。

  • ESLint 的配置文件是一个 JSON 文件,其中包含要使用的规则和其他选项。ESLint 支持多种配置文件格式,包括 .eslintrc.eslintrc.js.eslintrc.yaml.eslintrc.json。开发者可以根据项目的需求选择适合自己的配置文件格式。

2.1. webpack.config.js

配置eslint插件:

const EslintPlugin = require("eslint-webpack-plugin");
module.exports = {
  // ......
  plugins: [
    // ......
    new EslintPlugin({
      // 这些类型的文件需要进行 eslint 代码检查
      extensions: ["js", "jsx", "ts", "tsx"],
    }),
  ],
};

2.2. .eslintrc

更多eslint规则
配置eslint规则:

前端工程化第三章:webpack5基础(下)_第8张图片
具体代码如下

{
  "parser": "@typescript-eslint/parser", // 解释器
  "plugins": ["@typescript-eslint"], // 插件
  "root": true,
  "env": {
    "node": true,
    "es6": true
  },
  "extends": [
    "eslint:recommended" // 继承 recommended 代码规范
  ],
  "parserOptions": {
    "ecmaVersion": 2021 // es 规范
  },
  "rules": { // 配置一些规则
    "no-console": "warn", // 不允许调用 console 对象,否则会报警告
    "no-unused-vars": "warn" // 未使用的变量报警告
  }
}

2.3. src/index.ts

let arr: number[] = [1, 2, 3];
console.log(arr);

type Add = () => void;

let add: Add = () => {
  console.log("这是一个函数");
};
add();

let a: string = 'hello world';

编译后,可以看到此时报了一些警告:

前端工程化第三章:webpack5基础(下)_第9张图片

按要求解决完代码中的console和变量:

let arr: number[] = [1, 2, 3];
arr.push(4);

type Add = () => void;

let add: Add = () => {
  
};
add();

let a: string = 'hello world';
a + "你好";

再次编译已经没有警告了:

前端工程化第三章:webpack5基础(下)_第10张图片

3. 图片处理(png/jpg/gif/svg等)

3.1. asset模块

Webpack 5 中,可以使用 type: 'asset/xxxx' 配置选项来处理图片等资源文件。

type 类型有四种

  • asset/resource:每个资源文件作为单独的文件输出,并返回 URL。
  • asset/inline:生成 base64 编码的字符串直接嵌入到输出的 JavaScript bundle 中。可以减少请求,但会加大体积。
  • asset/source:将文件处理和捆绑为原始源代码。文件内容会作为字符串加载,并可直接在捆绑包中使用。
  • asset:会自动选择导出数据 URI 还是生成单独的文件,可以设置文件大小限制来实现。

3.1. webpack.config.js

module.exports = {
  // ......
  entry: "./src/index.js", // entry:默认的路径是src/index.js,也可以自定义
  // ......
  devServer: {
  	// ......
  },
  module: {
    rules: [
      {
        test: /\.png$/,
        type: "asset/resource",
      },
      {
        test: /\.jpg$/,
        type: "asset/inline",
      },
      {
        test: /\.bmp$/,
        type: "asset/source",
      },
      {
        test: /\.svg$/,
        type: "asset",
        parser: {
          dataUrlCondition: {
            maxSize: 1024, // 小于1024的"asset/resource",大于1024的"asset/inline"
          },
        },
      },
      // ......
    ],
  },
};

3.1.2. .eslintrc

注意:需要在eslintrc文件中添加browser:true,否则index.js中使用document对象会报错

前端工程化第三章:webpack5基础(下)_第11张图片

3.1.3. src/index.js

测试一下asset这几种状态:

// 图片处理
let imgPng = require("./images/baidu.png");
let imgJpg = require("./images/hao123.jpg");
let imgBmp = require("./images/360.bmp");
let imgSvg = require("./images/google.svg");

let image = document.createElement("img");
image.src = imgPng;
console.log(image, "png");

image.src = imgJpg;
console.log(image, "jpg");

image.src = imgBmp;
console.log(image, "jpg");

image.src = imgSvg;
console.log(image, "jpg");
  • asset/resource

    前端工程化第三章:webpack5基础(下)_第12张图片
    运行 npm run dev 后,查看控制台

    前端工程化第三章:webpack5基础(下)_第13张图片

  • asset/inline
    前端工程化第三章:webpack5基础(下)_第14张图片
    运行 npm run dev 后,查看控制台
    前端工程化第三章:webpack5基础(下)_第15张图片

  • asset/source

    前端工程化第三章:webpack5基础(下)_第16张图片

    运行 npm run dev 后,查看控制台

    前端工程化第三章:webpack5基础(下)_第17张图片

  • asset
    先看一下这个图片的大小是1829 byte,我们会测试一次大于设置的尺寸,测试一次小于设置的尺寸
    前端工程化第三章:webpack5基础(下)_第18张图片
    1.测试大于maxSize:

    前端工程化第三章:webpack5基础(下)_第19张图片
    运行 npm run dev 后,查看控制台

    前端工程化第三章:webpack5基础(下)_第20张图片

    2.测试小于maxSize:

    前端工程化第三章:webpack5基础(下)_第21张图片
    运行 npm run dev 后,查看控制台

    前端工程化第三章:webpack5基础(下)_第22张图片

3.2. 图片压缩(优化)

  • image-webpack-loader 可以在 Webpack 打包过程中对图片进行优化和压缩,从而减小图片文件的大小,提高页面加载速度和响应速度
    • optipng:用于压缩PNG图片的配置项
    • pngquant:同样用于压缩PNG图片的配置项,可以设置图片质量和压缩速度
    • svgo:用于压缩SVG图片的配置项,包含多个插件
    • gifsicle:用于压缩Gif图片的配置项
    • webp:用于将JPG/PNG图片压缩并转换为WebP图片格式的配置项

3.2.1. 安装 image-webpack-loader

cnpm install image-webpack-loader --save

3.2.2. webpack.config.js

module.exports = {
  // ......
  module: {
    rules: [
      // ......
      {
        // 匹配文件的正则表达式,这里表示匹配JPG、PNG、GIF和SVG格式的图片文件
        test: /\.(jpe?g|png|gif|svg)$/i,
        use: [
          {
            // 使用image-webpack-loader对图片进行优化和压缩
            loader: "image-webpack-loader",
            options: {
              // 是否禁用图片优化和压缩
              disable: process.env.NODE_ENV === "development",
              mozjpeg: {
                progressive: true, // 是否开启渐进式JPEG,可以有效提升JPEG图片加载速度
                quality: 65, // 压缩JPEG图片的质量,取值范围为0到100,值越大质量越好但文件越大
              },
              optipng: {
                enabled: true, // 是否开启PNG图片的优化,可以有效提升PNG图片加载速度
              },
              pngquant: {
                // 压缩PNG图片的质量范围,取值范围为0到1,值越大质量越好但文件越大
                // 第一个数字表示压缩质量的下限,第二个数字表示压缩质量的上限
                quality: [0.65, 0.9],
                speed: 4, // 压缩PNG图片的速度,取值范围为1到10,值越大速度越快但质量越低
              },
              svgo: {
                plugins: [
                  // 压缩SVG图片的插件列表,这里包含removeViewBox和cleanupIDs两个插件
                  {
                    //用于删除SVG图片中的viewBox属性
                    //viewBox属性是用来指定SVG视口范围的,它的值是一个矩形框的坐标和宽高
                    removeViewBox: false,
                  },
                  {
                    //用于删除SVG图片中的无用ID属性
                    cleanupIDs: true,
                  },
                ],
              },
              gifsicle: {
                interlaced: true, // 是否开启GIF图片的隔行扫描,可以有效提升GIF图片加载速度
              },
            },
          },
        ],
      },
      // ......
    ],
  },
};

运行npm run build后,可以看到图片体积明显变小了:

在这里插入图片描述

3.3. 响应式图片

  • 响应式图片是指能够根据设备屏幕大小分辨率等因素动态调整显示大小清晰度的图片。
  • responsive-loader 是一个 webpackloader,用于实现响应式图片的功能。它可以根据设备屏幕大小和像素密度等因素自动调整图片大小和清晰度,从而提高网站的用户体验和性能。
    • sizes:用于指定不同尺寸的图片大小。在这个例子中,我们指定了3个不同的图片大小,分别是375px(iphone6/7/8/X尺寸)768px(ipad尺寸)1024px(ipadPro尺寸)。当加载图片时,responsive-loader 会根据设备的屏幕大小和像素密度等因素自动选择最合适的图片大小。
    • adapter:用于指定图片处理库。在这个例子中,我们使用了 sharp 库,它是一个高性能的图片处理库,可以用来自动调整图片大小和清晰度
  • srcsetsizesHTMLimg 标签的两个属性,用于实现响应式图片的功能。
    • srcset 属性用于指定不同尺寸和清晰度的图片版本,它的值是一个以逗号分隔的图片列表,每个图片元素包含了图片 URL 和对应的宽度或像素密度等信息。
    • sizes 属性用于指定图片在不同屏幕尺寸下的显示大小,它的值是一个以逗号分隔的尺寸列表,每个尺寸元素包含了媒体查询和对应的尺寸信息。

3.3.1. 安装

cnpm i responsive-loader sharp --save

3.3.2. webpack.config.js

前端工程化第三章:webpack5基础(下)_第23张图片

module.exports = {
  module: {
    rules: [
      // ......
      {
        test: /\.png$/,
        //oneOf是一个优化选项,用于提高打包的速度
        oneOf: [
          {
            //resourceQuery是一个用于匹配请求资源的URL中查询字符中是否包含sizes,如果包含则切图,不包含则执行下面的asset/resource
            resourceQuery: /sizes/,
            use: [
              {
                loader: "responsive-loader",
                options: {
                  adapter: require("responsive-loader/sharp"),
                },
              },
            ],
          },
          {
            type: "asset/resource",
          },
        ],
      },
      // ......
    ],
  },
};

3.3.3. src/index.js

前端工程化第三章:webpack5基础(下)_第24张图片

import bgPng from "./images/bg.png?sizes[]=375,sizes[]=768,sizes[]=1024";
console.log(bgPng, "bgPng");
let image = new Image();
// let image = document.createElement("img"); // 等效上一行的写法
image.srcset = bgPng.srcSet;
// 屏幕宽度大于768px,则使用768px图片,并且图片宽度是屏幕的可视区域宽度
image.sizes = `(min-width: 768) 768px,100vw`;
document.body.appendChild(image);

运行npm run build,可以看到图片被打包成不同尺寸:

前端工程化第三章:webpack5基础(下)_第25张图片

运行npm run dev启动项目,切换不同屏幕尺寸可以看到效果如下:

前端工程化第三章:webpack5基础(下)_第26张图片
也可以通过审查这个元素去查看图片渲染大小:

前端工程化第三章:webpack5基础(下)_第27张图片

3.4. 雪碧图

  • 雪碧图(Sprite)是指将多个小图片(如图标、小按钮等)合并成一张大图片,通过CSS的 background-position 属性来控制显示不同的小图片。它的优点是减少HTTP请求次数提高页面的加载速度和性能
  • webpack-spritesmith 是一个 webpack 插件,用于生成雪碧图。它可以将多个小图片合并成一张大图片,并在生成的 CSS 文件中自动生成 background-position 属性和样式代码,简化了雪碧图的生成和使用过程。

3.4.1. 安装

cnpm install --save webpack-spritesmith

3.4.2. src/images/icons

准备一个 icons 文件夹,放入事先下载的png图片:

前端工程化第三章:webpack5基础(下)_第28张图片

3.4.3. webpack.config.js

前端工程化第三章:webpack5基础(下)_第29张图片
前端工程化第三章:webpack5基础(下)_第30张图片

const path = require("path"); // nodeJs 的 path 模块

const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 将css代码从js文件中拆分出来

const WebpackSpritesmith = require("webpack-spritesmith"); // 生成雪碧图插件

module.exports = {
  module: {
    rules: [
      // ......
      {
        test: /\.less$/, // 匹配以 .less 结尾的文件
        use: [
          process.env.NODE_ENV === "development"
            ? "style-loader"
            : MiniCssExtractPlugin.loader,
          "css-loader",
          "postcss-loader",
          // "less-loader",
          {
            loader: "less-loader",
            options: {
              lessOptions: {
                paths: [path.resolve(__dirname, "src/sprite")],
              },
            },
          },
        ],
      },
      // ......
    ],
  },
  plugins: [
    // ......
    new WebpackSpritesmith({
      // 具体配置可查看github
      src: {
        //指定输入的文件
        cwd: path.resolve(__dirname, "src/images/icons"),
        glob: "**/*.png",
      },
      target: {
        //指定输出的文件路径
        image: path.resolve(__dirname, "src/sprite/sprite.png"),
        css: path.resolve(__dirname, "src/sprite/sprite.less"),
      },
      apiOptions: {
        // 指定CSS文件应使用相对路径引用精灵图
        cssImageRef: "sprite/sprite.png",
      },
      spritesmithOptions: {
        algorithm: "top-down",
        padding: 10,
      },
    }),
  ],
};

3.4.4. src/index.js

前端工程化第三章:webpack5基础(下)_第31张图片

/**
 * 6.雪碧图测试代码
 */
import "./icon.less";
let img1 = document.createElement("img");
img1.classList.add("icon-baidu");
document.body.appendChild(img1);

let img2 = document.createElement("img");
img2.classList.add("icon-hao123");
document.body.appendChild(img2);

let img3 = document.createElement("img");
img3.classList.add("icon-360");
document.body.appendChild(img3);

3.4.5. icon.less

@import "./sprite/sprite.less"; // 引用雪碧图文件
.icon-baidu {
  .sprite(@baidu);
}
.icon-hao123 {
  .sprite(@hao123);
}
.icon-360 {
  .sprite(@360);
}

运行 npm run dev 查看效果:

  • 首先根据我们的配置,生成一个src/sprite/sprite.less和一个src/sprite/sprite.png文件
    前端工程化第三章:webpack5基础(下)_第32张图片

  • 其次我们在src/icon.less中导入的样式会生效

    前端工程化第三章:webpack5基础(下)_第33张图片

  • 然后就可以看到页面上已经将图片渲染出来了,并且是采用的雪碧图,是通过background-position属性实现的,减少了http请求,有效的提高了加载性能
    前端工程化第三章:webpack5基础(下)_第34张图片

你可能感兴趣的:(webpack学习,前端)