vue.jsvuejs3vue-loader

Removing all data-test attributes from Vue templates during production build in Vue 3


I work with Vue3 in TS (last vue-cli).

I want to get all nodes (vnodes) elements when vue-loader compile .vue file. I need to read nodes attributes and remove all "data-test".

I have try in vue.config.js to use :

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
      })
  }
}

I know the transformation is done inside vue-template-compiler. How can I enter in compile hook ?

I have try to use preTransformNode in module but that fail.

Sources :


Solution

  • The main problem here is that you are working with vue-template-compiler documentation, but that package is the compiler for Vue 2!

    In Vue 3, compiler is split into multiple packages and is missing proper documentation as of now (or I was just unable to find it)

    Also there were significant changes in the API - instead of modules, you pass nodeTransforms (source) and transforms are not objects, just functions.

    Luckily for you, there is a interesting video on YT presented by Vue core member Rahul Kadyan which shows the exact use case you need (removing data-test attributes) - code

    So I guess the code should look like this:

    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
          })
      }
    }
    

    Note - the problem mentioned in comments (solution working with serve but throws errors on build) is caused by Vue CLI using thread-loader for production builds. The problem is that while using thread-loader, you can not pass a functions as part of Webpack config (see this warning in the docs) so setting parallel: false is required to make it work....

    Vite (Update - 22.06.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] : [],
              },
            },
          }),
        ]
      }
    })