Reputation: 21
A bit of an introduction, currently (at the time I wrote this) Firebase functions does not support features like async and await from a more recent version of node. I am trying to overcome this by transpiling my code to the node version they currently support.
I am using webpack 3 to bundle my react.js web application. I have set up two separate configurations -one for development and the other production. I use a third confirguration to execute as a second task on production pipiline to take cloudfunctions.js
and spit it out to the deployment dir functions/index.js
using babel to transpile the code,
Instead of describing the transpile requirements in a .babelrc, I am adding those details using webpack to the options configuration object in inside the module in rules.
I've been successful transpiling the code, yet Firebase keeps complaining about 'firebase' not being defined. I've narrowed down the trigger of this error to the very first line of code which is an import.
Any suggestion that can point me to the right direction is truly appreciated.
import functions from ''firebase-functions';
As a matter of fact, I've tried Commonjs (using require) and made other attempts at ES6 import/exports.
Package.json:
{
"scripts": {
"start":"node ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack/dev.config.js",
"build": "cross-env NODE_ENV=production node ./node_modules/webpack/bin/webpack.js --config webpack/prod.config.js"
},
"dependencies": {
"@babel/polyfill": "^7.0.0-beta.40",
"firebase-admin": "^5.5.1",
"firebase-functions": "^0.7.3",
},
"devDependencies": {
"@babel/cli": "^7.0.0-beta.40",
"@babel/core": "^7.0.0-beta.40",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.40",
"@babel/preset-env": "^7.0.0-beta.40",
"babel-loader": "^8.0.0-beta.0",
"babel-preset-react": "^6.24.1",
"cross-env": "^5.1.3",
"generate-json-webpack-plugin": "^0.2.2",
"uglifyjs-webpack-plugin": "^1.1.8",
"webpack": "^3.10.0",
"webpack-merge": "^4.1.1"
}
}
functions.config.js (webpack)
const
path = require('path'),
pkg = require('../package'),
GenerateJsonPlugin = require('generate-json-webpack-plugin'),
UglifyJSPlugin = require('uglifyjs-webpack-plugin'),
webpack = require('webpack');
const externals = [
'firebase-admin',
'firebase-functions'
]
const genPackage = () => ({
name : 'functions',
private : true,
main : 'index.js',
license : 'MIT',
dependencies : externals.reduce( (acc, name) => Object.assign({}, acc, { [name]: pkg.dependencies[name] || pkg.devDependencies[name] }), {} )
})
module.exports = {
entry : [
'@babel/polyfill',
path.join(__dirname, '../cloudfunctions.js')
],
output : {
path : path.join(__dirname, '../functions/'),
filename : 'index.js'
},
module : {
rules: [
{
test : /\.js$/,
loader : 'babel-loader',
options :
{
presets : [
[
'@babel/env',
{
option : {
targets : {
node : '6.11.5'
}
}
}
]
],
plugins: [
'@babel/plugin-proposal-object-rest-spread'
]
}
,
exclude : /node_modules/
}
]
},
externals : externals.reduce( (acc, name) => Object.assign({}, acc, { [name]: true }), {} ),
plugins : [
new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) }),
new UglifyJSPlugin(),
new GenerateJsonPlugin('package.json', genPackage())
]
}
Environtment
Expected Behaviour
Actual Behaviour
Transpiles succesfully.
Continue receiving this log with the same error after hitting the firebase deploy --only functions
command:
i deploying functions
i functions: ensuring necessary APIs are enabled...
+ functions: all necessary APIs are enabled
i functions: preparing functions directory for uploading...
Error: Error occurred while parsing your function triggers.
ReferenceError: firebase is not defined
at Object.module.exports (C:\Users\Andrew Redican\Compass\functions\index.js:9040:18)
at __webpack_require__ (C:\Users\Andrew Redican\Compass\functions\index.js:20:30)
at Object.module.exports (C:\Users\Andrew Redican\Compass\functions\index.js:8967:17)
at __webpack_require__ (C:\Users\Andrew Redican\Compass\functions\index.js:20:30)
at Object.<anonymous> (C:\Users\Andrew Redican\Compass\functions\index.js:3687:18)
at __webpack_require__ (C:\Users\Andrew Redican\Compass\functions\index.js:20:30)
at C:\Users\Andrew Redican\Compass\functions\index.js:63:18
at Object.<anonymous> (C:\Users\Andrew Redican\Compass\functions\index.js:66:10)
at Module._compile (module.js:635:30)
at Object.Module._extensions..js (module.js:646:10)
cloundFunctions.js [input]
let functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
functions/index.js [output]
I have not included outfile since unmifinify version is 9049 lines of code long, while minified is not legibile.
I've Tried
I am obviosly missing something, but I've went over this article/repo several times now.
Other Notes
I am trying to get away from typescript and dealing promises' callback hell as far as I can. I am also trying not to rely directly on npm to run command directly but rather take advantage of webpack.
Upvotes: 0
Views: 852
Reputation: 21
I was able have webpack use babel to transpile code to functions/index.js. I figured out the problem.
When using webpack, make sure you specify output.libraryTarget to 'umd'.
Below is the webpack confg file:
const
path = require('path'),
pkg = require('../package'),
GenerateJsonPlugin = require('generate-json-webpack-plugin');
const
externals = [
'firebase-admin',
'firebase-functions'
],
genPackage = () => ({
name : 'functions',
private : true,
dependencies: externals.reduce(
(acc, name) =>
Object.assign({}, acc, {
[name]:
pkg.dependencies[name] ||
pkg.devDependencies[name]
}),
{}
)
});
module.exports = {
entry : [
'babel-polyfill',
'./cloudfunctions.js'
],
output: {
path : path.resolve(__dirname,'../functions'),
filename : 'index.js',
libraryTarget : 'umd'
},
module : {
rules : [
{
exclude : /node_modules/,
loader : 'babel-loader',
query : {
presets : [ 'babel-preset-env' ]
}
}
]
},
resolve: {
extensions: ['.js']
},
node: {
fs : 'empty',
net : 'empty',
tls : 'empty'
},
externals: externals.reduce(
(acc, name) => Object.assign({}, acc, { [name]: true }),{}
),
plugins: [
new GenerateJsonPlugin('package.json', genPackage())
]
};
Cheers!
Upvotes: 1