3.0.0-rc.10
Node 10.6.0 / Yarn 1.9.2 / macOS 10.13.5
yarn serve
61.0.1
)[Vue warn]: Error in created hook: "TypeError: this.fetchData(...).then(...).catch(...).finally is not a function"
According to the MDN web docs, Promise.prototype.finally()
is supported natively in Firefox since 58
, so it should work, even without any polyfill.
Promise.prototype.finally()
does not work in Firefox (61.0.1
).
Not sure if I'm missing something obvious here – I'm not even sure if this is actually a bug or just a configuration issue (maybe I have to adjust my babel.config.js
in some way?). What is weird is that Promise.prototype.finally()
works in Safari when I run the same test app, which doesn't have native support for it apparently – so the polyfill seems to be working there. I can only reproduce the issue in Firefox. A friend has also confirmed the same issue in Firefox under Windows 10.
Oh, and sorry if this issue belongs somewhere else. Since I couldn't pin down if it's a Firefox bug, an issue with Babel or one with the @vue/app
preset (or just a configuration error on my end), it made the most sense to me to open it here first.
Hm, I remember coming across something like this a while ago when building a prototype with beta.3 or something.
We include a Promise polyfill with vue-cli by default. Maybe we have a weird situation where
finally
If so, 1.) would be an issue to solve in vue-cli, if 2.), which would be a problem with babel-polyfill / core.js, can't be resolved quickly.
According to this there's also es.promise.finally
, which I tried to add the following way:
module.exports = {
presets: [
['@vue/app', {
polyfills: ['es6.promise', 'es6.promise.finally', 'es6.array.iterator']
}]
]
}
Hoewever, this throws an error on build:
Cannot read property 'android' of undefined (While processing
: "/fake/path/vue-cli-promise-finally/node_modules/@vue/babel-preset-app/index.js")
at targetEnvironments.filter.environment (/fake/path/vue-cli-promise-finally/node_modules/@babel/preset-env/lib/index.js:75:
16)
Might also be related to this, will try that workaround out later.
Doing the following seems to work:
// babel.config.js
module.exports = {
presets: [
['@vue/app', { useBuiltIns: 'entry' }]
]
}
// src/main.js
import '@babel/polyfill'
[…]
It does increase the bundle size a bit (as expected), but that's not really an issue.
According to this comment from Brian Ng:
Yep, there's currently no
usage
mapping for.then
,.catch
or.finally
.
So, issue solved for me. Do you think you could mention this limitation of having useBuiltIns
in usage
mode somewhere in the readme of @vue/babel-preset-app
? I know that's an issue/limitation with @babel/preset-env
itself, but given that @vue/cli
is pretty much zero config by default and very beginner-friendly for people who haven't worked with webpack/Babel/etc. before, this is likely one of the first places they'd look if they encountered such an issue.
This is an issue in core-js
- its promise polyfill replaces the native Promise in Firefox, however according to author of core-js, it is doing it because Firefox's Promise implementation somehow fails a subclassing check so is technically not spec-compliant.
For now I've included es7.promise.finally
by default to fix this in Vue CLI.
@yyx990803
Thanks, I think that's a decent solution for now.
I had forgotten Promise.prototype.finally()
is not part of the ES6 spec, so the way I've tried to include the polyfill before (via es6.promise.finally
) obviously didn't work in hindsight. Time to switch useBuiltins
back to the default usage
mode. :)
@yyx990803
什么时候发布版本,这个finally
配了好久都没有配置好
Sorry to comment on a closed topic but I'm getting an error relative to the subject.
`This dependency was not found:
To install it, you can run: npm install --save core-js/modules/es7.promise.finally`
I'm getting the error AFTER the rc10, so I had to fix the version in rc10.
Happens to me also after installing vue-styled-components
`This dependency was not found:
core-js/modules/es7.promise.finally in ./src/main.js
To install it, you can run: npm install --save core-js/modules/es7.promise.finally`
Im still missing the finally on firefox..
using ['@vue/app', { useBuiltIns: 'entry' }]
fails to build with Unknown option: .useBuiltIns.
It's a nested array:
[['@vue/app', { useBuiltIns: 'entry' }]]
@LinusBorg yes, thanks, that fixed the build error! but I still dont have the finally on promises :\
can this issue be reopened? its still happening 😕
@mrodal and others:
It's been fixed for me since @yyx990803 has included es7.promise.finally
by default. I also don't have to use useBuiltIns: 'entry'
(except when building for Electron).
Feel free to check out the configuration in my project.
@mrodal if it's still happening for your, open a new issue with reproduction and a reference to this issue here.
I won't reopen this old one, it's outdated and I can't tell if the problem you describe actually exists in the way you say it does.
Its fixed, I upgraded vue to the latest version. Its weird, because the version I had (2.5.17) had the changes made by @yyx990803.. but anyways, its working now, thanks @mserajnik and @LinusBorg
I think you are confusing Vue ( currently 2.5.18) with vue-cli (3.3.0).
The latter is responsible for injecting the polyfill. The Vue version isn't important for that.
true, sorry, I also upgraded vue cli service and plugins from 3.0.3 to 3.0.4
@LinusBorg
Actually, latest Vue is 2.5.22
.
@mrodal
Latest version of @vue/cli-plugin-babel
and @vue/cli-service
is 3.3.0
; if you encounter any issues when building, I'd always recommend upgrading every dev dependency to the latest version (if you can) – chances are, the issue has been fixed. And as long as it's not a new major version, the chance of your build environment breaking should be pretty slim (and you can always roll back anyway if something goes wrong).
You can use a tool like updates to check for newer versions.
I'm a noobie, but have the same issue but without having vue-cli installed. I come from Laravel. Anyhow, here is one open question in StackOverflow. Perhaps someone can help me :)
Edit 1:
The issue lies in my installed package. Somehow it overwrites my promise
@mserajnik in Which Vue cli version were this bug had Fixed ?
@ahussein3 This has been fixed in v3.0.0-rc.11
in August 2018.
I still have this issue with:
in firefox:
Promise.resolve(42).finally(() => console.log('works'));
TypeError: Promise.resolve(...).finally is not a function[Learn More]
If I type this in the console on another website it works :(
Sorry to hear that.
If you can provide an actual reproduction of your issue we could investigate.
Saying "I have this problem" doesn't allow us to do that.
I realize that but the building environment is so complex I cannot allocate time for this currently, I solved my issue by just removing finally
and use catch/then.
If it helps I don't have ny es(6/7).promise.finally
in my current dependencies, if I understand correctly this was the fix applied, if so how is is supposed to be included ? do I need to have it explicitely in my package.json ?
@schmurfy:
If your project was created using vue-cli and you didn‘t make any manual changes to the build setup (e.g., change the Babel config in some way it would disable the usage of the es7.promise.finally
polyfill), it should work out of the box.
As for the reproducible example, see the one in my opening post. That‘s just an empty project created with vue-cli (a version before the fix).
You could go this approach as well and start isolating the issue – if a new/empty project works, try to figure out what change(s) in your project cause(s) it not to work.
If core-js
is used by any of your modules (i.e. Babel), that's the cause.
This code isn't present in the current version, but core-js
3.0.1 overrides the Promise prototype:
var FORCED = isForced(PROMISE, function () {
// correct subclassing with @@species support
var promise = PromiseConstructor.resolve(1);
var empty = function () { /* empty */ };
var FakePromise = (promise.constructor = {})[SPECIES] = function (exec) {
exec(empty, empty);
};
// unhandled rejections tracking support, NodeJS Promise without it fails @@species test
return !((IS_NODE || typeof PromiseRejectionEvent == 'function')
&& (!IS_PURE || promise['finally'])
&& promise.then(empty) instanceof FakePromise
// v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables
// https://bugs.chromium.org/p/chromium/issues/detail?id=830565
// we can't detect it synchronously, so just check versions
&& v8.indexOf('6.6') !== 0
&& userAgent.indexOf('Chrome/66') === -1);
});
Most helpful comment
This is an issue in
core-js
- its promise polyfill replaces the native Promise in Firefox, however according to author of core-js, it is doing it because Firefox's Promise implementation somehow fails a subclassing check so is technically not spec-compliant.For now I've included
es7.promise.finally
by default to fix this in Vue CLI.