Webpack: "vuex requires a promise polyfill in this browser"

Created on 2 Feb 2017  路  17Comments  路  Source: vuejs-templates/webpack

Re-raising this as I don't think it was solved in #260

We should just be able to install babel-polyfill and then:

entry: {
  'babel-polyfill': 'babel-polyfill',
  app: './src/main.js'
},

But that's a no go.

Most helpful comment

No idea what I'm doing wrong, but I'm still getting the same error with @DevanB's final solution...

Error: [vuex] vuex requires a Promise polyfill in this browser.
  at webpack:///~/vuex/dist/vuex.js:214:0 <- index.js:34700

Edit: Got it working by adding es6-promise.auto.js to my karma.conf.js:

    files: [
      '../../node_modules/es6-promise/dist/es6-promise.auto.js',
      './index.js'
    ]

...Still not sure why import 'es6-promise/auto' doesn't work in Karma.

All 17 comments

The only way I could get this error to stop was by including this in the head of the index.html:

<!-- Script for polyfilling Promises on IE9 and 10 -->
<script src='https://cdn.polyfill.io/v2/polyfill.min.js'></script>

Hope there is a better solution, as I'm not pleased with this.

@jaredreich is that supposed to mean that the Babel polyfill doesnt work or that you don't have that option for some reason?

@DevanB so including the es6-promise polyfill in main.js as explained in #260 did not work?

Hey Linus thanks for the reply. Babel-polyfill is fine as I use it actively in other non-vue projects. My point was we shouldn't have to do something hacky like inserting a lone/non-stansard require/import at the top of main.js, using the webpack entry property should work. Unfortunately I don't know how this is a problem with vuex's setup, but it's definitely not a webpack or babel-polyfill issue.

If anyone else runs into this issue, I was able to get babel-polyfill working with this syntax:

entry: {
  app: [
    'babel-polyfill',
    './src/main.js'
  ]
},

@LinusBorg Yep, I added es6-promise to the top of main.js (like below), but still get the vuex error.

I tried putting the babel-polyfill in webpack.base.conf.js like below, but that didn't work either.

require('es6-promise').polyfill()

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
import { sync } from 'vuex-router-sync'
import VueHead from 'vue-head'

sync(store, router)
Vue.use(VueHead)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
})
entry: {
  app: [
    'babel-polyfill',
    './src/main.js'
  ]
},

The Problem is that import statements always get hoisted to the very top of the file, before any other code.
So while the require comes first in your code, it runs after the import for Vuex has run.

Solution: use require() for Vuex as well.

First, thanks for the help @LinusBorg!

I didn't know that. So import statements have the same "hoisting" like variables and would "out-rank" a require() statement?

I changed the require to a ES6 import statement (below), but no luck. So then I replaced the import statements with require statements (like below), and I received a vuex error (I assume having to do because of the require statement solution):

TypeError: store.registerModule is not a function. (In 'store.registerModule', 'store.registerModule' is undefined)

import { polyfill } from 'es6-promise'
polyfill()

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
import { sync } from 'vuex-router-sync'
import VueHead from 'vue-head'

sync(store, router)
Vue.use(VueHead)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
})
require('es6-promise').polyfill()

import Vue from 'vue'
import App from './App'
import router from './router'
var store = require('./store')
import { sync } from 'vuex-router-sync'
import VueHead from 'vue-head'

sync(store, router)
Vue.use(VueHead)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
})

@DevanB
https://github.com/stefanpenner/es6-promise#auto-polyfill
try

import 'es6-promise/auto'

@limichange that worked!

Again, thanks @LinusBorg for the help also (and the new knowledge!)

I'll be glad to put in a PR for some documentation on the process, if wanted. This was the final solution:

import 'es6-promise/auto'

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
import { sync } from 'vuex-router-sync'
import VueHead from 'vue-head'

sync(store, router)
Vue.use(VueHead)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
})

No idea what I'm doing wrong, but I'm still getting the same error with @DevanB's final solution...

Error: [vuex] vuex requires a Promise polyfill in this browser.
  at webpack:///~/vuex/dist/vuex.js:214:0 <- index.js:34700

Edit: Got it working by adding es6-promise.auto.js to my karma.conf.js:

    files: [
      '../../node_modules/es6-promise/dist/es6-promise.auto.js',
      './index.js'
    ]

...Still not sure why import 'es6-promise/auto' doesn't work in Karma.

it also works for babel-polyfill.
files: [ '../../node_modules/babel-polyfill/dist/polyfill.js', './index.js' ]

You can also just add import "es6-promise/auto" to test/unit/index.js.

Using [email protected] worked for me in a Webpack setup :)

new webpack.ProvidePlugin({
    Backbone: 'backbone',
    _: 'underscore',
    Promise: 'es6-promise-promise',
    Vue: 'vue',
    Vuex: 'vuex'
})

I just used files: ['../../node_modules/babel-polyfill/dist/polyfill.js','./index.js'], in my karma conf. It covered more hard to debug es6 issues. That is, hard to debug in the finicky PhantomJS debug/developer tools.

If you don't use SSR/Nuxt, running components independently can lead to unexpected states that you would frequently encounter in unit tests.

if you use axios npm install es6-promise. And then before axios scriptput this ---> require('es6-promise').polyfill();

Still have the same problem with ie11 SCRIPT 1010: expected identifier app.js (8549,1)

below is my main.js file
import 'es6-promise/auto'
import 'babel-polyfill'
import Vue from "vue";
import App from "./App";
import "bootstrap";
import "jquery"
import * as firebase from "firebase";
import { store } from "../store/store";

I solved it by add babel-polyfill like this:

import Vuex from 'vuex'
import Vue from 'vue'

require('babel-polyfill')

Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

export default store
Was this page helpful?
0 / 5 - 0 ratings