【问题标题】:Removing all data-test attributes from Vue templates during production build in Vue 3在 Vue 3 的生产构建期间从 Vue 模板中删除所有数据测试属性
【发布时间】:2023-12-31 00:22:01
【问题描述】:

我在 TS 中使用 Vue3(最后一个 vue-cli)。

我想在 vue-loader 编译 .vue 文件时获取所有节点(vnodes)元素。 我需要读取节点属性并删除所有“数据测试”。

我已经尝试在 vue.config.js 中使用:

module.exports = {
  chainWebpack: (config) => {
    config.module
      .rule('vue')
      .use('vue-loader')
      // .loader('vue-loader')                       // same with
      .tap((options) => {
        options.compilerOptions = {
          ...(options.compilerOptions || {}),
modules: [                                           // never enter here
            {
              preTransformNode(node) {
                // if (process.env.NODE_ENV === 'production') {
                const { attrsMap, attrsList } = node
                console.log(node)
                if (attrsMap['qa-id']) {
                  delete attrsMap['qa-id']
                  const index = attrsList.findIndex(
                    (x) => x.name === 'data-test'
                  )

                  attrsList.splice(index, 1)
                }
                // }

                return node
              }
            }
          ]
        }

        return options
      })
  }
}

我知道转换是在 vue-template-compiler 中完成的。 如何进入编译钩子?

我曾尝试在模块中使用 preTransformNode 但失败了。

来源:

【问题讨论】:

    标签: vue.js vuejs3 vue-loader


    【解决方案1】:

    这里的主要问题是您正在使用 vue-template-compiler 文档,但该包是 Vue 2 的编译器!

    在 Vue 3 中,编译器被拆分为多个 packages,并且到目前为止缺少正确的文档(或者我只是找不到它)

    API 也发生了重大变化 - 您传递的是 nodeTransforms (source) 而不是 modules,并且转换不是对象,而是函数。

    幸运的是,Vue 核心成员 Rahul Kadyan 提供了一个有趣的 video on YT,它显示了您需要的确切用例(删除 data-test 属性)-code

    所以我猜代码应该是这样的:

    function removeDataTestAttrs(node) {
      if (node.type === 1 /* NodeTypes.ELEMENT */) {
        node.props = node.props.filter(prop =>
          prop.type === 6 /* NodeTypes.ATTRIBUTE */
            ? prop.name !== 'data-test'
            : true
        )
      }
    }
    
    module.exports = {
      parallel: false, // !!IMPORTANT!! - see note below
      chainWebpack: (config) => {
        config.module
          .rule('vue')
          .use('vue-loader')
          .tap((options) => {
            options.compilerOptions = {
              ...(options.compilerOptions || {}),
              nodeTransforms: [removeDataTestAttrs]                                                                                                        
            }
    
            return options
          })
      }
    }
    

    注意 - cmets 中提到的问题(使用serve 但在build 上抛出错误的解决方案)是由使用thread-loader 进行生产构建的Vue CLI 引起的。问题是,在使用 thread-loader 时,您不能将函数作为 Webpack 配置的一部分传递(请参阅文档中的 this warning),因此需要设置 parralel: false 才能使其工作......

    【讨论】:

    • 您对vue-template-compiler 的看法是正确的。谢谢,很实用。祝你有美好的一天
    • 这适用于serve,但不适用于buildSyntax Error: Thread Loader (Worker 6) nodeTransforms[i] is not a function
    • @BriceChaponneau 找到了问题的原因。检查我更新的答案。 现在可以在我的机器上运行 :)
    • 喂!太感谢了。伟大的。效果很好