Version Info
firebase-tools: 3.18.4
firebase-admin 5.12.0
firebase-functions: 1.0.2
Platform Information
Windows
When I run the firebase serve command on an isomorphic React implementation, I get the following stack message every time I use a route, I'm using Express.js, to render the react views as seen on the functions-samples repo
TypeError: handler is not a function
at cloudFunction (~\Project\node_modules\firebase-functions\lib\providers\https.js:37:41)
at app.use (~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\@google-cloud\functions-emulator\src\supervisor\worker.js:142:11)
at Layer.handle [as handle_request] (~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\index.js:317:13)
at ~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\index.js:284:7
at Function.process_params (~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\index.js:335:12)
at next (~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\index.js:275:10)
at app.use (~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\@google-cloud\functions-emulator\src\supervisor\worker.js:114:7)
at Layer.handle [as handle_request] (~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\index.js:317:13)
Already uninstalled the emulator and re-install it, also deleted the config file ~/.config/configstore/@google-cloud/functions-emulator
Could you share your functions code?
import React from 'react'
import { renderToString } from 'react-dom/server'
import express from 'express'
import helmet from 'helmet'
import morgan from 'morgan'
import status from 'http-status'
import { default as Bundle } from 'Bundle'
import template from './template'
const ServerApp = React.createFactory(Bundle)
const renderApplication = (url, res, initialState) => {
const html = ReactDOMServer.renderToString(ServerApp({ url: url, context: {}, initialState }))
const templatedHTML = template({ body: html, initialState: JSON.stringify(initialState) })
res.status(status.OK).send(templatedHTML)
}
const app = express()
app.use(helmet())
app.use(morgan('dev'))
app.get('/favicon.ico', (req, res) => {
return res.send(204)
})
app.get('/', (req, res) => {
return renderApplication(req.url, res)
})
export default app
const functions = require('firebase-functions');
const app = require('./dist/ssr.bundle').default;
exports.app = functions.https.onRequest(app);
I am actually transiling the code with webpack & babel
It seems like the error comes from this line:
exports.app = functions.https.onRequest(app);
It is complaining that app is not a function. Could you add a console log above that line to print out what app is and share what you see?
info: undefined
This is really revealing, I will get back to my transpiled code, and try to figure out how come the bundle is not returning what I expected.
Thank you so much for your help!
The problem occurred because I forgot to add the libraryTarget: "commonjs2" option on the webpack config file
const config = {
entry: ['./src/index.js'],
target: 'node',
externals: [nodeExternals()],
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'ssr.bundle.js',
libraryTarget: 'commonjs2'
},
module: {
rules: [
{
test: /\.js/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
babelrc: true,
}
}
}
]
},
...
}
Glad you figured it out!
Most helpful comment
The problem occurred because I forgot to add the libraryTarget: "commonjs2" option on the webpack config file