petite_vite_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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d7f877c8e144f5c7b0a61d316d91a9465886a972590be434bef460a3c9317dc8
4
+ data.tar.gz: 2ce8f54f5d543dddd77d4a5973d2a1f9b7ae7ba72bb908cd1555644c6a681613
5
+ SHA512:
6
+ metadata.gz: 8fb5f89e45482976808e5b92e4a6aaaa464707fbb79c62cbc00b1a3e853c1dcef8cf327781e37ec9cdb2fbb3fd3d9f026f69896cdb47a4a111a3de2e62658faa
7
+ data.tar.gz: 418231e3782e40e49e0ea8933f5c52ba2b68a4e8bf910778d4707c8b1135995428d6569eb5a5b4b9ce515da2a0a55f31580c690f81ffc0f36759daa36236dfd0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright Zach Ahn
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # A Petite Vite integration Rails
2
+
3
+ A small Rails plugin that wires a Vite frontend into a Rails app. It provides a `vite_tags` view helper, an install generator, and rake task hooks — nothing more.
4
+
5
+ The Vite project lives in a subdirectory (e.g. `frontend/`) and is wired up as a [yarn workspace](https://yarnpkg.com/features/workspaces).
6
+
7
+ In development, `vite_tags` emits script tags pointing at the Vite dev server. In production, it reads Vite's `manifest.json` and emits hashed asset tags with `modulepreload` links, following Vite's [backend integration](https://vite.dev/guide/backend-integration.html) recipe.
8
+
9
+ ## Installation
10
+
11
+ ```sh
12
+ bundle add petite_vite_rails
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ### 1. Setup Vite Project
18
+
19
+ Create a Vite project within your Rails app (e.g. with `yarn create vue <path/to/frontend>`). I recommend putting it under the folder `frontend` or `app/frontend`.
20
+
21
+ ```
22
+ my-rails-site
23
+ ├── app
24
+ │   ├── assets
25
+ │   ├── controllers
26
+ │   ├── frontend ← *also recommended*
27
+ │   ├── models
28
+ │   └── views
29
+ ├── frontend ← *most recommended*
30
+ ├── Gemfile
31
+ └── ...
32
+ ```
33
+
34
+ ### 2. Install PetiteVite
35
+
36
+ Then, run the install generator. This sets up required configuration in addition to editing a few key files.
37
+
38
+ ```sh
39
+ rails generate petite_vite:install --frontend-root <path/to/frontend> # defaults to "frontend"
40
+ ```
41
+
42
+ Run `rails generate petite_vite:install --help` for all available options.
43
+
44
+ ### 3. Setup a controller
45
+
46
+ Your frontend framework will probably need a mount point — the HTML element where the frontend app would be rendered in. Run the scaffold generator to create the controller and view, and optionally to generate routes.
47
+
48
+ ```sh
49
+ rails generate petite_vite:scaffold --route-root --route-all
50
+ ```
51
+
52
+ Run `rails generate petite_vite:scaffold --help` for all available options.
53
+
54
+ ### 4. Start your app with `bin/dev`
55
+
56
+ Run `bin/dev` (see `Procfile.dev`) to run both the Vite development server and the Rails server. The Vite server allows for auto-reloads.
57
+
58
+ ### 5. Production deploys
59
+
60
+ PetiteVite integrates with `rails assets:precompile`. PetiteVite does NOT support running the Vite server in production.
61
+
62
+ ## Tips
63
+
64
+ - I like to set up a frontend router. I then create server routes for each frontend-based route. These routes just render the mountpoint, and the frontend app takes care of the rest.
65
+
66
+ ## License
67
+
68
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require "bundler/setup"
2
+
3
+ require "bundler/gem_tasks"
4
+
5
+ require "standard/rake"
@@ -0,0 +1,20 @@
1
+ Description:
2
+ Installs PetiteVite
3
+
4
+ Options:
5
+ --vite-dev-server-port
6
+ Port for the Vite dev server. Defaults to 5173.
7
+
8
+ --frontend-root
9
+ Path to the frontend (Vite) project. Defaults to "frontend".
10
+
11
+ --rails-development-url
12
+ Rails development server URL (used as the Vite CORS origin).
13
+ Defaults to "http://localhost:3000".
14
+
15
+ --skip-frontend-check
16
+ Skip the check that the frontend (Vite) project exists.
17
+ Defaults to false.
18
+
19
+ Example:
20
+ rails generate petite_vite:install
@@ -0,0 +1,183 @@
1
+ module PetiteVite
2
+ class InstallGenerator < Rails::Generators::Base
3
+ source_root File.expand_path("templates", __dir__)
4
+
5
+ def self.exit_on_failure?
6
+ true
7
+ end
8
+
9
+ class_option :vite_dev_server_port, type: :numeric, default: 5173,
10
+ banner: "Port for the Vite dev server"
11
+ class_option :frontend_root, type: :string, default: "frontend",
12
+ banner: "Path to frontend (Vite) project"
13
+ class_option :rails_development_url, type: :string, default: "http://localhost:3000",
14
+ banner: "Specifies the Rails development server URL"
15
+ class_option :skip_frontend_check, type: :boolean, default: false,
16
+ banner: "Skip the check that frontend (Vite) project exists"
17
+
18
+ def verify_input
19
+ vite_dev_server_port!
20
+ frontend_root!
21
+ rails_development_url!
22
+ skip_frontend_check!
23
+ end
24
+
25
+ def verify_frontend_exists
26
+ return if skip_frontend_check!
27
+
28
+ path = File.join(destination_root, frontend_root!)
29
+ unless File.exist?(path)
30
+ raise "Expected #{path} to exist. Pass --skip-frontend-check to bypass."
31
+ end
32
+
33
+ path = File.join(destination_root, frontend_root!, "package.json")
34
+ unless File.exist?(path)
35
+ raise "Expected #{path} to exist. Pass --skip-frontend-check to bypass."
36
+ end
37
+ end
38
+
39
+ def create_initializer
40
+ template("initializer.rb", "config/initializers/petite_vite.rb")
41
+ template("petite_vite.json", "config/petite_vite.json")
42
+ end
43
+
44
+ def create_package_json
45
+ template("package.json", "package.json")
46
+ end
47
+
48
+ def create_dev_scripts
49
+ return if File.exist?(File.join(destination_root, "Procfile.dev"))
50
+
51
+ template("Procfile.dev", "Procfile.dev")
52
+ template("bin/dev", "bin/dev")
53
+ chmod("bin/dev", 0o755)
54
+ end
55
+
56
+ def insert_to_procfile_dev
57
+ append_to_file("Procfile.dev", "vite: cd #{frontend_root!} && yarn dev\n")
58
+ end
59
+
60
+ def insert_to_frontend_source_main
61
+ prepend_to_file(File.join(destination_root, frontend_root!, frontend_source_main!), "import 'vite/modulepreload-polyfill'\n")
62
+ end
63
+
64
+ def insert_to_vite_config
65
+ vite_config_path = File.join(destination_root, frontend_root!, frontend_vite_config!)
66
+
67
+ depth = frontend_root!.count("/") + 1
68
+ relative_prefix = "../" * depth
69
+ insert_into_file(vite_config_path, before: %r{^\s*export default defineConfig\b}, verbose: false) do
70
+ "import shared from '#{relative_prefix}config/petite_vite.json'\n"
71
+ end
72
+
73
+ injected = <<~SCRIPT.indent(2)
74
+ clearScreen: false,
75
+ server: {
76
+ cors: {
77
+ origin: shared.viteCorsOrigin,
78
+ },
79
+ origin: shared.viteCorsOrigin,
80
+ port: shared.viteDevServerPort,
81
+ strictPort: true,
82
+ },
83
+ build: {
84
+ manifest: true,
85
+ rollupOptions: {
86
+ input: shared.frontendInput,
87
+ },
88
+ },
89
+ SCRIPT
90
+
91
+ gsub_file(vite_config_path, %r{(export default defineConfig\s*\(\s*\{\s*\n)}, "\\1#{injected}", verbose: false)
92
+ end
93
+
94
+ def insert_to_layout
95
+ Dir.glob(File.join(destination_root, "app", "views", "layouts", "**.html.erb")).each do |abspath|
96
+ basename = File.basename(abspath)
97
+ next if basename == "mailer.html.erb"
98
+ relpath = Pathname.new(abspath).relative_path_from(destination_root).to_s
99
+ insert_into_file(relpath, before: %r{^\s*</head>}, verbose: false) do
100
+ "<%= vite_tags %>\n"
101
+ end
102
+ end
103
+ end
104
+
105
+ private
106
+
107
+ def vite_dev_server_port!
108
+ @options_vite_dev_server_port ||=
109
+ options
110
+ .fetch("vite_dev_server_port")
111
+ .yield_self do |value|
112
+ port = Integer(value)
113
+ raise "Invalid option: vite_dev_server_port must be between 1 and 65535" if port < 1 || port > 65535
114
+ port
115
+ end
116
+ end
117
+
118
+ def frontend_root!
119
+ @options_frontend_root ||=
120
+ options
121
+ .fetch("frontend_root")
122
+ .sub(%r{/+\z}, "")
123
+ .tap do |result|
124
+ raise "Invalid option: frontend_root must not be the Rails root directory" if result == "." || result.empty?
125
+ raise "Invalid option: frontend_root must not start with /" if result.start_with?("/")
126
+ raise "Invalid option: frontend_root must only have [a-z0-9_/-]" if !%r{\A[a-z0-9_/-]+\z}i.match?(result)
127
+ end
128
+ end
129
+
130
+ def rails_development_url!
131
+ @options_rails_development_url ||=
132
+ options
133
+ .fetch("rails_development_url")
134
+ .yield_self do
135
+ u = URI(it)
136
+ u.path = ""
137
+ u.fragment = nil
138
+ u.query = nil
139
+ u.to_s
140
+ end
141
+ end
142
+
143
+ def skip_frontend_check!
144
+ if @options_skip_frontend_check.nil?
145
+ @options_skip_frontend_check = options.fetch("skip_frontend_check")
146
+ end
147
+
148
+ @options_skip_frontend_check
149
+ end
150
+
151
+ def frontend_source_main!
152
+ @frontend_source_main ||= begin
153
+ candidates = %w[main.ts main.tsx main.js main.jsx]
154
+ found = candidates.find { |c| File.exist?(File.join(destination_root, frontend_root!, "src", c)) }
155
+ unless found
156
+ raise "Expected one of #{candidates.map { |c| "src/#{c}" }.join(", ")} to exist in #{frontend_root!}."
157
+ end
158
+ "/src/#{found}"
159
+ end
160
+ end
161
+
162
+ # Vite's dev server strips a .ts extension when serving (so /src/main.js
163
+ # resolves to main.ts), but does NOT do this for .tsx/.jsx — those must be
164
+ # requested with their original extension.
165
+ def frontend_output!
166
+ @frontend_output ||= frontend_source_main!.sub(/\.ts\z/, ".js")
167
+ end
168
+
169
+ def frontend_vite_config!
170
+ @frontend_vite_config ||= begin
171
+ ts = File.join(destination_root, frontend_root!, "vite.config.ts")
172
+ js = File.join(destination_root, frontend_root!, "vite.config.js")
173
+ if File.exist?(ts)
174
+ "vite.config.ts"
175
+ elsif File.exist?(js)
176
+ "vite.config.js"
177
+ else
178
+ raise "Expected #{ts} or #{js} to exist."
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1 @@
1
+ web: bin/rails server
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+
3
+ if ! command -v foreman &> /dev/null
4
+ then
5
+ echo "Installing foreman..."
6
+ gem install foreman
7
+ fi
8
+
9
+ foreman start -f Procfile.dev
@@ -0,0 +1,6 @@
1
+ # typed: true
2
+
3
+ PetiteVite.config = PetiteVite::Config.new(
4
+ shared_json_path: Rails.root.join("config", "petite_vite.json"),
5
+ vite_manifest_relpath: "dist/.vite/manifest.json"
6
+ )
@@ -0,0 +1,8 @@
1
+ <%= JSON.pretty_generate(
2
+ {
3
+ private: true,
4
+ workspaces: [
5
+ options.fetch("frontend_root")
6
+ ]
7
+ }
8
+ ) %>
@@ -0,0 +1,10 @@
1
+ <%= JSON.pretty_generate(
2
+ {
3
+ buildCommand: nil,
4
+ frontendInput: frontend_source_main!,
5
+ frontendOutput: frontend_output!,
6
+ frontendRoot: frontend_root!,
7
+ viteCorsOrigin: rails_development_url!,
8
+ viteDevServerPort: vite_dev_server_port!
9
+ }
10
+ ) %>
@@ -0,0 +1,17 @@
1
+ Description:
2
+ Generates a PetiteViteController + page view with a mount div matching
3
+ the frontend project's index.html. Optionally wires up routes.
4
+
5
+ Options:
6
+ --route-root
7
+ Adds `root "petite_vite#page"` to config/routes.rb (skipped if a
8
+ root route is already defined).
9
+
10
+ --route-all
11
+ Adds `get "*path", to: "petite_vite#page"` to config/routes.rb so
12
+ client-side routing in the SPA works without extra wiring.
13
+
14
+ Example:
15
+ rails generate petite_vite:scaffold
16
+ rails generate petite_vite:scaffold --route-root
17
+ rails generate petite_vite:scaffold --route-root --route-all
@@ -0,0 +1,83 @@
1
+ require "json"
2
+
3
+ module PetiteVite
4
+ class ScaffoldGenerator < Rails::Generators::Base
5
+ source_root File.expand_path("templates", __dir__)
6
+
7
+ def self.exit_on_failure?
8
+ true
9
+ end
10
+
11
+ class_option :route_root, type: :boolean, default: false,
12
+ banner: "Add `root \"petite_vite#page\"` to config/routes.rb"
13
+ class_option :route_all, type: :boolean, default: false,
14
+ banner: "Add `get \"*path\", to: \"petite_vite#page\"` to config/routes.rb"
15
+
16
+ def verify_input
17
+ mount_id!
18
+ end
19
+
20
+ def create_controller
21
+ template("controller.rb", "app/controllers/petite_vite_controller.rb")
22
+ end
23
+
24
+ def create_view
25
+ template("page.html.erb", "app/views/petite_vite/page.html.erb")
26
+ end
27
+
28
+ def insert_root_route
29
+ return unless options.fetch("route_root")
30
+
31
+ routes_path = File.join(destination_root, "config/routes.rb")
32
+ if /^\s*root\s/.match?(File.read(routes_path))
33
+ say_status("skip", "root route already defined in config/routes.rb", :yellow)
34
+ return
35
+ end
36
+
37
+ insert_into_file("config/routes.rb", after: %r{Rails\.application\.routes\.draw do\n}, verbose: false) do
38
+ " root \"petite_vite#page\"\n"
39
+ end
40
+ end
41
+
42
+ def insert_catchall_route
43
+ return unless options.fetch("route_all")
44
+
45
+ insert_into_file("config/routes.rb", before: %r{^end\s*\z}, verbose: false) do
46
+ " get \"*path\", to: \"petite_vite#page\"\n"
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def frontend_root!
53
+ @frontend_root ||= begin
54
+ shared_path = File.join(destination_root, "config/petite_vite.json")
55
+ unless File.exist?(shared_path)
56
+ raise "Expected #{shared_path} to exist. Run `rails g petite_vite:install` first."
57
+ end
58
+ JSON.parse(File.read(shared_path)).fetch("frontendRoot")
59
+ end
60
+ end
61
+
62
+ def index_html_path!
63
+ @index_html_path ||= begin
64
+ path = File.join(destination_root, frontend_root!, "index.html")
65
+ unless File.exist?(path)
66
+ raise "Expected #{path} to exist."
67
+ end
68
+ path
69
+ end
70
+ end
71
+
72
+ def mount_id!
73
+ @mount_id ||= begin
74
+ contents = File.read(index_html_path!)
75
+ match = contents.match(/<div\b[^>]*\bid=["']([^"']+)["']/i)
76
+ unless match
77
+ raise "Could not determine mount-point id from #{index_html_path!}. Expected a <div id=\"...\"> element."
78
+ end
79
+ match[1]
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,4 @@
1
+ class PetiteViteController < ApplicationController
2
+ def page
3
+ end
4
+ end
@@ -0,0 +1 @@
1
+ <div id="<%= mount_id! %>"></div>
@@ -0,0 +1,13 @@
1
+ module PetiteViteRails
2
+ class Railtie < ::Rails::Railtie
3
+ initializer "petite_vite_rails.helpers" do
4
+ ActiveSupport.on_load(:action_view) do
5
+ include PetiteVite::ViewHelper
6
+ end
7
+ end
8
+
9
+ rake_tasks do
10
+ load File.expand_path("../tasks/petite_vite.rake", __dir__)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module PetiteViteRails
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,57 @@
1
+ module PetiteVite
2
+ module ViewHelper
3
+ def vite_tags
4
+ if Rails.env.development?
5
+ port = PetiteVite.config.vite_dev_server_port
6
+ frontend_output = PetiteVite.config.frontend_output.sub(%r{^/+}, "")
7
+ <<~SCRIPTS.html_safe
8
+ <script type="module" src="http://localhost:#{port}/@vite/client"></script>
9
+ <script type="module" src="http://localhost:#{port}/#{frontend_output}"></script>
10
+ SCRIPTS
11
+ else
12
+ # https://vite.dev/guide/backend-integration.html
13
+ #
14
+ # <!-- 0. if production -->
15
+ #
16
+ # <!-- 1. for cssFile of manifest[name].css -->
17
+ # <link rel="stylesheet" href="/{{ cssFile }}" />
18
+ #
19
+ # <!-- 2. for chunk of importedChunks(manifest, name) -->
20
+ # <!-- 3. for cssFile of chunk.css -->
21
+ # <link rel="stylesheet" href="/{{ cssFile }}" />
22
+ #
23
+ # <!-- 4 -->
24
+ # <script type="module" src="/{{ manifest[name].file }}"></script>
25
+ #
26
+ # <!-- 5. for chunk of importedChunks(manifest, name) -->
27
+ # <link rel="modulepreload" href="/{{ chunk.file }}" />
28
+
29
+ out = []
30
+ PetiteVite.config.manifest.contents.each do |_name, chunk|
31
+ next if !chunk["isEntry"]
32
+ # 1
33
+ chunk["css"]&.each do |css|
34
+ out.push(%(<link rel="stylesheet" href="/#{css}" />))
35
+ end
36
+ # 2
37
+ chunk["dynamicImports"]&.each do |imported_name|
38
+ # 3
39
+ imported_chunk = PetiteVite.config.manifest.contents[imported_name]
40
+ imported_chunk["css"]&.each do |css|
41
+ out.push(%(<link rel="stylesheet" href="/#{css}" />))
42
+ end
43
+ end
44
+ # 4
45
+ out.push(%(<script type="module" src="/#{chunk.fetch("file")}"></script>))
46
+ # 5
47
+ chunk["dynamicImports"]&.each do |imported_name|
48
+ imported_chunk = PetiteVite.config.manifest.contents[imported_name]
49
+ out.push(%(<link rel="modulepreload" href="/#{imported_chunk.fetch("file")}" />))
50
+ end
51
+ end
52
+
53
+ out.join("\n").html_safe
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,61 @@
1
+ require_relative "petite_vite_rails/version"
2
+ require_relative "petite_vite_rails/view_helper"
3
+ require_relative "petite_vite_rails/railtie"
4
+
5
+ module PetiteVite
6
+ class << self
7
+ attr_accessor :config
8
+ end
9
+
10
+ class Config
11
+ DEFAULT_VITE_DEV_SERVER_PORT = 5173
12
+
13
+ def initialize(shared_json_path:, vite_manifest_relpath:)
14
+ @shared_json_path = shared_json_path
15
+ @contents = JSON.parse(File.read(shared_json_path))
16
+ @vite_manifest_relpath = vite_manifest_relpath
17
+ end
18
+
19
+ def build_command = @contents.fetch("buildCommand")
20
+
21
+ def frontend_output = @contents.fetch("frontendOutput")
22
+
23
+ def frontend_root = @contents.fetch("frontendRoot")
24
+
25
+ def vite_dev_server_port
26
+ return DEFAULT_VITE_DEV_SERVER_PORT if !@contents.key?("viteDevServerPort")
27
+
28
+ value = @contents.fetch("viteDevServerPort")
29
+ if !value.is_a?(Integer)
30
+ raise "Invalid viteDevServerPort in #{@shared_json_path}: expected an Integer, got #{value.inspect}"
31
+ end
32
+ value
33
+ end
34
+
35
+ def manifest_path = File.join(frontend_root, @vite_manifest_relpath)
36
+
37
+ def manifest
38
+ @manifest ||= Manifest.new(config: self, manifest_path: manifest_path)
39
+ end
40
+ end
41
+
42
+ class Manifest
43
+ def initialize(config:, manifest_path:)
44
+ @config = config
45
+ @manifest_path = manifest_path
46
+ end
47
+
48
+ def contents
49
+ if instance_variable_defined?(:@contents)
50
+ return @contents
51
+ end
52
+
53
+ @contents =
54
+ if File.exist?(@manifest_path)
55
+ JSON.parse(File.read(@manifest_path))
56
+ else
57
+ {}
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,32 @@
1
+ namespace :petite_vite do
2
+ task build: :environment do
3
+ frontend_root = Rails.root / PetiteVite.config.frontend_root
4
+
5
+ Dir.chdir(frontend_root) do
6
+ sh(PetiteVite.config.build_command || "yarn run build")
7
+ end
8
+ end
9
+
10
+ task place: :environment do
11
+ frontend_root = Rails.root / PetiteVite.config.frontend_root
12
+ rails_asset_root = Rails.root / "public" / "assets"
13
+ rails_asset_root.mkdir if !rails_asset_root.directory?
14
+
15
+ frontend_root.join("dist", "assets").each_child do |asset|
16
+ cp asset, rails_asset_root
17
+ end
18
+ end
19
+ end
20
+
21
+ return if ENV["SKIP_JS_BUILD"]
22
+
23
+ if Rake::Task.task_defined?("assets:precompile")
24
+ Rake::Task["assets:precompile"].enhance(["petite_vite:build", "petite_vite:place"])
25
+ end
26
+
27
+ ["test:prepare", "spec:prepare"].each do |test_prepare|
28
+ if Rake::Task.task_defined?(test_prepare)
29
+ Rake::Task[test_prepare].enhance(["petite_vite:build", "petite_vite:place"])
30
+ break
31
+ end
32
+ end
@@ -0,0 +1,21 @@
1
+ require_relative "lib/petite_vite_rails/version"
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "petite_vite_rails"
5
+ spec.version = PetiteViteRails::VERSION
6
+ spec.authors = ["Zach Ahn"]
7
+ spec.email = ["engineering@zachahn.com"]
8
+ spec.homepage = "https://github.com/zachahn/petite_vite_rails"
9
+ spec.summary = "A petite Vite integration for Rails"
10
+ spec.license = "MIT"
11
+
12
+ spec.metadata["homepage_uri"] = spec.homepage
13
+
14
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
15
+ Dir["{app,config,db,lib}/**/*", "LICENSE", "Rakefile", "README.md", "*.gemspec"]
16
+ .select { |path| File.file?(path) }
17
+ .sort
18
+ end
19
+
20
+ spec.add_dependency "rails", ">= 8.0.0"
21
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: petite_vite_rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Zach Ahn
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rails
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: 8.0.0
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: 8.0.0
26
+ email:
27
+ - engineering@zachahn.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - LICENSE
33
+ - README.md
34
+ - Rakefile
35
+ - lib/generators/petite_vite/install/USAGE
36
+ - lib/generators/petite_vite/install/install_generator.rb
37
+ - lib/generators/petite_vite/install/templates/Procfile.dev.tt
38
+ - lib/generators/petite_vite/install/templates/bin/dev.tt
39
+ - lib/generators/petite_vite/install/templates/initializer.rb.tt
40
+ - lib/generators/petite_vite/install/templates/package.json.tt
41
+ - lib/generators/petite_vite/install/templates/petite_vite.json.tt
42
+ - lib/generators/petite_vite/scaffold/USAGE
43
+ - lib/generators/petite_vite/scaffold/scaffold_generator.rb
44
+ - lib/generators/petite_vite/scaffold/templates/controller.rb.tt
45
+ - lib/generators/petite_vite/scaffold/templates/page.html.erb.tt
46
+ - lib/petite_vite_rails.rb
47
+ - lib/petite_vite_rails/railtie.rb
48
+ - lib/petite_vite_rails/version.rb
49
+ - lib/petite_vite_rails/view_helper.rb
50
+ - lib/tasks/petite_vite.rake
51
+ - petite_vite_rails.gemspec
52
+ homepage: https://github.com/zachahn/petite_vite_rails
53
+ licenses:
54
+ - MIT
55
+ metadata:
56
+ homepage_uri: https://github.com/zachahn/petite_vite_rails
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirements: []
71
+ rubygems_version: 4.0.12
72
+ specification_version: 4
73
+ summary: A petite Vite integration for Rails
74
+ test_files: []