islandjs-rails 0.1.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 +7 -0
- data/CHANGELOG.md +16 -0
- data/LICENSE.md +22 -0
- data/README.md +754 -0
- data/exe/islandjs-rails +6 -0
- data/islandjs-rails.gemspec +55 -0
- data/lib/islandjs-rails.rb +3 -0
- data/lib/islandjs_rails/cli.rb +57 -0
- data/lib/islandjs_rails/configuration.rb +49 -0
- data/lib/islandjs_rails/core.rb +462 -0
- data/lib/islandjs_rails/core_methods.rb +609 -0
- data/lib/islandjs_rails/rails_helpers.rb +394 -0
- data/lib/islandjs_rails/railtie.rb +59 -0
- data/lib/islandjs_rails/tasks.rb +118 -0
- data/lib/islandjs_rails/vendor_manager.rb +271 -0
- data/lib/islandjs_rails/version.rb +3 -0
- data/lib/islandjs_rails.rb +142 -0
- data/lib/templates/app/controllers/islandjs_demo_controller.rb +9 -0
- data/lib/templates/app/javascript/islands/components/.gitkeep +0 -0
- data/lib/templates/app/javascript/islands/components/HelloWorld.jsx +117 -0
- data/lib/templates/app/javascript/islands/index.js +10 -0
- data/lib/templates/app/javascript/islands/utils/turbo.js +87 -0
- data/lib/templates/app/views/islandjs_demo/index.html.erb +98 -0
- data/lib/templates/app/views/islandjs_demo/react.html.erb +93 -0
- data/lib/templates/config/demo_routes.rb +3 -0
- data/lib/templates/package.json +21 -0
- data/lib/templates/webpack.config.js +49 -0
- data/package.json +12 -0
- data/yarn.lock +1890 -0
- metadata +181 -0
@@ -0,0 +1,98 @@
|
|
1
|
+
<div class="max-w-4xl mx-auto p-8">
|
2
|
+
<h1 class="text-4xl font-bold mb-6">🏝️ IslandJS Rails Demo</h1>
|
3
|
+
|
4
|
+
<div class="bg-blue-50 border-l-4 border-blue-400 p-6 mb-8">
|
5
|
+
<h2 class="text-xl font-semibold text-blue-800 mb-2">Welcome to IslandJS Rails!</h2>
|
6
|
+
<p class="text-blue-700">
|
7
|
+
This demo showcases React components as "islands" within a Rails application,
|
8
|
+
with full Turbo cache integration for seamless navigation.
|
9
|
+
</p>
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<div class="grid md:grid-cols-2 gap-6 mb-8">
|
13
|
+
<div class="bg-white rounded-lg shadow-md p-6 border">
|
14
|
+
<h3 class="text-lg font-semibold mb-3 text-gray-800">🚀 What You'll See</h3>
|
15
|
+
<ul class="space-y-2 text-gray-600">
|
16
|
+
<li class="flex items-start">
|
17
|
+
<span class="text-green-500 mr-2">✓</span>
|
18
|
+
React components that persist state across Turbo navigation
|
19
|
+
</li>
|
20
|
+
<li class="flex items-start">
|
21
|
+
<span class="text-green-500 mr-2">✓</span>
|
22
|
+
Zero webpack complexity - UMD libraries from vendor files
|
23
|
+
</li>
|
24
|
+
<li class="flex items-start">
|
25
|
+
<span class="text-green-500 mr-2">✓</span>
|
26
|
+
Rails-native development with modern JavaScript
|
27
|
+
</li>
|
28
|
+
<li class="flex items-start">
|
29
|
+
<span class="text-green-500 mr-2">✓</span>
|
30
|
+
Production-ready asset delivery system
|
31
|
+
</li>
|
32
|
+
</ul>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div class="bg-white rounded-lg shadow-md p-6 border">
|
36
|
+
<h3 class="text-lg font-semibold mb-3 text-gray-800">🎯 Test the Magic</h3>
|
37
|
+
<p class="text-gray-600 mb-4">
|
38
|
+
Click the React demo below, interact with the component, then navigate back.
|
39
|
+
Your component state will be preserved thanks to Turbo cache integration!
|
40
|
+
</p>
|
41
|
+
<div class="bg-gray-50 p-3 rounded text-sm text-gray-700">
|
42
|
+
<strong>Try this:</strong> Change the counter, navigate away, then come back.
|
43
|
+
The counter value persists! 🎉
|
44
|
+
</div>
|
45
|
+
</div>
|
46
|
+
</div>
|
47
|
+
|
48
|
+
<div class="bg-white rounded-lg shadow-md p-6 border mb-8">
|
49
|
+
<h3 class="text-lg font-semibold mb-4 text-gray-800">🏝️ React Island Demo</h3>
|
50
|
+
<p class="text-gray-600 mb-4">
|
51
|
+
Experience React components as "islands" within your Rails application.
|
52
|
+
This demonstrates the core IslandJS Rails philosophy: modern JavaScript without the complexity.
|
53
|
+
</p>
|
54
|
+
|
55
|
+
<div class="flex space-x-4">
|
56
|
+
<a href="/islandjs/react"
|
57
|
+
class="inline-flex items-center px-6 py-3 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 transition-colors">
|
58
|
+
<span class="mr-2">🚀</span>
|
59
|
+
View React Demo
|
60
|
+
</a>
|
61
|
+
|
62
|
+
<a href="/islandjs/react"
|
63
|
+
class="inline-flex items-center px-6 py-3 bg-gray-100 text-gray-700 font-medium rounded-lg hover:bg-gray-200 transition-colors">
|
64
|
+
<span class="mr-2">🔄</span>
|
65
|
+
Test Turbo Cache
|
66
|
+
</a>
|
67
|
+
</div>
|
68
|
+
</div>
|
69
|
+
|
70
|
+
<div class="bg-gray-50 rounded-lg p-6">
|
71
|
+
<h3 class="text-lg font-semibold mb-3 text-gray-800">📚 How It Works</h3>
|
72
|
+
<div class="grid md:grid-cols-2 gap-4 text-sm text-gray-600">
|
73
|
+
<div>
|
74
|
+
<h4 class="font-medium text-gray-800 mb-2">Vendor System</h4>
|
75
|
+
<ul class="space-y-1">
|
76
|
+
<li>• React & ReactDOM served from <code class="bg-gray-200 px-1 rounded">/islands/vendor/</code></li>
|
77
|
+
<li>• Browser caching for optimal performance</li>
|
78
|
+
<li>• No webpack bundling of external libraries</li>
|
79
|
+
</ul>
|
80
|
+
</div>
|
81
|
+
<div>
|
82
|
+
<h4 class="font-medium text-gray-800 mb-2">Turbo Integration</h4>
|
83
|
+
<ul class="space-y-1">
|
84
|
+
<li>• Component state persists across navigation</li>
|
85
|
+
<li>• Automatic cache management</li>
|
86
|
+
<li>• Rails-native user experience</li>
|
87
|
+
</ul>
|
88
|
+
</div>
|
89
|
+
</div>
|
90
|
+
</div>
|
91
|
+
|
92
|
+
<div class="mt-8 text-center text-gray-500 text-sm">
|
93
|
+
<p>
|
94
|
+
Built with IslandJS Rails •
|
95
|
+
<a href="https://github.com/praxis-emergent/islandjs-rails" class="text-blue-600 hover:text-blue-800">View on GitHub</a>
|
96
|
+
</p>
|
97
|
+
</div>
|
98
|
+
</div>
|
@@ -0,0 +1,93 @@
|
|
1
|
+
<div class="max-w-4xl mx-auto p-8">
|
2
|
+
<!-- Navigation -->
|
3
|
+
<div class="mb-6">
|
4
|
+
<a href="/islandjs" class="inline-flex items-center text-blue-600 hover:text-blue-800 font-medium">
|
5
|
+
<span class="mr-2">←</span>
|
6
|
+
Back to IslandJS Demo Home
|
7
|
+
</a>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
<h1 class="text-3xl font-bold mb-6">🚀 React Component Island</h1>
|
11
|
+
|
12
|
+
<!-- Turbo Cache Demo Instructions -->
|
13
|
+
<div class="bg-yellow-50 border-l-4 border-yellow-400 p-4 mb-6">
|
14
|
+
<h3 class="text-lg font-semibold text-yellow-800 mb-2">🔄 Test Turbo Cache Integration</h3>
|
15
|
+
<p class="text-yellow-700 mb-2">
|
16
|
+
<strong>Try this:</strong> Interact with the component below (click the button, change the message),
|
17
|
+
then navigate back to the demo home and return here. Your changes will be preserved!
|
18
|
+
</p>
|
19
|
+
<p class="text-sm text-yellow-600">
|
20
|
+
This demonstrates how IslandJS Rails components maintain state across Turbo navigation.
|
21
|
+
</p>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<!-- React Component Island -->
|
25
|
+
<div class="bg-white rounded-lg shadow-md p-6 mb-6 border">
|
26
|
+
<h2 class="text-xl font-semibold mb-4 text-gray-800">Interactive React Component</h2>
|
27
|
+
<p class="text-gray-600 mb-4">
|
28
|
+
This React component maintains its state across page navigation thanks to Turbo cache integration.
|
29
|
+
</p>
|
30
|
+
|
31
|
+
<div id="hello-world-demo" class="border-2 border-dashed border-blue-300 rounded-lg p-6 bg-blue-50">
|
32
|
+
<%= react_component('HelloWorld', {
|
33
|
+
message: 'Hello from IslandJS Rails!',
|
34
|
+
count: 0,
|
35
|
+
showAdvanced: false
|
36
|
+
}) %>
|
37
|
+
</div>
|
38
|
+
</div>
|
39
|
+
|
40
|
+
<!-- Technical Details -->
|
41
|
+
<div class="bg-gray-50 rounded-lg p-6 mb-6">
|
42
|
+
<h3 class="text-lg font-semibold mb-4 text-gray-800">🏗️ How It Works</h3>
|
43
|
+
<div class="grid md:grid-cols-2 gap-4 text-sm">
|
44
|
+
<div>
|
45
|
+
<h4 class="font-medium text-gray-800 mb-2">Component Rendering</h4>
|
46
|
+
<ol class="space-y-1 text-gray-600">
|
47
|
+
<li>1. Rails renders this ERB template</li>
|
48
|
+
<li>2. <code class="bg-gray-200 px-1 rounded">react_component</code> helper creates container</li>
|
49
|
+
<li>3. React loads from vendor files (<code class="bg-gray-200 px-1 rounded">/islands/vendor/</code>)</li>
|
50
|
+
<li>4. Component mounts as independent "island"</li>
|
51
|
+
</ol>
|
52
|
+
</div>
|
53
|
+
<div>
|
54
|
+
<h4 class="font-medium text-gray-800 mb-2">Turbo Integration</h4>
|
55
|
+
<ol class="space-y-1 text-gray-600">
|
56
|
+
<li>1. Component state saved to data attributes</li>
|
57
|
+
<li>2. Turbo caches page with current state</li>
|
58
|
+
<li>3. Navigation preserves component state</li>
|
59
|
+
<li>4. State restored on return visit</li>
|
60
|
+
</ol>
|
61
|
+
</div>
|
62
|
+
</div>
|
63
|
+
</div>
|
64
|
+
|
65
|
+
<!-- Navigation Actions -->
|
66
|
+
<div class="text-center">
|
67
|
+
<a href="/islandjs"
|
68
|
+
class="inline-flex items-center px-6 py-3 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 transition-colors">
|
69
|
+
<span class="mr-2">←</span>
|
70
|
+
Back to Demo Home
|
71
|
+
</a>
|
72
|
+
</div>
|
73
|
+
|
74
|
+
<!-- Debug Info -->
|
75
|
+
<% if Rails.env.development? %>
|
76
|
+
<div class="mt-8 bg-gray-800 text-green-400 p-4 rounded-lg text-sm font-mono">
|
77
|
+
<h4 class="text-green-300 font-bold mb-2">🔧 Development Info</h4>
|
78
|
+
<div class="space-y-1">
|
79
|
+
<div>Vendor Mode: <%= IslandjsRails.configuration.vendor_script_mode %></div>
|
80
|
+
<div>React: <span id="react-version">Loading...</span></div>
|
81
|
+
<div>ReactDOM: <span id="reactdom-version">Loading...</span></div>
|
82
|
+
<div>Islands Namespace: <span id="islands-namespace">Loading...</span></div>
|
83
|
+
</div>
|
84
|
+
<script>
|
85
|
+
document.addEventListener('DOMContentLoaded', function() {
|
86
|
+
document.getElementById('react-version').textContent = window.React ? 'Loaded' : 'Missing';
|
87
|
+
document.getElementById('reactdom-version').textContent = window.ReactDOM ? 'Loaded' : 'Missing';
|
88
|
+
document.getElementById('islands-namespace').textContent = window.islandjsRails ? 'Available' : 'Missing';
|
89
|
+
});
|
90
|
+
</script>
|
91
|
+
</div>
|
92
|
+
<% end %>
|
93
|
+
</div>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
{
|
2
|
+
"name": "islandjs-rails",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"private": true,
|
5
|
+
"scripts": {
|
6
|
+
"build": "rm -f public/islands_bundle.*.js && NODE_ENV=production webpack",
|
7
|
+
"build:dev": "rm -f public/islands_bundle.*.js && NODE_ENV=production webpack",
|
8
|
+
"watch": "NODE_ENV=development webpack --watch"
|
9
|
+
},
|
10
|
+
"dependencies": {},
|
11
|
+
"devDependencies": {
|
12
|
+
"@babel/core": "^7.23.0",
|
13
|
+
"@babel/preset-env": "^7.23.0",
|
14
|
+
"@babel/preset-react": "^7.23.0",
|
15
|
+
"babel-loader": "^9.1.3",
|
16
|
+
"terser-webpack-plugin": "^5.3.14",
|
17
|
+
"webpack": "^5.88.2",
|
18
|
+
"webpack-cli": "^5.1.4",
|
19
|
+
"webpack-manifest-plugin": "^5.0.1"
|
20
|
+
}
|
21
|
+
}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
const path = require('path');
|
2
|
+
const TerserPlugin = require('terser-webpack-plugin');
|
3
|
+
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
|
4
|
+
|
5
|
+
const isProduction = process.env.NODE_ENV === 'production';
|
6
|
+
|
7
|
+
module.exports = {
|
8
|
+
mode: isProduction ? 'production' : 'development',
|
9
|
+
entry: {
|
10
|
+
islands_bundle: ['./app/javascript/islands/index.js']
|
11
|
+
},
|
12
|
+
externals: {
|
13
|
+
// IslandJS managed externals - do not edit manually
|
14
|
+
},
|
15
|
+
output: {
|
16
|
+
filename: '[name].[contenthash].js',
|
17
|
+
path: path.resolve(__dirname, 'public'),
|
18
|
+
publicPath: '/',
|
19
|
+
clean: false
|
20
|
+
},
|
21
|
+
module: {
|
22
|
+
rules: [
|
23
|
+
{
|
24
|
+
test: /\.(js|jsx)$/,
|
25
|
+
exclude: /node_modules/,
|
26
|
+
use: {
|
27
|
+
loader: 'babel-loader',
|
28
|
+
options: {
|
29
|
+
presets: ['@babel/preset-env', '@babel/preset-react']
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
]
|
34
|
+
},
|
35
|
+
resolve: {
|
36
|
+
extensions: ['.js', '.jsx']
|
37
|
+
},
|
38
|
+
optimization: {
|
39
|
+
minimize: isProduction,
|
40
|
+
minimizer: [new TerserPlugin()]
|
41
|
+
},
|
42
|
+
plugins: [
|
43
|
+
new WebpackManifestPlugin({
|
44
|
+
fileName: 'islands_manifest.json',
|
45
|
+
publicPath: '/'
|
46
|
+
})
|
47
|
+
],
|
48
|
+
devtool: isProduction ? false : 'source-map'
|
49
|
+
};
|
data/package.json
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
{
|
2
|
+
"devDependencies": {
|
3
|
+
"@babel/core": "^7.23.0",
|
4
|
+
"@babel/preset-env": "^7.23.0",
|
5
|
+
"@babel/preset-react": "^7.23.0",
|
6
|
+
"babel-loader": "^9.1.3",
|
7
|
+
"terser-webpack-plugin": "^5.3.14",
|
8
|
+
"webpack": "^5.88.2",
|
9
|
+
"webpack-cli": "^5.1.4",
|
10
|
+
"webpack-manifest-plugin": "^5.0.1"
|
11
|
+
}
|
12
|
+
}
|