islandjs-rails 0.6.0 → 1.0.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 +71 -0
- data/LICENSE.md +1 -1
- data/README.md +60 -52
- data/lib/islandjs_rails/cli.rb +2 -2
- data/lib/islandjs_rails/configuration.rb +2 -3
- data/lib/islandjs_rails/core.rb +15 -69
- data/lib/islandjs_rails/core_methods.rb +61 -65
- data/lib/islandjs_rails/rails_helpers.rb +38 -16
- data/lib/islandjs_rails/railtie.rb +6 -6
- data/lib/islandjs_rails/tasks.rb +2 -2
- data/lib/islandjs_rails/vendor_manager.rb +6 -3
- data/lib/islandjs_rails/version.rb +1 -1
- data/lib/islandjs_rails/vite_installer.rb +286 -0
- data/lib/islandjs_rails/vite_integration.rb +148 -0
- data/lib/islandjs_rails.rb +1 -0
- data/lib/templates/app/javascript/entrypoints/islands.js +20 -0
- data/lib/templates/app/views/islandjs_demo/index.html.erb +2 -2
- data/lib/templates/package.json +4 -11
- data/lib/templates/script/build-vite-atomic.js +89 -0
- data/lib/templates/vite.config.islands.ts +67 -0
- metadata +9 -8
- data/islandjs-rails.gemspec +0 -55
- data/lib/templates/app/javascript/islands/index.js +0 -10
- data/lib/templates/webpack.config.js +0 -49
- data/package.json +0 -12
- data/yarn.lock +0 -1890
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IslandjsRails
|
|
4
|
+
# Handles Vite integration for Islands architecture
|
|
5
|
+
class ViteIntegration
|
|
6
|
+
attr_reader :root_path
|
|
7
|
+
|
|
8
|
+
def initialize(root_path = Rails.root)
|
|
9
|
+
@root_path = Pathname.new(root_path)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Check if Vite is already installed in the project
|
|
13
|
+
def vite_installed?
|
|
14
|
+
vite_config_exists? || vite_json_exists?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Check if Inertia is installed
|
|
18
|
+
def inertia_installed?
|
|
19
|
+
inertia_gem_installed? || inertia_layout_exists?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Check if Islands is already configured
|
|
23
|
+
def islands_configured?
|
|
24
|
+
islands_vite_config_exists? && islands_structure_exists?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Get the path to the Islands Vite config
|
|
28
|
+
def islands_vite_config_path
|
|
29
|
+
root_path.join('vite.config.islands.ts')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Get the path to the Islands manifest
|
|
33
|
+
def islands_manifest_path
|
|
34
|
+
root_path.join('public/islands/.vite/manifest.json')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Get the path to the main Vite config
|
|
38
|
+
def vite_config_path
|
|
39
|
+
root_path.join('vite.config.ts')
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Get the path to vite.json
|
|
43
|
+
def vite_json_path
|
|
44
|
+
root_path.join('vite.json')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Check if Islands Vite config exists
|
|
48
|
+
def islands_vite_config_exists?
|
|
49
|
+
islands_vite_config_path.exist?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Check if Islands structure exists
|
|
53
|
+
def islands_structure_exists?
|
|
54
|
+
root_path.join('app/javascript/islands').directory?
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Check if vite.config.ts exists
|
|
58
|
+
def vite_config_exists?
|
|
59
|
+
vite_config_path.exist?
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Check if vite.json exists
|
|
63
|
+
def vite_json_exists?
|
|
64
|
+
vite_json_path.exist?
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Check if inertia_rails gem is installed
|
|
68
|
+
def inertia_gem_installed?
|
|
69
|
+
Gem.loaded_specs.key?('inertia_rails')
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Check if Inertia layout exists
|
|
73
|
+
def inertia_layout_exists?
|
|
74
|
+
root_path.join('app/views/layouts/inertia.html.erb').exist?
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Read Islands manifest
|
|
78
|
+
def read_islands_manifest
|
|
79
|
+
return {} unless islands_manifest_path.exist?
|
|
80
|
+
|
|
81
|
+
JSON.parse(islands_manifest_path.read)
|
|
82
|
+
rescue JSON::ParserError
|
|
83
|
+
{}
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Get Islands bundle path from manifest
|
|
87
|
+
def islands_bundle_path
|
|
88
|
+
manifest = read_islands_manifest
|
|
89
|
+
entry = manifest['app/javascript/entrypoints/islands.js']
|
|
90
|
+
|
|
91
|
+
return nil unless entry
|
|
92
|
+
|
|
93
|
+
"/islands/#{entry['file']}"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Check if package.json exists
|
|
97
|
+
def package_json_exists?
|
|
98
|
+
root_path.join('package.json').exist?
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Read package.json
|
|
102
|
+
def read_package_json
|
|
103
|
+
return {} unless package_json_exists?
|
|
104
|
+
|
|
105
|
+
JSON.parse(root_path.join('package.json').read)
|
|
106
|
+
rescue JSON::ParserError
|
|
107
|
+
{}
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Write package.json
|
|
111
|
+
def write_package_json(data)
|
|
112
|
+
root_path.join('package.json').write(JSON.pretty_generate(data) + "\n")
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Update package.json scripts for Islands
|
|
116
|
+
def update_package_json_scripts!
|
|
117
|
+
package_json = read_package_json
|
|
118
|
+
scripts = package_json['scripts'] || {}
|
|
119
|
+
|
|
120
|
+
# Always use namespaced scripts for consistency
|
|
121
|
+
scripts['build:islands'] = 'vite build --config vite.config.islands.ts'
|
|
122
|
+
scripts['watch:islands'] = 'vite build --config vite.config.islands.ts --watch'
|
|
123
|
+
|
|
124
|
+
# If there's an existing Vite setup (like Inertia), update main build script
|
|
125
|
+
if scripts['build'] && scripts['build'].include?('vite') && !scripts['build'].include?('build:islands')
|
|
126
|
+
scripts['build'] = "#{scripts['build']} && yarn build:islands"
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
package_json['scripts'] = scripts
|
|
130
|
+
write_package_json(package_json)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Detect which layout to use for Islands
|
|
134
|
+
def islands_layout_path
|
|
135
|
+
# Always use application.html.erb for Islands (ERB pages)
|
|
136
|
+
# Never touch inertia.html.erb (that's for SPA)
|
|
137
|
+
root_path.join('app/views/layouts/application.html.erb')
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Check if Islands helper is already in layout
|
|
141
|
+
def layout_has_islands_helper?
|
|
142
|
+
return false unless islands_layout_path.exist?
|
|
143
|
+
|
|
144
|
+
content = islands_layout_path.read
|
|
145
|
+
content.include?('<%= islands %>') || content.include?('islands %>')
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
data/lib/islandjs_rails.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require_relative "islandjs_rails/version"
|
|
2
2
|
require_relative "islandjs_rails/configuration"
|
|
3
|
+
require_relative "islandjs_rails/vite_integration"
|
|
3
4
|
require_relative "islandjs_rails/core"
|
|
4
5
|
require_relative "islandjs_rails/vendor_manager"
|
|
5
6
|
require_relative "islandjs_rails/cli"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// IslandJS Rails - Islands Entrypoint
|
|
2
|
+
// This file exports all your Island components to window.islandjsRails
|
|
3
|
+
// Components exported here can be used in ERB templates via <%= react_component('ComponentName') %>
|
|
4
|
+
|
|
5
|
+
// Import your island components
|
|
6
|
+
import HelloWorld from '../islands/components/HelloWorld.jsx'
|
|
7
|
+
|
|
8
|
+
// Export to global namespace for ERB template access
|
|
9
|
+
window.islandjsRails = {
|
|
10
|
+
HelloWorld,
|
|
11
|
+
// Add more components here as you create them:
|
|
12
|
+
// ChatWidget,
|
|
13
|
+
// UserProfile,
|
|
14
|
+
// etc.
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Optional: Log available components in development
|
|
18
|
+
if (import.meta.env.DEV) {
|
|
19
|
+
console.log('🏝️ IslandJS components loaded:', Object.keys(window.islandjsRails))
|
|
20
|
+
}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
</li>
|
|
20
20
|
<li class="flex items-start">
|
|
21
21
|
<span class="text-green-500 mr-2">✓</span>
|
|
22
|
-
|
|
22
|
+
Simplified build process - UMD libraries from vendor files
|
|
23
23
|
</li>
|
|
24
24
|
<li class="flex items-start">
|
|
25
25
|
<span class="text-green-500 mr-2">✓</span>
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
<ul class="space-y-1">
|
|
76
76
|
<li>• React & ReactDOM served from <code class="bg-gray-200 px-1 rounded">/islands/vendor/</code></li>
|
|
77
77
|
<li>• Browser caching for optimal performance</li>
|
|
78
|
-
<li>• No
|
|
78
|
+
<li>• No bundling of external libraries (loaded as UMD)</li>
|
|
79
79
|
</ul>
|
|
80
80
|
</div>
|
|
81
81
|
<div>
|
data/lib/templates/package.json
CHANGED
|
@@ -3,19 +3,12 @@
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"scripts": {
|
|
6
|
-
"build": "
|
|
7
|
-
"
|
|
8
|
-
"watch": "NODE_ENV=development webpack --watch"
|
|
6
|
+
"build:islands": "vite build --config vite.config.islands.ts",
|
|
7
|
+
"watch:islands": "vite build --config vite.config.islands.ts --watch"
|
|
9
8
|
},
|
|
10
9
|
"dependencies": {},
|
|
11
10
|
"devDependencies": {
|
|
12
|
-
"
|
|
13
|
-
"@
|
|
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"
|
|
11
|
+
"vite": "^5.4.19",
|
|
12
|
+
"@vitejs/plugin-react": "^5.0.0"
|
|
20
13
|
}
|
|
21
14
|
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* IslandJS Rails - Atomic Vite Build Script
|
|
5
|
+
*
|
|
6
|
+
* Builds both Inertia (if present) and Islands bundles atomically.
|
|
7
|
+
* If either build fails, the entire operation fails.
|
|
8
|
+
*
|
|
9
|
+
* Usage: node script/build-vite-atomic.js
|
|
10
|
+
* Or via package.json: yarn build
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { execSync } from 'child_process'
|
|
14
|
+
import fs from 'fs'
|
|
15
|
+
import path from 'path'
|
|
16
|
+
import { fileURLToPath } from 'url'
|
|
17
|
+
|
|
18
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
19
|
+
const rootDir = path.join(__dirname, '..')
|
|
20
|
+
|
|
21
|
+
// Check if a file exists
|
|
22
|
+
function fileExists(filepath) {
|
|
23
|
+
try {
|
|
24
|
+
return fs.existsSync(path.join(rootDir, filepath))
|
|
25
|
+
} catch {
|
|
26
|
+
return false
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Execute command and handle errors
|
|
31
|
+
function exec(command, description) {
|
|
32
|
+
console.log(`\n📦 ${description}...`)
|
|
33
|
+
try {
|
|
34
|
+
execSync(command, {
|
|
35
|
+
cwd: rootDir,
|
|
36
|
+
stdio: 'inherit',
|
|
37
|
+
env: process.env
|
|
38
|
+
})
|
|
39
|
+
console.log(`✅ ${description} succeeded`)
|
|
40
|
+
return true
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error(`❌ ${description} failed`)
|
|
43
|
+
throw error
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function buildAtomic() {
|
|
48
|
+
console.log('🏗️ Building Vite assets atomically...\n')
|
|
49
|
+
|
|
50
|
+
const hasInertia = fileExists('vite.config.ts')
|
|
51
|
+
const hasIslands = fileExists('vite.config.islands.ts')
|
|
52
|
+
|
|
53
|
+
if (!hasInertia && !hasIslands) {
|
|
54
|
+
console.error('❌ No Vite configs found!')
|
|
55
|
+
console.error(' Expected: vite.config.ts or vite.config.islands.ts')
|
|
56
|
+
process.exit(1)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
// Build Inertia if config exists
|
|
61
|
+
if (hasInertia) {
|
|
62
|
+
exec('vite build --emptyOutDir', 'Building Inertia assets')
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Build Islands if config exists
|
|
66
|
+
if (hasIslands) {
|
|
67
|
+
exec('vite build --config vite.config.islands.ts', 'Building Islands bundle')
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.log('\n🎉 All builds succeeded!')
|
|
71
|
+
console.log('\n📦 Built assets:')
|
|
72
|
+
|
|
73
|
+
if (hasInertia) {
|
|
74
|
+
console.log(' ✓ Inertia: public/vite-dev/')
|
|
75
|
+
}
|
|
76
|
+
if (hasIslands) {
|
|
77
|
+
console.log(' ✓ Islands: public/islands/')
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
process.exit(0)
|
|
81
|
+
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.error('\n❌ Build failed!')
|
|
84
|
+
console.error(' No changes were deployed (atomic guarantee)')
|
|
85
|
+
process.exit(1)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
buildAtomic()
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import react from '@vitejs/plugin-react'
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import fs from 'fs'
|
|
5
|
+
|
|
6
|
+
// IslandJS Rails - Islands Architecture Build Configuration
|
|
7
|
+
// This config builds React components as IIFE bundles for use in ERB templates
|
|
8
|
+
// Separate from your main Vite build (Inertia, etc.)
|
|
9
|
+
|
|
10
|
+
export default defineConfig({
|
|
11
|
+
plugins: [react()],
|
|
12
|
+
|
|
13
|
+
// CRITICAL: Disable copying public/ directory into build output
|
|
14
|
+
// Prevents Vite from copying public/vendor/islands → public/islands/vendor/islands
|
|
15
|
+
// We want vendor files to stay ONLY in public/vendor/islands (single source of truth)
|
|
16
|
+
publicDir: false,
|
|
17
|
+
|
|
18
|
+
// Define global constants for browser (replace Node.js process.env)
|
|
19
|
+
// CRITICAL: These must be string replacements, not JSON objects
|
|
20
|
+
define: {
|
|
21
|
+
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production'),
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
build: {
|
|
25
|
+
// Library mode for IIFE output
|
|
26
|
+
lib: {
|
|
27
|
+
entry: path.resolve(__dirname, 'app/javascript/entrypoints/islands.js'),
|
|
28
|
+
name: 'islandjsRails',
|
|
29
|
+
formats: ['iife'],
|
|
30
|
+
// Don't specify fileName here - let rollupOptions handle it
|
|
31
|
+
fileName: 'islands_bundle'
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
// Externalize React - loaded via UMD from CDN
|
|
35
|
+
rollupOptions: {
|
|
36
|
+
external: ['react', 'react-dom'],
|
|
37
|
+
output: {
|
|
38
|
+
globals: {
|
|
39
|
+
react: 'React',
|
|
40
|
+
'react-dom': 'ReactDOM'
|
|
41
|
+
},
|
|
42
|
+
// Use [hash] for content-based fingerprinting (auto cache-busting)
|
|
43
|
+
// This ensures every build change gets a new filename
|
|
44
|
+
entryFileNames: 'islands_bundle.[hash].js',
|
|
45
|
+
chunkFileNames: 'chunks/[name].[hash].js',
|
|
46
|
+
assetFileNames: 'assets/[name].[hash][extname]'
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
// Output to public/islands directory
|
|
51
|
+
outDir: 'public/islands',
|
|
52
|
+
// Clean output directory (vendor files are in public/vendor/islands, separate)
|
|
53
|
+
emptyOutDir: true,
|
|
54
|
+
|
|
55
|
+
// Generate manifest for Rails helpers (critical for fingerprinting!)
|
|
56
|
+
manifest: true,
|
|
57
|
+
|
|
58
|
+
// Source maps for development
|
|
59
|
+
sourcemap: process.env.NODE_ENV !== 'production'
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
resolve: {
|
|
63
|
+
alias: {
|
|
64
|
+
'@': path.resolve(__dirname, 'app/javascript')
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
})
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: islandjs-rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Eric Arnold
|
|
@@ -114,7 +114,7 @@ dependencies:
|
|
|
114
114
|
- !ruby/object:Gem::Version
|
|
115
115
|
version: '0.22'
|
|
116
116
|
description: IslandJS Rails enables React and other JavaScript islands in Rails apps
|
|
117
|
-
with zero
|
|
117
|
+
with zero build configuration. Load UMD libraries from CDNs, integrate with ERB
|
|
118
118
|
partials, and render components with Turbo-compatible lifecycle management.
|
|
119
119
|
email:
|
|
120
120
|
- ericarnold00+praxisemergent@gmail.com
|
|
@@ -127,7 +127,6 @@ files:
|
|
|
127
127
|
- LICENSE.md
|
|
128
128
|
- README.md
|
|
129
129
|
- exe/islandjs-rails
|
|
130
|
-
- islandjs-rails.gemspec
|
|
131
130
|
- lib/islandjs-rails.rb
|
|
132
131
|
- lib/islandjs_rails.rb
|
|
133
132
|
- lib/islandjs_rails/cli.rb
|
|
@@ -139,18 +138,19 @@ files:
|
|
|
139
138
|
- lib/islandjs_rails/tasks.rb
|
|
140
139
|
- lib/islandjs_rails/vendor_manager.rb
|
|
141
140
|
- lib/islandjs_rails/version.rb
|
|
141
|
+
- lib/islandjs_rails/vite_installer.rb
|
|
142
|
+
- lib/islandjs_rails/vite_integration.rb
|
|
142
143
|
- lib/templates/app/controllers/islandjs_demo_controller.rb
|
|
144
|
+
- lib/templates/app/javascript/entrypoints/islands.js
|
|
143
145
|
- lib/templates/app/javascript/islands/components/.gitkeep
|
|
144
146
|
- lib/templates/app/javascript/islands/components/HelloWorld.jsx
|
|
145
|
-
- lib/templates/app/javascript/islands/index.js
|
|
146
147
|
- lib/templates/app/javascript/islands/utils/turbo.js
|
|
147
148
|
- lib/templates/app/views/islandjs_demo/index.html.erb
|
|
148
149
|
- lib/templates/app/views/islandjs_demo/react.html.erb
|
|
149
150
|
- lib/templates/config/demo_routes.rb
|
|
150
151
|
- lib/templates/package.json
|
|
151
|
-
- lib/templates/
|
|
152
|
-
-
|
|
153
|
-
- yarn.lock
|
|
152
|
+
- lib/templates/script/build-vite-atomic.js
|
|
153
|
+
- lib/templates/vite.config.islands.ts
|
|
154
154
|
homepage: https://github.com/praxis-emergent/islandjs-rails
|
|
155
155
|
licenses:
|
|
156
156
|
- MIT
|
|
@@ -160,7 +160,8 @@ metadata:
|
|
|
160
160
|
changelog_uri: https://github.com/praxis-emergent/islandjs-rails/blob/main/CHANGELOG.md
|
|
161
161
|
documentation_uri: https://github.com/praxis-emergent/islandjs-rails/blob/main/README.md
|
|
162
162
|
post_install_message: "\n\U0001F3DD️ IslandJS Rails installed successfully!\n\n\U0001F4CB
|
|
163
|
-
Next step: Initialize IslandJS in your Rails app\n\n rails islandjs:init\n\
|
|
163
|
+
Next step: Initialize IslandJS in your Rails app\n\n rails islandjs:init\n\nThis
|
|
164
|
+
will set up Vite for Islands architecture alongside your existing setup.\n\n"
|
|
164
165
|
rdoc_options: []
|
|
165
166
|
require_paths:
|
|
166
167
|
- lib
|
data/islandjs-rails.gemspec
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
require_relative "lib/islandjs_rails/version"
|
|
2
|
-
|
|
3
|
-
Gem::Specification.new do |spec|
|
|
4
|
-
spec.name = "islandjs-rails"
|
|
5
|
-
spec.version = IslandjsRails::VERSION
|
|
6
|
-
spec.authors = ["Eric Arnold"]
|
|
7
|
-
spec.email = ["ericarnold00+praxisemergent@gmail.com"]
|
|
8
|
-
|
|
9
|
-
spec.summary = "Simple, modern JavaScript islands for Rails"
|
|
10
|
-
spec.description = "IslandJS Rails enables React and other JavaScript islands in Rails apps with zero webpack configuration. Load UMD libraries from CDNs, integrate with ERB partials, and render components with Turbo-compatible lifecycle management."
|
|
11
|
-
spec.homepage = "https://github.com/praxis-emergent/islandjs-rails"
|
|
12
|
-
spec.license = "MIT"
|
|
13
|
-
spec.required_ruby_version = ">= 3.0.0"
|
|
14
|
-
|
|
15
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
|
16
|
-
spec.metadata["source_code_uri"] = "https://github.com/praxis-emergent/islandjs-rails"
|
|
17
|
-
spec.metadata["changelog_uri"] = "https://github.com/praxis-emergent/islandjs-rails/blob/main/CHANGELOG.md"
|
|
18
|
-
spec.metadata["documentation_uri"] = "https://github.com/praxis-emergent/islandjs-rails/blob/main/README.md"
|
|
19
|
-
|
|
20
|
-
# Specify which files should be added to the gem when it is released.
|
|
21
|
-
spec.files = Dir.chdir(__dir__) do
|
|
22
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
|
23
|
-
(File.expand_path(f) == __FILE__) ||
|
|
24
|
-
f.start_with?(*%w[bin/ test/ spec/ features/ .git .github .claude appveyor Gemfile]) ||
|
|
25
|
-
f.match?(%r{\A(\.rspec|Rakefile)\z}) ||
|
|
26
|
-
f.end_with?(".gem")
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
spec.bindir = "exe"
|
|
31
|
-
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
32
|
-
spec.require_paths = ["lib"]
|
|
33
|
-
|
|
34
|
-
# Post-install message
|
|
35
|
-
spec.post_install_message = <<~MSG
|
|
36
|
-
|
|
37
|
-
🏝️ IslandJS Rails installed successfully!
|
|
38
|
-
|
|
39
|
-
📋 Next step: Initialize IslandJS in your Rails app
|
|
40
|
-
|
|
41
|
-
rails islandjs:init
|
|
42
|
-
|
|
43
|
-
MSG
|
|
44
|
-
|
|
45
|
-
# Rails integration
|
|
46
|
-
spec.add_dependency "rails", ">= 7.0", "< 9.0"
|
|
47
|
-
spec.add_dependency "thor", "~> 1.0"
|
|
48
|
-
|
|
49
|
-
# Development dependencies
|
|
50
|
-
spec.add_development_dependency "rake", "~> 13.0"
|
|
51
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
|
52
|
-
spec.add_development_dependency "webmock", "~> 3.0"
|
|
53
|
-
spec.add_development_dependency "vcr", "~> 6.0"
|
|
54
|
-
spec.add_development_dependency "simplecov", "~> 0.22"
|
|
55
|
-
end
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// IslandJS Rails - Main entry point
|
|
2
|
-
// This file is the webpack entry point for your JavaScript islands
|
|
3
|
-
|
|
4
|
-
// React component imports
|
|
5
|
-
import HelloWorld from './components/HelloWorld.jsx';
|
|
6
|
-
|
|
7
|
-
// Mount components to the global islandjsRails namespace
|
|
8
|
-
window.islandjsRails = {
|
|
9
|
-
HelloWorld
|
|
10
|
-
};
|
|
@@ -1,49 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
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
|
-
}
|