Home > OS >  Sharing a folder between react & node typescript
Sharing a folder between react & node typescript

Time:02-18

I'm working on a React & Nodejs smart-mirror, both using TypeScript and using a shared directory to store the mirror's modules. The project structure is as follows;

└── root
   ├── api (node)
      ├── node_modules
   ├── client
      ├── node_modules
   ├── modules
      ├── moduleName
         ├── index.tsx
         ├── helper.ts
         ├── types.ts

The helper file contains an express route, which is dynamically loaded, the index is the react component and the types is shared. The api works works fine but the react app throws errors when the helper file contains the express router, or references the api code at all.

The react application then throws errors requiring modules inside the node_modules from the api when the helper code isn't referenced in the react app at all, only the index file. I have created this already without typescript but as soon as I added typescript the errors started to happen.

I have tried many different methods to exclude the helper files and even setting the react app to only load .tsx but I am still receiving the same errors.

index.tsx

import { useTheme } from '@mui/styles'
import React, { useEffect, useState } from 'react'

import Socket from 'socket'
import { Theme } from 'theme'

import useStyles from './styles'
import { AlertType } from './types'

const Alert = () => {
  const [alerts, setAlerts] = useState<Array<AlertType>>([])
  const theme: Theme = useTheme()
  const classes = useStyles(theme)

  useEffect(() => {
    const io = Socket('alert')
    let timeout: number
    io.on('SEND_ALERT', (alert: AlertType) => {
      setAlerts([...alerts, alert])
      timeout = window.setTimeout(() => {
        setAlerts(alerts.filter((a: AlertType) => a !== alert))
      }, alert.duration * 1000)
    })

    return () => {
      window.clearTimeout(timeout)
      io.disconnect()
    }
  }, [])

  return alerts.length ? (
    <div className={classes.container}>
      {alerts.map(({ message }: AlertType, index: number) => (
        <div className={classes.alert} key={`${message[0]}-${index}`}>
          <div className={classes.content}>{message}</div>
        </div>
      ))}
    </div>
  ) : null
}

export default Alert

helper.ts

import { Request, Response, Router } from 'express'
import { Namespace, Socket } from 'socket.io'
import { AlertType } from './types'

const router = Router()

const AlertRouter = (io: Namespace) => {
  router.get('/', (req: Request, res: Response) =>
    res.status(200).json({ message: 'Hello world!' })
  )

  io.on('connection', (client: Socket) => {
    client.on('SEND_ALERT', (alert: AlertType) => io.emit('SEND_ALERT', alert))
  })

  return router
}

export default AlertRouter

types.ts

export interface AlertType {
  message: string
  duration: number
}

Errors

Any help is much appreciated.

CodePudding user response:

In case anybody else comes across this issue, I have found a hack which I'm not keen on but it works for now.

I added the following to webpack.config.js

{
  plugins: {
    new webpack.ContextReplacementPlugin(
      /\/package-name\//,
      (data) => {
        delete data.dependencies[0].critical;
        return data;
      },
    ),
  },
  resolve: {
    fallback: {
      // list of failing modules required only in the api
      "crypto": false,
      "fs": false,
      "http": false,
      "path": false,
      "net": false,
      "querystring": false,
      "stream": false,
      "url": false,
      "util": false,
      "zlib": false
    }
  }
}
  • Related