-
Notifications
You must be signed in to change notification settings - Fork 759
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document Support for Esbuild #1149
Comments
for me not work |
Going by the README, it seems like providing your own const ReactRailsUJS = require("react_ujs");
import * as Components from "./components";
ReactRailsUJS.getConstructor = (className) => Components[className]; With export { default as Component1 } from "./components/Component1";
export { default as Component2 } from "./components/Component2";
export { default as Component3 } from "./components/Component3"; |
Not working |
Here's what I got working:
const path = require('path')
const ImportGlobPlugin = require('esbuild-plugin-import-glob').default;
const esbuild = require("esbuild")
esbuild.build({
entryPoints: ["application.js"],
bundle: true,
outdir: path.join(process.cwd(), "app/assets/builds"),
absWorkingDir: path.join(process.cwd(), "app/javascript"),
watch: true,
minify: false,
plugins: [
ImportGlobPlugin()
],
}).catch(() => process.exit(1))
// NOTE: I am using Typescript and tsx files here. Change for your setup.
import * as Components from "./components/**/*.tsx"
let componentsContext = {}
Components.filenames.forEach((fileName, i) => {
let cleanName = fileName.replace("./components/", "").replace(".tsx", "")
componentsContext[cleanName] = Components.default[i].default
})
const ReactRailsUJS = require("react_ujs")
console.log(ReactRailsUJS)
ReactRailsUJS.getConstructor = (name) => {
return componentsContext[name]
}
ReactRailsUJS.handleEvent('turbo:load', ReactRailsUJS.handleMount, false);
ReactRailsUJS.handleEvent('turbo:frame-load', ReactRailsUJS.handleMount, false);
ReactRailsUJS.handleEvent('turbo:before-render', ReactRailsUJS.handleUnmount, false); The key is globbing your files through the plugin, building up your own context object, and then providing your own custom |
I bet there are nicer approaches, but one that worked for me (heavily inspired by @multiplegeorges) with a fresh rails7 & esbuild app is: app/javascript/components/index.js
@multiplegeorges's approach was throwing a warning for me: working example: https://github.com/cionescu/rails-7-new-esbuild/blob/e50cdf3bd790ba26ffcf5bff7f0596aac4d1173c/app/javascript/components/index.js |
I'm using the related project webpacker-react and tried it on a test project on rails 7 with esbuild (jsbundling-rails). apart adding lodash in package.json it work out the box. see https://github.com/renchap/webpacker-react Perhaps it could help to modify this project. |
@net1957 So you are running webpacker and esbuild at the same time ? |
@navidemad No, I dropped webpacker in favor of esbuild, but webpacker-react don't depend on webpacker. The name is a little misleading. this gem and webpacker-react resolve the same problem in Rails with the same interface in controllers and views |
I'm maintaining What's the advantage of moving away from webpacker? I just updated the comparison: rails/jsbundling-rails#79. |
this one working fine with me import components from './react/**/**.tsx';
let componentsContext = {};
components.forEach(component => {
const name = Object.keys(component)[0];
componentsContext[name] = component[name];
});
ReactRailsUJS.getConstructor = name => {
return componentsContext[name];
};
ReactRailsUJS.handleEvent('turbo:load', ReactRailsUJS.handleMount, false);
ReactRailsUJS.handleEvent('turbo:frame-load', ReactRailsUJS.handleMount, false);
ReactRailsUJS.handleEvent('turbo:before-render', ReactRailsUJS.handleUnmount, false); |
Hi everybody, Shakapacker supports esbuild: https://github.com/shakacode/shakapacker/blob/master/docs/using_esbuild_loader.md |
Big thanks to @multiplegeorges and @cionescu for the workaround, I managed to get components loaded and working after cloning @cionescu's example, however it seems to choke on prerender:
Click to expand and see the full backtrace``` Encountered error "#" when prerendering Clock with {"foo":"bar"} eval (eval at ((execjs):36:8), :6:45) eval (eval at ((execjs):36:8), :18:13) (execjs):36:8 (execjs):54:14 (execjs):1:40 Object. ((execjs):1:58) Module._compile (node:internal/modules/cjs/loader:1103:14) Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10) Module.load (node:internal/modules/cjs/loader:981:32) Function.Module._load (node:internal/modules/cjs/loader:822:12) /usr/local/bundle/gems/execjs-2.8.1/lib/execjs/external_runtime.rb:39:in `exec' /usr/local/bundle/gems/execjs-2.8.1/lib/execjs/external_runtime.rb:21:in `eval' /usr/local/bundle/gems/react-rails-2.6.1/lib/react/server_rendering/exec_js_renderer.rb:39:in `render_from_parts' /usr/local/bundle/gems/react-rails-2.6.1/lib/react/server_rendering/exec_js_renderer.rb:20:in `render' /usr/local/bundle/gems/react-rails-2.6.1/lib/react/server_rendering/bundle_renderer.rb:40:in `render' /usr/local/bundle/gems/react-rails-2.6.1/lib/react/server_rendering.rb:27:in `block in render' /usr/local/bundle/gems/connection_pool-2.2.5/lib/connection_pool.rb:63:in `block (2 levels) in with' /usr/local/bundle/gems/connection_pool-2.2.5/lib/connection_pool.rb:62:in `handle_interrupt' /usr/local/bundle/gems/connection_pool-2.2.5/lib/connection_pool.rb:62:in `block in with' /usr/local/bundle/gems/connection_pool-2.2.5/lib/connection_pool.rb:59:in `handle_interrupt' /usr/local/bundle/gems/connection_pool-2.2.5/lib/connection_pool.rb:59:in `with' /usr/local/bundle/gems/react-rails-2.6.1/lib/react/server_rendering.rb:26:in `render' /usr/local/bundle/gems/react-rails-2.6.1/lib/react/rails/component_mount.rb:74:in `prerender_component' /usr/local/bundle/gems/react-rails-2.6.1/lib/react/rails/component_mount.rb:38:in `block in react_component' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/helpers/capture_helper.rb:45:in `block in capture' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/helpers/capture_helper.rb:209:in `with_output_buffer' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/helpers/capture_helper.rb:45:in `capture' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/helpers/tag_helper.rb:338:in `content_tag' /usr/local/bundle/gems/react-rails-2.6.1/lib/react/rails/component_mount.rb:57:in `react_component' /usr/local/bundle/gems/react-rails-2.6.1/lib/react/rails/view_helper.rb:21:in `react_component' /workspace/app/views/main/index.html.erb:6:in `_app_views_main_index_html_erb___4033424673020032686_24280' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/base.rb:244:in `public_send' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/base.rb:244:in `_run' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/template.rb:157:in `block in render' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/notifications.rb:208:in `instrument' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/template.rb:361:in `instrument_render_template' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/template.rb:155:in `render' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/renderer/template_renderer.rb:65:in `block (2 levels) in render_template' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/notifications.rb:206:in `block in instrument' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/notifications/instrumenter.rb:24:in `instrument' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/notifications.rb:206:in `instrument' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/renderer/template_renderer.rb:60:in `block in render_template' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/renderer/template_renderer.rb:75:in `block in render_with_layout' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/notifications.rb:206:in `block in instrument' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/notifications/instrumenter.rb:24:in `instrument' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/notifications.rb:206:in `instrument' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/renderer/template_renderer.rb:74:in `render_with_layout' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/renderer/template_renderer.rb:59:in `render_template' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/renderer/template_renderer.rb:11:in `render' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/renderer/renderer.rb:61:in `render_template_to_object' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/renderer/renderer.rb:29:in `render_to_object' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/rendering.rb:117:in `block in _render_template' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/base.rb:270:in `in_rendering_context' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/rendering.rb:116:in `_render_template' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal/streaming.rb:216:in `_render_template' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/rendering.rb:103:in `render_to_body' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal/rendering.rb:46:in `render_to_body' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal/renderers.rb:142:in `render_to_body' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/abstract_controller/rendering.rb:25:in `render' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal/rendering.rb:30:in `render' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal/instrumentation.rb:22:in `block (2 levels) in render' /usr/local/lib/ruby/3.1.0/benchmark.rb:311:in `realtime' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/core_ext/benchmark.rb:14:in `ms' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal/instrumentation.rb:22:in `block in render' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal/instrumentation.rb:91:in `cleanup_view_runtime' /usr/local/bundle/gems/activerecord-7.0.2.3/lib/active_record/railties/controller_runtime.rb:34:in `cleanup_view_runtime' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal/instrumentation.rb:21:in `render' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal/implicit_render.rb:35:in `default_render' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal/basic_implicit_render.rb:6:in `block in send_action' :90:in `tap' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/abstract_controller/base.rb:214:in `process_action' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal/rendering.rb:53:in `process_action' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/abstract_controller/callbacks.rb:234:in `block in process_action' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:118:in `block in run_callbacks' /usr/local/bundle/gems/react-rails-2.6.1/lib/react/rails/controller_lifecycle.rb:31:in `use_react_component_helper' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:127:in `block in run_callbacks' /usr/local/bundle/gems/actiontext-7.0.2.3/lib/action_text/rendering.rb:20:in `with_renderer' /usr/local/bundle/gems/actiontext-7.0.2.3/lib/action_text/engine.rb:69:in `block (4 levels) in ' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:127:in `instance_exec' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:127:in `block in run_callbacks' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:138:in `run_callbacks' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/abstract_controller/callbacks.rb:233:in `process_action' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal/rescue.rb:22:in `process_action' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal/instrumentation.rb:67:in `block in process_action' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/notifications.rb:206:in `block in instrument' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/notifications/instrumenter.rb:24:in `instrument' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/notifications.rb:206:in `instrument' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal/instrumentation.rb:66:in `process_action' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal/params_wrapper.rb:259:in `process_action' /usr/local/bundle/gems/activerecord-7.0.2.3/lib/active_record/railties/controller_runtime.rb:27:in `process_action' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/abstract_controller/base.rb:151:in `process' /usr/local/bundle/gems/actionview-7.0.2.3/lib/action_view/rendering.rb:39:in `process' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal.rb:188:in `dispatch' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_controller/metal.rb:251:in `dispatch' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/routing/route_set.rb:49:in `dispatch' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/routing/route_set.rb:32:in `serve' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/journey/router.rb:50:in `block in serve' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/journey/router.rb:32:in `each' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/journey/router.rb:32:in `serve' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/routing/route_set.rb:850:in `call' /usr/local/bundle/gems/warden-1.2.9/lib/warden/manager.rb:36:in `block in call' /usr/local/bundle/gems/warden-1.2.9/lib/warden/manager.rb:34:in `catch' /usr/local/bundle/gems/warden-1.2.9/lib/warden/manager.rb:34:in `call' /usr/local/bundle/gems/rack-2.2.3/lib/rack/tempfile_reaper.rb:15:in `call' /usr/local/bundle/gems/rack-2.2.3/lib/rack/etag.rb:27:in `call' /usr/local/bundle/gems/rack-2.2.3/lib/rack/conditional_get.rb:27:in `call' /usr/local/bundle/gems/rack-2.2.3/lib/rack/head.rb:12:in `call' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/http/permissions_policy.rb:22:in `call' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/http/content_security_policy.rb:18:in `call' /usr/local/bundle/gems/rack-2.2.3/lib/rack/session/abstract/id.rb:266:in `context' /usr/local/bundle/gems/rack-2.2.3/lib/rack/session/abstract/id.rb:260:in `call' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/middleware/cookies.rb:693:in `call' /usr/local/bundle/gems/activerecord-7.0.2.3/lib/active_record/migration.rb:603:in `call' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/middleware/callbacks.rb:27:in `block in call' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/callbacks.rb:99:in `run_callbacks' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/middleware/callbacks.rb:26:in `call' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/middleware/executor.rb:14:in `call' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/middleware/debug_exceptions.rb:28:in `call' /usr/local/bundle/gems/web-console-4.2.0/lib/web_console/middleware.rb:132:in `call_app' /usr/local/bundle/gems/web-console-4.2.0/lib/web_console/middleware.rb:19:in `block in call' /usr/local/bundle/gems/web-console-4.2.0/lib/web_console/middleware.rb:17:in `catch' /usr/local/bundle/gems/web-console-4.2.0/lib/web_console/middleware.rb:17:in `call' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/middleware/show_exceptions.rb:26:in `call' /usr/local/bundle/gems/railties-7.0.2.3/lib/rails/rack/logger.rb:36:in `call_app' /usr/local/bundle/gems/railties-7.0.2.3/lib/rails/rack/logger.rb:25:in `block in call' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/tagged_logging.rb:99:in `block in tagged' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/tagged_logging.rb:37:in `tagged' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/tagged_logging.rb:99:in `tagged' /usr/local/bundle/gems/railties-7.0.2.3/lib/rails/rack/logger.rb:25:in `call' /usr/local/bundle/gems/sprockets-rails-3.4.2/lib/sprockets/rails/quiet_assets.rb:13:in `call' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/middleware/remote_ip.rb:93:in `call' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/middleware/request_id.rb:26:in `call' /usr/local/bundle/gems/rack-2.2.3/lib/rack/method_override.rb:24:in `call' /usr/local/bundle/gems/rack-2.2.3/lib/rack/runtime.rb:22:in `call' /usr/local/bundle/gems/activesupport-7.0.2.3/lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/middleware/executor.rb:14:in `call' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/middleware/static.rb:23:in `call' /usr/local/bundle/gems/rack-2.2.3/lib/rack/sendfile.rb:110:in `call' /usr/local/bundle/gems/actionpack-7.0.2.3/lib/action_dispatch/middleware/host_authorization.rb:137:in `call' /usr/local/bundle/gems/railties-7.0.2.3/lib/rails/engine.rb:530:in `call' /usr/local/bundle/gems/puma-5.6.2/lib/puma/configuration.rb:252:in `call' /usr/local/bundle/gems/puma-5.6.2/lib/puma/request.rb:77:in `block in handle_request' /usr/local/bundle/gems/puma-5.6.2/lib/puma/thread_pool.rb:340:in `with_force_shutdown' /usr/local/bundle/gems/puma-5.6.2/lib/puma/request.rb:76:in `handle_request' /usr/local/bundle/gems/puma-5.6.2/lib/puma/server.rb:441:in `process_client' /usr/local/bundle/gems/puma-5.6.2/lib/puma/thread_pool.rb:147:in `block in spawn_thread' ```I did notice one or two other issues here suggesting that the Anyone have any ideas? |
I struggled to get the import globbing to work with I ended up installing Then I did this in my
And that seems to work so far. |
I'm trying to follow @dyeje 's instructions, but I can't find any file named ran the following commands with node v16.15.1:
Where is this file supposed to be? |
@guyas make it in the root of your project. Here's an example file from one of my projects: const path = require("path");
const rails = require("esbuild-rails");
const ImportGlobPlugin = require("esbuild-plugin-import-glob").default;
require("esbuild")
.build({
entryPoints: ["application.js"],
bundle: true,
outdir: path.join(process.cwd(), "app/assets/builds"),
absWorkingDir: path.join(process.cwd(), "app/javascript"),
watch: process.argv.includes("--watch"),
plugins: [rails(), ImportGlobPlugin()],
loader: { ".js": "jsx" },
})
.catch(() => process.exit(1)); |
I've created such file and went on with your guide, yet the component is not rendered as intended. I still get only
|
@guyas Idk if you were running into the same issue as I was but I was using named exports for my react components, after I switched to default exports my components were able to render fine! |
@mrpineapples Thanks! @ahangarha we need this in the docs. |
Note, given that https://github.com/shakacode/shakapacker#esbuild-loader-configuration supports ESBuild, is there any reason to add complexity to also support jsbundling-rails? |
@justin808 Just for posterity it doesn't actually need to be a default export, the code I used which was in this example #1149 (comment) uses componentsContext[component.name.replace(".js", "")] = component.module.default which can be modified to support named and/or default exports by doing something like this const componentName = component.name.replace(".jsx", "");
// We prefer named exports but fall back to default
componentsContext[componentName] = component.module[componentName] || component.module.default; |
In build options I set require('esbuild').build({
...
bundle: true,
outdir: 'app/assets/builds',
publicPath: 'assets',
minify: true,
// add this
keepNames: true
...
} import reactComponents from "./react/**/**.tsx"
let componentsContext = {}
reactComponents.forEach((component) => {
// maybe component.default.name is renamed without keepNames: true
componentsContext[component.default.name] = component.default
})
const ReactRailsUJS = require("react_ujs")
ReactRailsUJS.getConstructor = (name) => {
return componentsContext[name]
} |
Working on a bit of legacy code and unfortunately with the solutions here, we've found ourselves with a mega-bundle of all our components in |
@imjared Did you get anywhere with this? One naive thought would be to manually manage different bundles for the different pages that you need but that sounds like a pretty big pain |
@SeanRoberts - unfortunately not. i did briefly consider the different bundle/different page approach but with all the prop passing and whatnot that we got out of the box in react-rails, i wasn't too sure how it'd work out. |
@imjared What did you end up choosing to do? Just deliver a large bundle? |
@SeanRoberts for now, yeah. we're considering looking into shakapacker but time is a limited resource. |
Migration to Shakapacker shouldn't be challenging. |
Moved to jsbundling-rails with esbuild. removed scss from webpacker and let dartsass-rails handle it. then removed webpacker. React-rails was the last to get working and the first comment was the ticket! I didn't even create an esbuild.config... although I could. here's my script
Things that didn't work... jsbundling-rails && cssbundling-rails (without unbundling sass) These solutions would probably work with a simpler app (or more time configuring them) but I'm using an old app with millions of users and almost a decade of all kinds of developers now i'm set up to switch to cssbundling-rails and propshaft using tailwind. Sky's the limit. |
Any chance that somebody could summarize for the project docs? |
Ping @justin808 Issue with Dynamic Importing of Components in Rails 7 with ESBuildContextRails 7 has been gradually moving away from Webpack, offering various JavaScript bundling options, including ESBuild. This shift prompted an exploration of non-Webpack solutions for integrating React with Rails using the ProblemThe typical method for loading components dynamically ( SolutionI followed a similar workaround to what @multiplegeorges suggested, but adjusted for my case. Here's the effective setup: Component Registration and ImportingInstead of relying on // app/javascript/application.js
import * as Components from "./components/**/*.{js,ts,tsx,jsx}";
const componentsContext = {};
Components.default.forEach((component) => {
let cleanName = component.filename
.replace("./components/", "")
.replace(/\.\w+$/, ""); // Strips the file extension
componentsContext[cleanName] = component.module.default;
});
const ReactRailsUJS = require("react_ujs");
ReactRailsUJS.getConstructor = (name) => componentsContext[name]; Configuration for ESBuild // esbuild.config.mjs
import * as esbuild from "esbuild";
import path from "path";
import rails from "esbuild-rails";
import chokidar from "chokidar";
import http from "http";
import { setTimeout } from "timers/promises";
import ImportGlobPlugin from "esbuild-plugin-import-glob";
esbuild.build({
entryPoints: ["application.js"],
bundle: true,
outdir: "app/assets/builds",
absWorkingDir: path.join(process.cwd(), "app/javascript"),
plugins: [ImportGlobPlugin()],
format: "esm",
minify: process.env.RAILS_ENV === "production",
sourcemap: process.env.RAILS_ENV !== "production",
splitting: true,
}).catch(() => process.exit(1)); And my components: // javascript/components/Post.jsx
import React from 'react';
export default function Post({ title }) {
return (
<h1 className="text-2xl font-bold">Hey, <span className="underline">{title}</span></h1>
);
} I hope it helps 😊 |
Rails 7 seems to be moving away from webpack(er), with multiple options to bundle JS with the new
js-bundling
gem (e.g. with ESbuild etc.).As such, in order to future proof the project, it might make sense to add support/documentation for JS bundling solutions other than webpack.
Notably,
require.context()
is webpack specific. I have managed to work around this by providing a mapping manually with ESbuild:As such, simply removing
require.context()
meant that I was able to successfully use react-rails with ESbuild.This took quite some time to work out - as such, it would be useful to document this (or a better solution) somewhere.
The text was updated successfully, but these errors were encountered: