@fluentui/icons 未在页面中显示

@fluentui/icons not showing in page

最近我清理了项目中的 webpack 配置以使其更易于维护,我通过将配置拆分为两个文件来做到这一点:

// webpack.config.js
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const { merge } = require("webpack-merge");
const parts = require("./webpack.parts");

const commonConfig = merge([
  {
    target: "web",
    stats: {
      optimizationBailout: true,
    },
    entry: {
      index: {
        import: parts.rootResolverFn("src/index/main.js"),
        dependOn: "vendors",
      },
      vendors: ["react", "react-dom", "prop-types"],
    },
    output: {
      filename: "[name].[contenthash].js",
      path: parts.rootResolverFn("dist/public"),
      publicPath: "/",
      clean: true,
    },
    resolve: parts.resolve(),
  },
  parts.plugins(),
  parts.loadJs(),
  parts.loadAssets(),
  parts.loadCss(),
  parts.bundleAnalyzer(),
]);

const developmentConfig = merge([
  {
    output: {
      filename: "[name].bundle.js",
      pathinfo: false,
    },
    devtool: "eval-source-map",
    devServer: parts.devServer(),
    plugins: [new ReactRefreshWebpackPlugin()],
  },
]);

const productionConfig = merge([
  {
    optimization: {
      splitChunks: { chunks: "all" },
      runtimeChunk: { name: "runtime" },
      usedExports: true,
      sideEffects: true,
      minimizer: [
        `...`,
        new CssMinimizerPlugin({
          minimizerOptions: {
            preset: [
              "default",
              {
                discardComments: { removeAll: true },
              },
            ],
          },
        }),
      ],
    },
  },
]);

module.exports = (env, { mode }) => {
  switch (mode) {
    case "production":
      return merge(commonConfig, productionConfig);
    case "development":
      return merge(commonConfig, developmentConfig);
    default:
      throw new Error(`Trying to use unknown mode: ${mode}`);
  }
};

和另一个文件:

// webpack.parts.js
const path = require("path");
const { spawnSync } = require("child_process");
const webpack = require("webpack");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
const pkg = require("./package.json");

const root = path.join(__dirname, "./");

const pathResolver = (base) => (toResolve) => path.resolve(base, toResolve);
const rootResolver = pathResolver(root);

const isProd = process.env.NODE_ENV === "production";

let commitHash;
if (!isProd) {
  try {
    const { stdout } = spawnSync("git", ["rev-parse", "--short", "HEAD"]);
    console.log(`Current commit is: ${String(stdout)}`);
    commitHash = String(stdout);
  } catch (e) {
    console.warn("Could not retrieve hash for this development environment, is this a valid git repository?");
  }
}

const copyPluginPatterns = [
  {
    from: rootResolver("src/assets"),
    to: rootResolver("dist/public/assets"),
  },
  {
    from: rootResolver("node_modules/mxgraph/javascript"),
    to: rootResolver("dist/public/mxgraph"),
  },
  {
    from: rootResolver("src/config.js"),
    to: rootResolver("dist/public/"),
  },
];

exports.rootResolverFn = (path) => rootResolver(path);

exports.devServer = () => ({
  port: 8282,
  hot: true,
  historyApiFallback: true,
  open: true,
  client: {
    overlay: true,
  },
});

exports.resolve = () => ({
  alias: {
    api: rootResolver("src"),
    components: rootResolver("src/components"),
    shared: rootResolver("src/shared"),
  },
  extensions: ["*", ".js", ".jsx", ".json", ".mjs", ".es"],
  modules: [path.resolve(root), path.resolve(root, "src"), path.resolve(root, "node_modules")],
  symlinks: false,
});

exports.loadAssets = () => ({
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif)$/,
        type: "asset/resource",
      },
      {
        test: /\.(svg)$/,
        type: "asset/inline",
      },
    ],
  },
});

exports.loadJs = () => ({
  module: {
    rules: [
      {
        test: /\.m?(js|jsx)$/,
        exclude: /(node_modules)/,
        use: {
          loader: "babel-loader",
          options: {
            plugins: [!isProd && require.resolve("react-refresh/babel")].filter(Boolean),
          },
        },
      },
    ],
  },
});

exports.loadCss = () => ({
  module: {
    rules: [
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              sourceMap: true,
              url: false,
            },
          },
          "fast-sass-loader",
          "postcss-loader",
        ],
      },
    ],
  },
});

exports.plugins = () => {
  return {
    plugins: [
      new MiniCssExtractPlugin({
        ignoreOrder: true,
        filename: "[name].[contenthash].css",
      }),
      new CopyPlugin({
        patterns: copyPluginPatterns,
      }),
      new webpack.DefinePlugin({
        ENV: JSON.stringify(process.env.NODE_ENV || "development"),
        VERSION: JSON.stringify(pkg.version),
        TEST_MODE: JSON.stringify(process.env.TEST_MODE),
        COMMIT_SHA: process.env.COMMIT_SHA || commitHash,
      }),
      new HtmlWebpackPlugin({
        title: "MyApp",
        meta: {
          charset: "utf-8",
          viewport: "width=device-width, initial-scale=1",
        },
        template: rootResolver("src/index/index.html"),
        hash: true,
        chunks: ["index", "vendors"],
        minify: {
          collapseWhitespace: false,
        },
      }),
      new webpack.IgnorePlugin({
        resourceRegExp: /^\.\/locale$/,
        contextRegExp: /moment$/,
      }),
    ],
  };
};

exports.bundleAnalyzer = (options = {}) => ({
  plugins: [
    new BundleAnalyzerPlugin({
      analyzerHost: "localhost",
      analyzerPort: "2112",
      ...options,
    }),
  ],
});

应用这些更改后,@fluentui/font-icons-mdl2 中的 icons 停止正确显示,如下图所示:

我正在使用 microsoft/fluentui docs 中推荐的方法,我可以看到使用 webpack-bundle-analyzer @fluentui/font-icons/mdl2 库包含在包中

令我感到奇怪的是,通过检查 DevTools 中的 Network 选项卡,我可以看到检索字体的调用并且它们是成功的

但是,如您所见,字形上方的几张图片显示不正确。

有人最近在使用 @fluentui/font-icons-mdl2webpack 时遇到过类似的问题吗?提前致谢。

好吧,我能够找出问题所在,有问题的行是:

splitChunks: { chunks: "all" },
runtimeChunk: { name: "runtime" },

删除这些行后,图标开始按预期再次出现。我将关闭它,但我的任务是找出发生这种情况的确切原因,也就是说,webpack 是一个了不起的工具,但您真的应该花时间仔细阅读文档。干杯