1

I'm using Loadable components in my react Server side rendering site. It works well in localhost, then I tried to run the site in google cloud function I am getting The "path" argument must be of type string. Received undefined error.

Here I have added the code I used to call loadable-stats.json file

   const nodeStats = path.resolve(
    __dirname,
    '../../public/dist/async-node/loadable-stats.json',
  )

  const webStats = path.resolve(
    __dirname,
    '../../public/dist/web/loadable-stats.json',
  )

Here is the screenshot of my code structure

My firebase.json file

    {
  "hosting": {
    "public": "public",
    "rewrites": [
      {
        "source": "**",
        "function": "supercharged"
      }
    ]
  }
}

Here I have added server index.js file

import express from 'express';
import renderer from './server/renderer';
import createStore from './server/createStore';
import Routes from './public/Routes'
import {matchRoutes} from 'react-router-config';

const functions = require('firebase-functions');


import path from 'path'

const app = express();

app.use(express.static(path.join(__dirname, '../public')))


app.get('*.js', function (req, res, next) {
  req.url = req.url + '.gz';
  res.set('Content-Encoding', 'gzip');
  next();
});
function handleRender(req, res) {
  const store = createStore(req)

  //incoming request path or page that user is trying to fetch
  //and it's going to look at our router configuration object
  //and deside what set of component need to render
  const promises =   matchRoutes(Routes, req.path).map(({route}) => {
    return route.loadData? route.loadData(store, req.path) : null;
  });

Promise.all(promises).then(() => {
  res.set('Cache-Control', 'public, max-age=600, s-maxage=1200');
  // Send the rendered page back to the client.
  res.send(renderer(req, store));
});
}

// This is fired every time the server-side receives a request.
app.use(handleRender);

//const port = 3000;
//app.listen(port);
exports.supercharged = functions.https.onRequest(app);

My webpack config file

      import path from 'path'
  import nodeExternals from 'webpack-node-externals'
  import LoadablePlugin from '@loadable/webpack-plugin'
  import MiniCssExtractPlugin from 'mini-css-extract-plugin'

  const DIST_PATH = path.resolve(__dirname, 'public/dist')
  const production = process.env.NODE_ENV === 'production'
  const development =
    !process.env.NODE_ENV || process.env.NODE_ENV === 'development'

  const getConfig = target => ({
    name: target,
    mode: development ? 'development' : 'production',
    target,
    entry: `./src/public/index-${target}.js`,
    module: {
      rules: [
        {
          test: /\.js?$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              caller: { target },
            },
          },
        },
        {
          test: /\.css$/,
          use: [
            {
              loader: MiniCssExtractPlugin.loader,
            },
            'css-loader',
          ],
        },
      ],
    },
    externals:
      target === 'async-node'
        ? ['@loadable/component', nodeExternals()]
        : undefined,
    output: {
      path: path.join(DIST_PATH, target),
      filename: production ? '[name]-bundle-[chunkhash:8].js' : '[name].js',
      publicPath: `/dist/${target}/`,
      libraryTarget: target === 'async-node' ? 'commonjs2' : undefined,
    },
    plugins: [new LoadablePlugin(), new MiniCssExtractPlugin()],
  })

  export default [getConfig('web'), getConfig('async-node')]

This code works when I run my project using NODE_ENV=production node functions/main.js. This code is not working when I run in google cloud function firebase serve --only functions,hosting.

Suggession or advice will be more helpful for me.

Pulikese
  • 33
  • 4
  • Can you share your firebase config for the functions? – guillaume blaquiere May 08 '21 at 18:08
  • @guillaumeblaquiere Hi, I updated my question added firebase configuration – Pulikese May 09 '21 at 09:51
  • My assumption is that your server directory is deployed, alone, no sibling/parent directory are uploaded in the same time and thus, the files are missing in the Cloud Functions. That's for the issue. Now, to fix that, except copying/moving the public dir in your server dir, at least at deployment time, I don't see any other workaround – guillaume blaquiere May 09 '21 at 11:43
  • If I removed loadable component related code in webpack and from JS files, Everything is working fine in deployment. I will copy public dir into server dir and let you know what happens – Pulikese May 09 '21 at 12:06
  • @guillaumeblaquiere I removed all firebase config class from project and initialised again, I'm not getting the above error but I'm getting new error "UnhandledPromiseRejectionWarning: Error: Invalid hook call" If I deleted node_modules from functions folder this error is gone but in deployment I couldn't deploy – Pulikese May 12 '21 at 16:12
  • Does this help you for this new error? https://stackoverflow.com/questions/62185865/webpack-external-react-causes-react-hooks-error – Roger May 19 '21 at 15:40
  • @Roger I don't understand that answer, Do I need to create bundle for server and client side? – Pulikese May 20 '21 at 14:21
  • @MathanKumar The path variable is undefined when you deploy the code, it could be that the `path.resolve(...` function is not finding a valid route. Verify that the file system in your Google Cloud Function looks like the one in your screenshot with the code example [shown in the documentation](https://cloud.google.com/functions/docs/concepts/exec#file_system) . – Álvaro Zamora Jun 04 '21 at 14:44

0 Answers0