islandjs-rails 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +33 -152
- data/lib/islandjs_rails/rails_helpers.rb +18 -2
- data/lib/islandjs_rails/version.rb +1 -1
- data/lib/templates/package.json +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3efc622c722a226faf6ab715f92302e3476aa46be3c186dabd7ec8e51cf49166
|
4
|
+
data.tar.gz: 5c6fa3546df97f4c8430e6b9c06b320a6cd06432b6493025bc05a5c4242f88e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec382c1d892648a353afed3dec2420b895bf14eae349f3b4a2877aade87bcf8dd2954f3bf1715aa93c6e9fd1f4b3ffed2089c86c356957b0b830aca71387fa03
|
7
|
+
data.tar.gz: 6fd2a2440a750bf0b284452b6faf5835d6a5635e5fef7e4213eb439d77ae95d7667e934eec36e5ff077ea7f1e58d9fbe2d60c140d49ec3c795eae7fe429fe9ad
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## [0.4.0] - 2025-08-10
|
9
|
+
|
10
|
+
### Added
|
11
|
+
- Add ENV flag to control the dev UMD bundle info footer. The floating footer is now disabled by default and only shows in development when `ISLANDJS_RAILS_SHOW_UMD_DEBUG` is truthy.
|
12
|
+
|
13
|
+
## [0.3.0] - 2025-08-09
|
14
|
+
|
15
|
+
### Added
|
16
|
+
- **Vendor Script Helper**: New `extra_vendor_tag` helper method for including third-party JavaScript libraries from the vendor directory
|
17
|
+
- **Enhanced Package Template**: Updated `lib/templates/package.json` with improved webpack configuration and dependencies
|
18
|
+
|
19
|
+
### Enhanced
|
20
|
+
- Simplified vendor asset integration with automatic Turbo tracking
|
21
|
+
- Better support for third-party library inclusion in Rails applications
|
22
|
+
|
8
23
|
## [0.2.1] - 2025-08-06
|
9
24
|
|
10
25
|
### Fixed
|
data/README.md
CHANGED
@@ -1,14 +1,15 @@
|
|
1
|
-
# IslandJS Rails
|
1
|
+
# IslandJS Rails — Turbo compatible JSX in seconds
|
2
|
+
|
3
|
+
**Launch quickly:** *upgrade with vite only if necessary (MYAGNI).*
|
2
4
|
|
3
5
|
[](https://github.com/praxis-emergent/islandjs-rails/actions/workflows/github-actions-demo.yml)
|
4
6
|
[](coverage/index.html)
|
5
7
|
[](spec/)
|
6
8
|
[](#rails-8-ready)
|
7
|
-
[](https://www.ruby-lang.org/)
|
8
9
|
|
9
|
-
IslandJS Rails supports the development of React
|
10
|
+
IslandJS Rails supports the development of React islands in Rails apps by synchronizing `package.json` dependencies with UMD libraries served in `public/islands/vendor`.
|
10
11
|
|
11
|
-
Write Turbo compatible JSX in `app/javascript/islands/components/` and render it with a `react_component` helper in ERB templates (including Turbo Stream partials) — Vue and other framework support can be added with a bit of work
|
12
|
+
Write Turbo compatible JSX in `app/javascript/islands/components/` and render it with a `react_component` helper in ERB templates (including Turbo Stream partials) — **Vue and other framework support can be added with a bit of work**.
|
12
13
|
|
13
14
|
## Quick Start
|
14
15
|
|
@@ -34,6 +35,11 @@ rails "islandjs:install[react,18.3.1]"
|
|
34
35
|
rails "islandjs:install[react-dom,18.3.1]"
|
35
36
|
```
|
36
37
|
|
38
|
+
### Run Yarn In Development
|
39
|
+
```bash
|
40
|
+
yarn watch
|
41
|
+
```
|
42
|
+
|
37
43
|
### Render React Components
|
38
44
|
```erb
|
39
45
|
<!-- In any view -->
|
@@ -45,6 +51,11 @@ rails "islandjs:install[react-dom,18.3.1]"
|
|
45
51
|
<% end %>
|
46
52
|
```
|
47
53
|
|
54
|
+
### Build For Production
|
55
|
+
```bash
|
56
|
+
yarn build # you may remove any stale islandjs bundles before committing
|
57
|
+
```
|
58
|
+
|
48
59
|
> 💡 **Turbo Cache Compatible**: React components automatically persist state across Turbo navigation! See [Turbo Cache Integration](#turbo-cache-integration) for details.
|
49
60
|
|
50
61
|
### Write Modern JSX (with Turbo Cache Support)
|
@@ -96,10 +107,10 @@ IslandJS Rails aligns perfectly with **Rails 8's philosophy** of simplicity and
|
|
96
107
|
|
97
108
|
### The Problem IslandJS Rails Solves
|
98
109
|
Modern Rails developers face a painful choice:
|
99
|
-
- **Bundle everything**:
|
100
|
-
- **Skip modern JS**: Miss out on React and
|
110
|
+
- **Bundle everything**: Complicated configs, slow builds, bundle bloat
|
111
|
+
- **Skip modern JS**: Miss out on React and other modern frontend tools
|
101
112
|
|
102
|
-
**
|
113
|
+
**IslandJS Rails offers a middle way:** a simple, zero-config solution for adding React and other JS libraries to your Rails app. Get 80% of reactive use cases covered for 5% of the hassle. Most apps don't even need the other 20% anyway.
|
103
114
|
|
104
115
|
### The IslandJS Rails Solution
|
105
116
|
```bash
|
@@ -121,7 +132,16 @@ const quill = new window.Quill("#editor", {
|
|
121
132
|
});
|
122
133
|
```
|
123
134
|
|
124
|
-
|
135
|
+
**Important Note:** IslandJS Rails works with packages that ship UMD builds. Many popular packages have UMD builds, but some modern packages do not — React 19+ removed UMD builds entirely. Future versions of IslandJS Rails will support local UMD generation for some packages (such as [React 19+](https://github.com/lofcz/umd-react)).
|
136
|
+
|
137
|
+
If you absolutely need a package that doesn't ship UMD builds, you have a few options:
|
138
|
+
|
139
|
+
- Option A: Find an alternative lib that supports UMD builds
|
140
|
+
- Option B: Build the UMD yourself & serve it like a normal `islandjs-rails` install
|
141
|
+
- Option C: Write vanilla JS for the use case
|
142
|
+
- Option D: Set up `vite` with [turbo-mount](https://github.com/skryukov/turbo-mount) & write your component that way. You can migrate incrementally from `islandj-rails` to `turbo-mount` if preferred — they can coexist in the same app.
|
143
|
+
|
144
|
+
## IslandJS Rails is Rails 8 Ready
|
125
145
|
|
126
146
|
✅ **Tested against Rails 8**
|
127
147
|
✅ **Compatible with Rails 8 asset pipeline**
|
@@ -211,7 +231,7 @@ yarn install
|
|
211
231
|
**Development Workflow:**
|
212
232
|
1. Run `yarn watch` (or `npm run watch`) in one terminal
|
213
233
|
2. Edit your components in `app/javascript/islands/components/`
|
214
|
-
3. Changes are automatically compiled to `public
|
234
|
+
3. Changes are automatically compiled to `public/`
|
215
235
|
|
216
236
|
**Production Deployment:**
|
217
237
|
1. Run `yarn build` (or `npm run build`) to create optimized bundle
|
@@ -231,13 +251,13 @@ When installing scoped packages, you **must** include the full package name with
|
|
231
251
|
|
232
252
|
```bash
|
233
253
|
# ✅ Correct - Full scoped package name
|
234
|
-
rails "islandjs:install[@solana/web3.js,1.98.
|
254
|
+
rails "islandjs:install[@solana/web3.js,1.98.4]"
|
235
255
|
|
236
256
|
# ❌ Incorrect - Missing .js suffix
|
237
|
-
rails "islandjs:install[@solana/web3,1.98.
|
257
|
+
rails "islandjs:install[@solana/web3,1.98.4]"
|
238
258
|
|
239
259
|
# ❌ Incorrect - Missing scope
|
240
|
-
rails "islandjs:install[web3.js,1.98.
|
260
|
+
rails "islandjs:install[web3.js,1.98.4]"
|
241
261
|
```
|
242
262
|
|
243
263
|
### Shell Escaping
|
@@ -249,7 +269,7 @@ The `@` symbol is handled automatically by Rails task syntax when using double q
|
|
249
269
|
rails "islandjs:install[@solana/web3.js]"
|
250
270
|
|
251
271
|
# ✅ Also works (with version)
|
252
|
-
rails "islandjs:install[@solana/web3.js,1.98.
|
272
|
+
rails "islandjs:install[@solana/web3.js,1.98.4]"
|
253
273
|
|
254
274
|
# ⚠️ May not work in some shells without quotes
|
255
275
|
rails islandjs:install[@solana/web3.js] # Avoid this
|
@@ -534,16 +554,6 @@ const HelloWorld = ({ containerId }) => {
|
|
534
554
|
}) %>
|
535
555
|
```
|
536
556
|
|
537
|
-
### Live Demo
|
538
|
-
|
539
|
-
See the complete demo: [`react.html.erb`](app/views/islandjs_demo/react.html.erb)
|
540
|
-
|
541
|
-
The demo shows:
|
542
|
-
- ✅ **State persistence** across Turbo navigation
|
543
|
-
- ✅ **Automatic state restoration** when navigating back
|
544
|
-
- ✅ **Zero configuration** - works out of the box
|
545
|
-
- ✅ **Compatible with Turbo Drive** and all Hotwire features
|
546
|
-
|
547
557
|
### Turbo Utility Functions
|
548
558
|
|
549
559
|
IslandJS Rails provides utility functions for Turbo compatibility:
|
@@ -640,99 +650,6 @@ IslandjsRails.configure do |config|
|
|
640
650
|
end
|
641
651
|
```
|
642
652
|
|
643
|
-
## Real-World Examples
|
644
|
-
|
645
|
-
### React Dashboard Component
|
646
|
-
|
647
|
-
```bash
|
648
|
-
# Install dependencies
|
649
|
-
rails islandjs:install[react]
|
650
|
-
rails islandjs:install[react-dom]
|
651
|
-
rails islandjs:install[chart.js]
|
652
|
-
```
|
653
|
-
|
654
|
-
```jsx
|
655
|
-
// jsx/components/Dashboard.jsx
|
656
|
-
import React, { useState, useEffect } from 'react';
|
657
|
-
import { useTurboProps, useTurboCache } from '../utils/turbo.js';
|
658
|
-
|
659
|
-
function Dashboard({ containerId }) {
|
660
|
-
const initialProps = useTurboProps(containerId);
|
661
|
-
|
662
|
-
const [data, setData] = useState(initialProps.data || []);
|
663
|
-
const [loading, setLoading] = useState(false);
|
664
|
-
|
665
|
-
// Setup turbo cache persistence
|
666
|
-
useEffect(() => {
|
667
|
-
const cleanup = useTurboCache(containerId, { data }, true);
|
668
|
-
return cleanup;
|
669
|
-
}, [containerId, data]);
|
670
|
-
|
671
|
-
useEffect(() => {
|
672
|
-
// Fetch dashboard data if not cached
|
673
|
-
if (data.length === 0) {
|
674
|
-
setLoading(true);
|
675
|
-
fetch('/api/dashboard')
|
676
|
-
.then(res => res.json())
|
677
|
-
.then(fetchedData => {
|
678
|
-
setData(fetchedData);
|
679
|
-
setLoading(false);
|
680
|
-
});
|
681
|
-
}
|
682
|
-
}, []);
|
683
|
-
|
684
|
-
if (loading) return <div>Loading dashboard...</div>;
|
685
|
-
|
686
|
-
return (
|
687
|
-
<div>
|
688
|
-
<h1>Dashboard</h1>
|
689
|
-
{/* Chart component here */}
|
690
|
-
<p>Data points: {data.length}</p>
|
691
|
-
</div>
|
692
|
-
);
|
693
|
-
}
|
694
|
-
|
695
|
-
export default Dashboard;
|
696
|
-
```
|
697
|
-
|
698
|
-
```erb
|
699
|
-
<!-- app/views/dashboard/show.html.erb -->
|
700
|
-
<%= islands %>
|
701
|
-
<%= react_component('Dashboard', { data: @dashboard_data }) %>
|
702
|
-
```
|
703
|
-
|
704
|
-
### Turbo + React Integration
|
705
|
-
|
706
|
-
**⭐ Recommended: Use Built-in Turbo Cache**
|
707
|
-
|
708
|
-
IslandJS Rails now includes automatic Turbo cache compatibility! See the [Turbo Cache Integration](#turbo-cache-integration) section above for the modern approach with zero manual setup.
|
709
|
-
|
710
|
-
**Alternative: Manual Turbo Integration**
|
711
|
-
|
712
|
-
For custom scenarios, you can manually handle Turbo events:
|
713
|
-
|
714
|
-
```javascript
|
715
|
-
// Manual approach (not needed with react_component helper)
|
716
|
-
document.addEventListener('turbo:load', () => {
|
717
|
-
const container = document.getElementById('react-component');
|
718
|
-
if (container && !container.hasChildNodes()) {
|
719
|
-
ReactDOM.render(
|
720
|
-
React.createElement(MyComponent, {
|
721
|
-
data: JSON.parse(container.dataset.props)
|
722
|
-
}),
|
723
|
-
container
|
724
|
-
);
|
725
|
-
}
|
726
|
-
});
|
727
|
-
|
728
|
-
document.addEventListener('turbo:before-cache', () => {
|
729
|
-
// Cleanup React components before Turbo caches
|
730
|
-
document.querySelectorAll('[data-react-component]').forEach(el => {
|
731
|
-
ReactDOM.unmountComponentAtNode(el);
|
732
|
-
});
|
733
|
-
});
|
734
|
-
```
|
735
|
-
|
736
653
|
## Troubleshooting
|
737
654
|
|
738
655
|
### Common Issues
|
@@ -770,30 +687,6 @@ rails islandjs:install[react]
|
|
770
687
|
|
771
688
|
MIT License - see LICENSE file for details.
|
772
689
|
|
773
|
-
## Structure
|
774
|
-
|
775
|
-
```
|
776
|
-
lib/islandjs_rails/
|
777
|
-
├── spec/
|
778
|
-
│ ├── spec_helper.rb # Test setup and mocking
|
779
|
-
│ ├── lib/
|
780
|
-
│ │ ├── islandjs_rails_spec.rb # Main module tests
|
781
|
-
│ │ └── islandjs_rails/
|
782
|
-
│ │ ├── core_spec.rb # Core functionality tests
|
783
|
-
│ │ ├── rails_helpers_spec.rb # Rails helpers tests
|
784
|
-
│ │ ├── configuration_spec.rb # Configuration tests
|
785
|
-
│ │ ├── cli_spec.rb # CLI tests
|
786
|
-
│ │ ├── tasks_spec.rb # Rake tasks tests
|
787
|
-
│ │ ├── railtie_spec.rb # Rails integration tests
|
788
|
-
│ │ └── rails8_integration_spec.rb # Rails 8 specific tests
|
789
|
-
│ ├── fixtures/ # Test fixtures
|
790
|
-
│ └── support/ # Test support files
|
791
|
-
├── coverage/ # SimpleCov coverage reports
|
792
|
-
├── Gemfile # Test dependencies
|
793
|
-
├── Rakefile # Test runner configuration
|
794
|
-
└── README.md # This file
|
795
|
-
```
|
796
|
-
|
797
690
|
## Running Tests
|
798
691
|
|
799
692
|
### From the gem directory:
|
@@ -814,16 +707,6 @@ bundle exec rspec
|
|
814
707
|
open coverage/index.html
|
815
708
|
```
|
816
709
|
|
817
|
-
## Adding New Tests
|
818
|
-
|
819
|
-
When adding new IslandJS Rails functionality:
|
820
|
-
|
821
|
-
1. Add tests to the appropriate test file
|
822
|
-
2. Use the provided test helpers for consistency
|
823
|
-
3. Mock external dependencies (CDN calls, file system operations)
|
824
|
-
4. Test both success and failure scenarios
|
825
|
-
5. Ensure tests are isolated and don't affect each other
|
826
|
-
|
827
710
|
## Future Enhancements
|
828
711
|
|
829
712
|
Planned features for future releases:
|
@@ -834,8 +717,6 @@ Planned features for future releases:
|
|
834
717
|
- **TypeScript Support**: First-class TypeScript support for UMD packages
|
835
718
|
- **Local UMD Generation**: Generate UMD builds for packages that don't ship them
|
836
719
|
- **Multi-framework Support**: Vue, Svelte, and other frameworks
|
837
|
-
- **Build-time Optimization**: Optional build-time bundling for production
|
838
|
-
- **Edge Computing**: Cloudflare Workers and similar platform support
|
839
720
|
|
840
721
|
---
|
841
722
|
|
@@ -5,7 +5,7 @@ module IslandjsRails
|
|
5
5
|
output = []
|
6
6
|
output << island_partials # Now uses vendor UMD partial
|
7
7
|
output << island_bundle_script
|
8
|
-
output << umd_versions_debug if
|
8
|
+
output << umd_versions_debug if umd_debug_enabled?
|
9
9
|
output.compact.join("\n").html_safe
|
10
10
|
end
|
11
11
|
|
@@ -181,7 +181,7 @@ module IslandjsRails
|
|
181
181
|
|
182
182
|
# Legacy UMD helper methods for backward compatibility with tests
|
183
183
|
def umd_versions_debug
|
184
|
-
return unless
|
184
|
+
return unless umd_debug_enabled?
|
185
185
|
|
186
186
|
begin
|
187
187
|
installed = IslandjsRails.core.send(:installed_packages)
|
@@ -229,8 +229,24 @@ module IslandjsRails
|
|
229
229
|
html_safe_string(partials)
|
230
230
|
end
|
231
231
|
|
232
|
+
# Generate a script tag for vendor JavaScript files
|
233
|
+
# Useful for including third-party libraries from the vendor directory
|
234
|
+
def extra_vendor_tag(name, extension = ".min.js")
|
235
|
+
"<script src='/vendor/#{name}#{extension}' data-turbo-track='reload'></script>".html_safe
|
236
|
+
end
|
237
|
+
|
232
238
|
private
|
233
239
|
|
240
|
+
# Whether the floating UMD versions debug footer should render
|
241
|
+
def umd_debug_enabled?
|
242
|
+
return false unless Rails.env.development?
|
243
|
+
|
244
|
+
env_value = ENV['ISLANDJS_RAILS_SHOW_UMD_DEBUG']
|
245
|
+
return false if env_value.nil?
|
246
|
+
|
247
|
+
%w[1 true yes on].include?(env_value.to_s.strip.downcase)
|
248
|
+
end
|
249
|
+
|
234
250
|
# Find the bundle file path (with manifest support)
|
235
251
|
def find_bundle_path
|
236
252
|
# Try manifest first (production)
|
data/lib/templates/package.json
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
"version": "1.0.0",
|
4
4
|
"private": true,
|
5
5
|
"scripts": {
|
6
|
-
"build": "rm -f public/
|
7
|
-
"build:dev": "rm -f public/
|
6
|
+
"build": "rm -f public/islands_* && NODE_ENV=production webpack",
|
7
|
+
"build:dev": "rm -f public/islands_* && NODE_ENV=production webpack",
|
8
8
|
"watch": "NODE_ENV=development webpack --watch"
|
9
9
|
},
|
10
10
|
"dependencies": {},
|