Note dirty fix: https://github.com/6to5/6to5/issues/630#issuecomment-71982523 (EDIT: see comments below)
This is probably a common use case in webpack.
If using selfContained option in 6to5 v3, and if one wants to use the bluebird library (or their favourite Promise lib), the following doesn't work nicely anymore:
// ...
new webpack.ProvidePlugin({
'Promise': 'bluebird'
}),
// ...
It's a common use case to override a built-in with a third party library?
@sebmck Common use-case even before Promise became a built-in. webpack's ProvidePlugin is useful to automatically require on reserved free variables. Example: $ (jquery), React (react or react/addons), _ (lodash/underscore), etc
Currently I use expose-loader to include Bluebird. (e.g. require("expose?Promise!bluebird");.)
Although ProvidePlugin is a much cleaner way since it only affects inside webpack modules, but it just doesn't work in this case.
Just an update. Dirty fix mentioned at https://github.com/babel/babel/issues/630#issuecomment-71982523 will not work with v5.x. Since Promise object is now fetched via require('babel-runtime/core-js/promise');.
My workaround is to use some sort of bootstraping step:
// bootstrap.js
require('babel-runtime/core-js/promise').default = require('bluebird');
// ...
require('./app');
So, how do you use this "bootstrap"?
Where does it go?
Is it an entry .js file?
What if you have several entries in your app?
To create a bootstrap for each entry? Too dirty.
expose loader also doesn't work
The bootstrap method seems to work but it requires creating a bootstrap file for each webpack entry (i suppose).
For performing the bootstrap method on server do this
// use bluebird for promises
require('babel-runtime/core-js/promise').default = require('bluebird')
require('babel/register')
({
stage: 0,
plugins: ['typecheck'],
optional: ['runtime']
})
So, how do you use this "bootstrap"?
Where does it go?
Is it an entry .js file?
Yep, bootstrap.js is supposedly your new 'entry app'.
What if you have several entries in your app?
I haven't really thought about the multiple entries usecase.
But one approach I would do is this (untested):
overrides.js:
// apply global overrides stuff here
require('babel-runtime/core-js/promise').default = require('bluebird');
global.Promise = require('bluebird'); // extra override
Then load following plugin in your webpack.config.js:
new webpack.BannerPlugin(
";require('path/to/overrides.js');",
{
raw: true,
entryOnly: true // applied to only entries
})
More info: http://webpack.github.io/docs/list-of-plugins.html#bannerplugin
@Dashed Interesting thoughts. I might give it a try in case I split my app into several entries. Thanks.
Module not found: Error: Cannot resolve module 'babel-runtime/core-js/promise'
I got this error, when I put require('babel-runtime/core-js/promise').default = require('bluebird'); in my entry point.
@CrisLi webpack cannot find module babel-runtime. maybe you forgot to npm install?
@Dashed @halt-hammerzeit I haven't created any Babel plugins but I'm wondering if it would be possible to create one for redefining bluebird as native Promise. This would be great because then could just reference this plugin in .babelrc and would work for both client and server.
@dtothefp Well, any babel plugin will be called inside of require(babel/register) so there is a possibility that it may not work (but noone has tried).
According to the docs, maybe something like this could do it:
export default function ({ Plugin, types: t }) {
// apply global overrides stuff here
require('babel-runtime/core-js/promise').default = require('bluebird');
return new Plugin("foo-bar", {
visitor: {
// visitors
}
});
}
I won't try to roll out such a plugin because I have a base entry.js file anyway (with various utility stuff going on there)
But if you were compiling through Babel rather than using the register I'm assuming that code would be added to each file? Not sure if that is a problem? Anyhow if I had extra time in the day to build it I think this would be a cleaner solution to the problem rather than having to add boilerplate to every entry and/remember the webpack banner plugin for each client build
@dtothefp @halt-hammerzeit I haven't really tried babel-plugins stuff since it's considered experimental in 5.x; and it won't have first-class support until 6.x (see: https://github.com/babel/babel/issues/2168).
If there is a way to create such a plugin; would it be possible to do global pollution/overrides only once? It seems a plugin will be executed for every visited node in the AST.
for me it's working fine to write this into my webpack config
new webpack.ProvidePlugin({
'Promise': 'bluebird'
}),
in my entrypoint I have this line import 'babel-core/polyfill';
I'm using babel-core 5.8.25
@Dashed @halt-hammerzeit @timaschew any idea if these techniques work for Babel 6. I haven't upgraded yet and have this issue up on he loader but no reply https://github.com/babel/babel-loader/issues/143.
@dtothefp I haven't made the switch to 6.x yet; so I haven't really looked at what the migration path would look like.
I think everything is largely the same with the exception of setting up babel 6 in webpack config file(s).
If you're not planning on polluting globals with polyfills (i.e. using runtime in babel 5.x), this is the replacement for runtime: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-runtime
On the other hand, if you're fine with polluting the globals with polyfills (i.e. http://babeljs.io/docs/usage/polyfill/), then you can do globals.Promise = require('bluebird'); in your entry scripts.
Ok so based on the promise spec for babel's core.js -> promise library it will not provide adequate error handling as outlined in this informative article http://jamesknelson.com/are-es6-promises-swallowing-your-errors/
Which is evidently why Bluebird needs to be installed and used as the promise library of choice.
not sure if this extract from that link is relevant to pg-promise but i'll include it just incase :
"...After installing bluebird, you can make sure you know about unhandled rejections by adding the following three lines:
Promise.onPossiblyUnhandledRejection(function(error){
throw error;
});
And on the odd chance you do want to discard a rejection, just handle it with an empty catch, like so:
Promise.reject('error value').catch(function() {});
..."
So, since this is the first link in Google, here's a proper modern answer to this issue:
https://github.com/59naga/babel-plugin-transform-bluebird
@halt-hammerzeit would you be willing to update the readme to document alternatives? 馃槃
@dashed Haven't got it working in my project yet, still getting .promisifyAll is not a function in some places, while in other places it seems to work.
Maybe, when I make it all work with this plugin.
@myqianlan: it seems to work ! :smile:
Most helpful comment
Ok so based on the promise spec for babel's core.js -> promise library it will not provide adequate error handling as outlined in this informative article http://jamesknelson.com/are-es6-promises-swallowing-your-errors/
Which is evidently why Bluebird needs to be installed and used as the promise library of choice.
not sure if this extract from that link is relevant to pg-promise but i'll include it just incase :
"...After installing bluebird, you can make sure you know about unhandled rejections by adding the following three lines:
And on the odd chance you do want to discard a rejection, just handle it with an empty catch, like so:
..."