带动态查询的Webpack Loader

时间:2016-04-08 17:48:18

标签: javascript webpack

我在webpack配置中为SVG文件设置了一个Webpack加载器,它看起来像这样

const SVGO_CONFIG = JSON.stringify({
  plugins: [
    {removeTitle: true},
  ],
});

const SVG_LOADER = {
  test: /\.svg$/,
  loader: 'babel!svg-react!svgo?' + SVGO_CONFIG,
};

这允许我import svg文件,好像它们是如此反应组件

import Icon from 'src/images/icon.svg';

但在某些情况下,我希望能够告诉svgo-loader从文件中删除fillstroke属性。我可以通过在配置

中设置另一个插件来完成此操作
const SVGO_CONFIG = JSON.stringify({
  plugins: [
    {removeTitle: true},
    {removeAttrs: {attrs: "(fill|stroke)"}},
  ],
});

但这适用于我导入的所有svg文件。是否有一种简单的方法来标记import语句以略微修改配置?

import TransparentIcon from 'src/images/icon.svg?removeFill`;

我的半解决方案是使用额外的扩展名(或在不同的文件夹中)保存文件,但这意味着我无法在删除属性的情况下导入文件。

2 个答案:

答案 0 :(得分:1)

您可以将include用于此目的。例如:

const SVG_LOADER = {
  test: /\.svg$/,
  loader: 'babel!svg-react!svgo?' + SVGO_CONFIG,
  include: [path.join(__dirname, 'svgs/demo.svg', ...]
};

您需要两个单独的规则。你应该确保他们的include不重叠,否则它们会同时执行。解决此问题的一种巧妙方法是将每个目录的svgs拆分并指向这些。

答案 1 :(得分:1)

有两种方法:

  1. 在两个单独的SVG加载器中使用test属性的正则表达式,如下所示:

    const SVGO_CONFIG = JSON.stringify({
      plugins: [
        {removeTitle: true},
      ],
    });
    
    const SVG_LOADER = {
      test: /\.svg$/,
      loader: 'babel!svg-react!svgo?' + SVGO_CONFIG,
    };
    
    const SVGO_CONFIG_REMOVE_FILL = JSON.stringify({
      plugins: [
        {removeTitle: true},
        {removeAttrs: {attrs: "(fill|stroke)"}},
      ],
    });
    
    const SVG_LOADER_REMOVE_FILL = {
      test: /\.svg\?removeFill$/,
      loader: 'babel!svg-react!svgo?' + SVGO_CONFIG_REMOVE_FILL,
    };
    
  2. 您可以编写自己的加载程序来调整查询字符串。 (这可能是过度工程化的):

    module.exports = function(content) {
      return content;
    };
    module.exports.pitch = function(remainingRequest, precedingRequest, data) {
      var i;
      var len = this.loaders.length;
      var loader;
      if (this.resourceQuery === '?removeFill') {
        for (i = 0; i < len; i++) {
          loader = this.loaders[i];
          if (loader.query === '?{"plugins":[{"removeTitle":true}]}') {
            loader.query = '?' + JSON.stringify({
              plugins: [
                {removeTitle: true},
                {removeAttrs: {attrs: "(fill|stroke)"}},
              ],
            });
          }
        }
      }
    };