Webpack 插件實現 CSS 樣式尺寸單位轉換

Webpack 插件實現 CSS 樣式尺寸單位轉換

實現方式一

插件代碼

以下是編寫的一個 Webpack 插件,用於將樣式文件中以 rpx 爲單位的值轉換爲以 px 爲單位的值(換算比率爲 1px=2rpx):

const pluginName = "CssSzieConvertPlugin";

class CssSzieConvertPlugin {
  apply(compiler) {
    compiler.hooks.emit.tap(pluginName, (compilation) => {
      for (const chunk of compilation.chunks) {
        for (const file of chunk.files) {
          if (file.endsWith(".css")) {
            const originalSource = compilation.assets[file].source();
            const newSource = originalSource.replace(
              /\b(\d+(\.\d+)?)(rpx)\b/g,
              (match, number) => `${number / 2}px`
            );
            compilation.assets[file] = {
              source: () => newSource,
              size: () => newSource.length,
            };
          }
        }
      }
    });
  }
}

module.exports = CssSzieConvertPlugin;

上面的代碼創建了一個名爲 CssSzieConvertPlugin 的插件類。該插件通過註冊到 Webpack 的 emit 鉤子上來處理樣式文件。

在鉤子回調函數中,首先遍歷所有的 chunk 和文件,並檢查哪些文件是 CSS 文件。通過檢查文件擴展名是否爲 .css 來識別 CSS 文件。

然後,獲取原始文件的源代碼,並使用正則表達式 /\b(\d+(\.\d+)?)(rpx)\b/g 匹配所有以 rpx 爲單位的數字。使用 replace 方法將每個匹配項替換爲一個新的值。使用一個回調函數,將匹配項中的數字除以 2,並將單位從 "rpx" 更改爲 "px"。

最後,更新 compilation.assets 對象中的文件源代碼和大小,以便 Webpack 可以使用更新後的文件替換原始文件。

使用代碼

在 Webpack 配置文件中使用這個插件,例如:

const CssSzieConvertPlugin = require("./CssSzieConvertPlugin");

module.exports = {
  // ...
  plugins: [
    new CssSzieConvertPlugin(),
    // ...
  ],
};

這將在 Webpack 構建過程中自動應用編寫的插件,並將樣式文件中的 rpx 值轉換爲 px 值。

實現方式二

插件代碼

以下是編寫的另一個 Webpack 插件,用於將樣式文件中以 rpx 爲單位的值轉換爲以 px 爲單位的值(換算比率爲 1px=2rpx):

const pluginName = "CssSzieConvertPlugin";

class CssSzieConvertPlugin {
  constructor(options) {
    this.options = options || {};
  }

  apply(compiler) {
    compiler.hooks.emit.tapAsync(pluginName, (compilation, callback) => {
      const { test = /\.css$/, exclude = /node_modules/ } = this.options;
      const files = Object.keys(compilation.assets).filter(
        (filename) => test.test(filename) && !exclude.test(filename)
      );

      files.forEach((file) => {
        let source = compilation.assets[file].source();

        // 使用正則表達式匹配所有以 rpx 爲單位的數字
        if (source.replace) {
          // 解決 TypeError: source.replace is not a function 問題

          source = source.replace(
            /\b(\d+(\.\d+)?)(rpx)\b/g,
            (match, p1) => `${p1 / 2}px`
          );
        }

        // 更新編譯後的代碼
        compilation.assets[file] = {
          source: () => source,
          size: () => source.length,
        };
      });

      callback();
    });
  }
}

module.exports = CssSzieConvertPlugin;

該插件類名爲 CssSzieConvertPlugin,構造函數接受一個選項對象作爲參數,該選項對象包含兩個屬性:testexclude,它們分別表示要處理的文件類型和要排除的文件。默認情況下,test 屬性爲 /\css$/exclude 屬性爲 /node_modules/

apply 方法中,使用 Webpack 的 emit 鉤子來處理樣式文件。首先使用選項中的正則表達式來過濾要處理的文件,然後遍歷這些文件並對它們的源代碼進行處理。

對於每個文件,使用正則表達式 /\b(\d+(\.\d+)?)(rpx)\b/g 匹配所有以 rpx 爲單位的數字,並將每個匹配項替換爲該數字除以 2 的結果。最後,更新編譯後的代碼,並將更新後的源代碼和大小存儲在 compilation.assets 對象中。

使用代碼

  1. 在 Webpack 配置文件中使用這個插件,例如:

    const CssSzieConvertPlugin = require("./CssSzieConvertPlugin");
    
    module.exports = {
      // ...
      plugins: [
        new CssSzieConvertPlugin({
          test: /\.wxss/,
          exclude: /node_modules/,
        }),
        // ...
      ],
    };
    

    這將在 Webpack 構建過程中自動應用編寫的插件,並將樣式文件中的 rpx 值轉換爲 px 值。在上面的示例中,指定了要處理的文件類型爲 .wxss 文件,並排除了 node_modules 目錄中的文件。

  2. 在基於 Webpack 構建工具的 Vue 項目中配置,例如:

    // vue.config.js
    const CssSzieConvertPlugin = require("./CssSzieConvertPlugin");
    
    module.exports = {
      configureWebpack: {
        plugins: [
          new CssSzieConvertPlugin({
            test: /\.(css|js|html)/,
            exclude: /node_modules/,
          }),
        ],
      },
    };
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章