在Vue 3的生产构建期间,从Vue模板中删除所有数据测试属性

omvjsjqw  于 2023-01-26  发布在  Vue.js
关注(0)|答案(3)|浏览(124)

我在TS中使用Vue 3(上一个Vue-cli)。
我想在vue加载器编译.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内部完成的。我如何进入compile hook?
我曾尝试在模块中使用preTransformNode,但失败了。

资料来源:

knpiaxh1

knpiaxh11#

这里的主要问题是,您正在使用vue-template-compiler文档,但该包是Vue 2的编译器!
在Vue 3中,编译器被拆分为多个packages,目前缺少适当的文档(或者我只是无法找到它)
此外,API中也有重大变化--您传递的不是modules,而是nodeTransforms(源代码),转换不是对象,而是函数。
幸运的是,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
      })
  }
}

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

维特(更新-2022年6月22日)

// vite.config.ts
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
    )
  }
}

export default defineConfig(() => {
  return {
    plugins: [
      vue({
        template: {
          compilerOptions: {
            nodeTransforms: isProd ? [removeDataTestAttrs] : [],
          },
        },
      }),
    ]
  }
})
nhaq1z21

nhaq1z212#

版本-CLI 5 +版本3.2:

const { defineConfig } = require('@vue/cli-service');

function removeAttributesDuringBuild (node) {
  const attributesToRemove = [
    'data-test',
    ':data-test',
    'v-bind:data-test',
    'data-value',
    ':data-value',
    'v-bind:data-value'
  ];
  const nodeIsElement = node.type === 1; // ENUMS ARE STUPID
  if (nodeIsElement) {
    node.props = node.props.filter(function (prop) {
      const propIsAttribute = prop.type === 6; // ENUMS ARE STUPID
      const propIsDynamicAttribute = prop.name === 'bind';
      if (propIsAttribute) {
        const attributeName = prop.name;
        return !attributesToRemove.includes(attributeName);
      }
      if (propIsDynamicAttribute) {
        const attributeName = prop.arg?.content;
        return !attributesToRemove.includes(attributeName);
      }
      return true;
    });
  }
}

module.exports = defineConfig({
  lintOnSave: false,
  transpileDependencies: true,
  parallel: false, // disabled to allow for node transforms
  chainWebpack: (config) => {
    // Remove comments during build
    config.optimization
      .minimizer('terser')
      .tap((args) => {
        args[0].terserOptions.output = {
          ...args[0].terserOptions.output,
          comments: false
        };
        return args;
      });

    // Remove dev attributes
    config.module
      .rule('vue')
      .use('vue-loader')
      .tap(function (options) {
        options.compilerOptions = {
          ...(options.compilerOptions || {}),
          nodeTransforms: [removeAttributesDuringBuild]
        };
        return options;
      });
  }
});
vcudknz3

vcudknz33#

维生素4 +维生素E 2.7

import vue from '@vitejs/plugin-vue2';
import { defineConfig } from 'vite';

function removeAttributesDuringBuild (astEl) {
  const attributesToRemove = [
    'data-test',
    ':data-test',
    'v-bind:data-test',
    'data-value',
    ':data-value',
    'v-bind:data-value'
  ];

  function removeAttribute (attributesMap, attributesList, attributeToRemove) {
    if (attributesMap[attributeToRemove]) {
      delete attributesMap[attributeToRemove];
      const index = attributesList.findIndex(function (attribute) {
        return attribute.name === attributeToRemove;
      });
      attributesList.splice(index, 1);
    }
  }

  if (process.env.NODE_ENV === 'production') {
    const { attrsMap, attrsList } = astEl;
    attributesToRemove.forEach(function (attributeToRemove) {
      removeAttribute(attrsMap, attrsList, attributeToRemove);
    });
  }
  return astEl;
}

export default defineConfig(() => {
  return {
    plugins: [
      vue({
        template: {
          compilerOptions: {
            modules: [
              {
                preTransformNode: removeAttributesDuringBuild
              }
            ]
          }
        }
      })
    ]
  };
});

相关问题