【问题标题】:Prepending custom loader to vue-loader breaks when template includes custom tags当模板包含自定义标签时,将自定义加载器添加到 vue-loader 会中断
【发布时间】:2021-05-12 06:29:29
【问题描述】:

我有一个看起来像这样的 vue2 组件:

<template>
  <p>Hello world</p>
</template>

<script>
export default { name: 'Example' };
</script>

<docs>
Some documentation...
</docs>

我还想为我的 vue 文件使用额外的加载器,所以我的 webpack 配置如下所示:

module.exports = {
  module: {
    rules: [{
      test: /\.vue$/,
      use: [{
        loader: 'vue-loader',
      }, {
        loader: path.resolve(__dirname, 'CustomLoader.js'),
      }],
    }],
  },
};

// CustomLoader.js
module.exports = function(source) {
  return source;
}

运行webpack bundle 会引发一个错误,即缺少&lt;docs&gt; 块的加载器,即使CustomLoader 返回源代码不变。大致如下:

Error in path/to/component.vue?vue&type=custom&index=0&blockType=docs
Module parse failed: Unexpected token
File was processed with these loaders:
* ./node_modules/vue-loader/lib.index.js
* ./CustomLoader.js
You may need an additional loader to handle the result of these loaders.

删除其中一个

  • CustomLoader
  • &lt;docs&gt; 标签 解决问题。

谁能告诉我问题出在哪里?

【问题讨论】:

    标签: javascript vue.js webpack vuejs2 vue-loader


    【解决方案1】:

    在翻阅vue-loader的源代码后,我自己找到了答案。从广义上讲,vue-loader 检查是否存在另一个 vue 文件加载器。如果没有其他加载器,则它会将自定义块的内容扔掉。否则,它将返回内容,期望其他加载器知道如何处理它。这就是为什么添加另一个加载器,即使是一个什么都不做的加载器,也会导致构建失败。

    如果您想更好地了解发生了什么,请查看 vue-loader 源代码,具体来说:

    要了解如何解决这个问题,首先要了解 vue-loader 是如何解析模板的。它用导入语句和内联加载器链替换每个块。所以这个

    <template>
      <!-- ... -->
    </template>
    
    <script>
    // ...
    </script>
    
    <docs>
    // ...
    </docs>
    

    变成这样

    import render from 'custom-loader!vue-loader!source.vue?vue&type=template'
    import script from 'custom-loader!vue-loader!source.vue?vue&type=script'
    import 'custom-loader!vue-loader!source.vue?vue&type=custom&blockType=docs'
    

    所以本质上,每个.vue 文件都会多次调用自定义加载程序。一次是在第一遍,然后对于每个展开的块再一次。

    我的解决方法是检查加载程序中的resourceQuery。如果它指向一个自定义块,我只返回一个空模板。像这样的:

    // CustomLoader.js
    module.exports = function(source) {
      if (this.resourceQuery.includes('type=custom')) {
        return '<custom></custom>';
      }
      return source;
    }
    

    重要的是返回 vue-loader(使用 vue 模板编译器)能够解析的内容。因此&lt;custom&gt; 标记而不是空字符串。

    【讨论】:

      猜你喜欢
      • 2016-05-05
      • 2019-02-14
      • 2019-12-30
      • 2010-11-15
      • 2017-07-29
      • 2013-01-29
      • 2016-02-25
      • 2011-08-10
      • 2011-07-10
      相关资源
      最近更新 更多