Webpack: Object destructuring in v-bind

Created on 24 Oct 2017  路  9Comments  路  Source: vuejs-templates/webpack

Passing props like this...

<puppy v-bind="{ ...dogLikeQualities }"></puppy>

Produces this error...

Module build failed: Error
    at Node.transpile (/home/mauro/code/sandbox/webpack/node_modules/vue-template-es2015-compiler/buble.js:12676:11)
    at /home/mauro/code/sandbox/webpack/node_modules/vue-template-es2015-compiler/buble.js:5864:59
    at Array.forEach (<anonymous>)
    at Node.transpile (/home/mauro/code/sandbox/webpack/node_modules/vue-template-es2015-compiler/buble.js:5864:10)
    at Node.transpile (/home/mauro/code/sandbox/webpack/node_modules/vue-template-es2015-compiler/buble.js:6553:28)
    at /home/mauro/code/sandbox/webpack/node_modules/vue-template-es2015-compiler/buble.js:5864:59
    at Array.forEach (<anonymous>)
    at Node.transpile (/home/mauro/code/sandbox/webpack/node_modules/vue-template-es2015-compiler/buble.js:5864:10)
    at Node.transpile (/home/mauro/code/sandbox/webpack/node_modules/vue-template-es2015-compiler/buble.js:6553:28)
    at /home/mauro/code/sandbox/webpack/node_modules/vue-template-es2015-compiler/buble.js:5864:59
    at Array.forEach (<anonymous>)
    at Node.transpile (/home/mauro/code/sandbox/webpack/node_modules/vue-template-es2015-compiler/buble.js:5864:10)
    at Node.transpile (/home/mauro/code/sandbox/webpack/node_modules/vue-template-es2015-compiler/buble.js:5991:28)
    at /home/mauro/code/sandbox/webpack/node_modules/vue-template-es2015-compiler/buble.js:5864:59
    at Array.forEach (<anonymous>)

Here's a project freshly built from this template that demos this issue: https://github.com/maurop123/object-destructure

The master branch only has the code changes replicating this issue, and the dev branch has the diff attempts to resolve it.

Most helpful comment

Works! All I had to do was add this to bottom of my vue-loader.conf.js

module.exports = {
  ...
  buble: {
    objectAssign: 'Object.assign',
    transforms: {  // turn off the `with` removal
      stripWith: false
    }
  }
}

Thanks!

All 9 comments

Vue-loader uses buble under the hood to get rid of the with this { ... } code that the template compiler produces.

You probably have to set the objectAssign option for buble in the vue-loader config as shown here:

https://vue-loader.vuejs.org/en/options.html#buble

Note that, as mentioned in that link, you still have to provide a polyfill for Object.assign to support older browsers (IE)

Ok I'll try this out and report back

Works! All I had to do was add this to bottom of my vue-loader.conf.js

module.exports = {
  ...
  buble: {
    objectAssign: 'Object.assign',
    transforms: {  // turn off the `with` removal
      stripWith: false
    }
  }
}

Thanks!

Just made the PR here: https://github.com/vuejs-templates/webpack/pull/1017

If it helps, I can make it on the other templates, too.

@maurop123 @LinusBorg I added the buble config in my vue-loader config, but I still have an error:

ERROR in ./node_modules/vue-loader/lib/template-compiler?{"id":"data-v-b7762b10","hasScoped":false,"buble":{"objectAssign":"Object.assign","transforms":{"stripWith":false}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0&bustCache!./src/components/my-component.vue Module build failed: SyntaxError: 'with' in strict mode (1:26)

and I use babel-preset-stage-3 which includes babel-plugin-transform-object-rest-spread.

Is there anything else I should do to make it work?
Thank you

You also Set stripWith: false which you certainly should not do.

@LinusBorg it works, thank you. (This was the occasion for me to discover bubl茅). So in which case would you turn off the stripWith option?

I don't have a concrete use case for that. It's basically a fallback to the behaviour vue-loader had before webpack 2 came along and all es modules were in strict mode by default. ou probably will never have a use for this option.

For someone who will visit here, this is what worked for me
./build/vue-loader.conf.js

'use strict'
const utils = require('./utils')
const config = require('../config')
const isProduction = process.env.NODE_ENV === 'production'
const sourceMapEnabled = isProduction
  ? config.build.productionSourceMap
  : config.dev.cssSourceMap

module.exports = {
  loaders: utils.cssLoaders({
    sourceMap: sourceMapEnabled,
    extract: isProduction
  }),
  cssSourceMap: sourceMapEnabled,
  cacheBusting: config.dev.cacheBusting,
  transformToRequire: {
    video: ['src', 'poster'],
    source: 'src',
    img: 'src',
    image: 'xlink:href'
  },
  buble: {
    objectAssign: 'Object.assign'
  }
}

and example of template of my component

<template>
  <!--
    // replaced @input="$emit('input', $event.target.value)" with
    // v-on="$listeners", need testing
    // see more here
    // http://blog.webf.zone/vue-js-considerations-and-tricks-fa7e0e4bb7bb
  -->
  <div>
    <label class="form-label">{{ getLabel | capitalize }}</label>
    <input
      v-tooltip="getTooltipContent"
      :bind="$attrs"
      :type="type"
      :value="value"
      :placeholder="getPlaceHolder"
      :class="getClass"
      class="form-input"
      data-vv-validate-on="none"
      v-on="{
        ...$listeners,
        input: event => $emit('input', event.target.value)
      }">
  </div>
</template>
Was this page helpful?
0 / 5 - 0 ratings