6

I am trying to set up my first Ruby on Rails 7 with a React app. I installed Ruby on Rails with the esbuild flag:

rails new project_name -d postgresql -j esbuild

I Yarn added react, react-dom and react-router-dom.

I also created a React './components' folder in my 'app/javascript' folder and I'm importing it into the application.js file which is the entry point for the esbuild build script in the package.json file.

// Entry point for the build script in your package.json
import "@hotwired/turbo-rails";
import "./controllers";
import "./components";

When I execute bin/dev, the server spins up properly and I get my project index page. However, esbuild throws the following error.

15:05:03 js.1   | started with pid 6552
15:05:03 js.1   | yarn run v1.22.10
15:05:03 js.1   | $ esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets --watch
15:05:03 js.1   | ✘ [ERROR] Could not resolve "./components"
15:05:03 js.1   |
15:05:03 js.1   |     app/javascript/application.js:4:7:
15:05:03 js.1   |       4 │ import "./components";
15:05:03 js.1   |         ╵        ~~~~~~~~~~~~~~
15:05:03 js.1   |
15:05:03 js.1   | 1 error
15:05:03 js.1   | [watch] build finished, watching for changes...

I don't understand why this statement can't be resolved when the import "./controllers"; statement functions just fine. I've looked through the esbuild documentation and searched for other posts here, but I can't seem to find anything that deals with this error.

Hopefully, I'm being dim and there's a simple solution.

My package.json file is below as well in case that is useful:

{
  "name": "app",
  "private": "true",
  "dependencies": {
    "@hotwired/stimulus": "^3.2.1",
    "@hotwired/turbo-rails": "^7.2.4",
    "esbuild": "^0.16.10",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.6.1"
  },
  "scripts": {
    "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets"
  }
}

I have tried changing the name of the components folder and using a different syntax:

import 'components';
import '/components';
import "./test";

etc... I've read through the esbuild documentation and tried completely building again from scratch and keep getting stuck with the same error.

I'm hoping this is a quick fix and someone less dense than I can help me see the light.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
baconsocrispy
  • 81
  • 2
  • 8

3 Answers3

1

I had the same problem and I resolved it(pun intended) by installing turbo-rails

npm i @hotwired/turbo-rails

0

The problem is that you probably haven't installed some packages that should be inside './components'.

Andres
  • 1,484
  • 19
  • 29
0

One solution is to use explicit paths. import "components/Foo" instead of longer paths like import "./app/javascript/components/Foo" are nicer to work with, but the longer pathnames should fix it. With the root of your app as app/javascript you may also need to explicitly import index or index.js, unless it gets resolved properly

import "./components/index";

For the index.js/x entry point of the React app.

Your build command currently looks good

"scripts": {
  "build": "esbuild app/javascript/application.js --bundle --sourcemap --outdir=app/assets/builds --public-path=assets"
}

You can use alias or shorter pathnames in your esbuild.json config file. Set the components prop to a shortened version like "./app/javascript/components".

{
  "alias": {
    "components": "./app/javascript/components",
  },
  "entryPoints": ["app/javascript/application.js"],
  "bundle": true,
  "outdir": "app/assets/builds",
  "publicPath": "assets",
  "sourcemap": true
}

If you're going to use Node.js it's a similar config

const { build } = require('esbuild');

build({
  entryPoints: ['app/javascript/application.js'],
  bundle: true,
  outdir: 'app/assets/builds',
  publicPath: 'assets',
  sourcemap: true,
  define: {
    'process.env.NODE_ENV': JSON.stringify('production'),
  },
  alias: {
    'components': './app/javascript/components',
  },
}).catch(() => process.exit(1));
hygtfrde
  • 130
  • 3