export function getFileLoaderUtils()

in packages/docusaurus-utils/src/webpackUtils.ts [39:154]


export function getFileLoaderUtils(): FileLoaderUtils {
  // files/images < urlLoaderLimit will be inlined as base64 strings directly in
  // the html
  const urlLoaderLimit = WEBPACK_URL_LOADER_LIMIT;

  // defines the path/pattern of the assets handled by webpack
  const fileLoaderFileName = (folder: AssetFolder) =>
    path.posix.join(
      OUTPUT_STATIC_ASSETS_DIR_NAME,
      folder,
      '[name]-[contenthash].[ext]',
    );

  const loaders: FileLoaderUtils['loaders'] = {
    file: (options: {folder: AssetFolder}) => ({
      loader: require.resolve(`file-loader`),
      options: {
        name: fileLoaderFileName(options.folder),
      },
    }),
    url: (options: {folder: AssetFolder}) => ({
      loader: require.resolve('url-loader'),
      options: {
        limit: urlLoaderLimit,
        name: fileLoaderFileName(options.folder),
        fallback: require.resolve('file-loader'),
      },
    }),

    // TODO avoid conflicts with the ideal-image plugin
    // TODO this may require a little breaking change for ideal-image users?
    // Maybe with the ideal image plugin, all md images should be "ideal"?
    // This is used to force url-loader+file-loader on markdown images
    // https://webpack.js.org/concepts/loaders/#inline
    inlineMarkdownImageFileLoader: `!${escapePath(
      require.resolve('url-loader'),
    )}?limit=${urlLoaderLimit}&name=${fileLoaderFileName(
      'images',
    )}&fallback=${escapePath(require.resolve('file-loader'))}!`,
    inlineMarkdownLinkFileLoader: `!${escapePath(
      require.resolve('file-loader'),
    )}?name=${fileLoaderFileName('files')}!`,
  };

  const rules: FileLoaderUtils['rules'] = {
    /**
     * Loads image assets, inlines images via a data URI if they are below
     * the size threshold
     */
    images: () => ({
      use: [loaders.url({folder: 'images'})],
      test: /\.(?:ico|jpe?g|png|gif|webp)(?:\?.*)?$/i,
    }),

    fonts: () => ({
      use: [loaders.url({folder: 'fonts'})],
      test: /\.(?:woff2?|eot|ttf|otf)$/i,
    }),

    /**
     * Loads audio and video and inlines them via a data URI if they are below
     * the size threshold
     */
    media: () => ({
      use: [loaders.url({folder: 'medias'})],
      test: /\.(?:mp4|webm|ogv|wav|mp3|m4a|aac|oga|flac)$/i,
    }),

    svg: () => ({
      test: /\.svg$/i,
      oneOf: [
        {
          use: [
            {
              loader: require.resolve('@svgr/webpack'),
              options: {
                prettier: false,
                svgo: true,
                svgoConfig: {
                  plugins: [
                    {
                      name: 'preset-default',
                      params: {
                        overrides: {
                          removeTitle: false,
                          removeViewBox: false,
                        },
                      },
                    },
                  ],
                },
                titleProp: true,
                ref: ![path],
              },
            },
          ],
          // We don't want to use SVGR loader for non-React source code
          // ie we don't want to use SVGR for CSS files...
          issuer: {
            and: [/\.(?:tsx?|jsx?|mdx?)$/i],
          },
        },
        {
          use: [loaders.url({folder: 'images'})],
        },
      ],
    }),

    otherAssets: () => ({
      use: [loaders.file({folder: 'files'})],
      test: /\.(?:pdf|docx?|xlsx?|zip|rar)$/i,
    }),
  };

  return {loaders, rules};
}