react-email-rails 0.1.0 → 0.1.1
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 +5 -0
- data/CONTRIBUTING.md +3 -32
- data/README.md +50 -14
- data/lib/react_email_rails/configuration.rb +1 -0
- data/lib/react_email_rails/railtie.rb +2 -0
- data/lib/react_email_rails/render_modes/subprocess.rb +1 -1
- data/lib/react_email_rails/tasks.rb +32 -0
- data/lib/react_email_rails/version.rb +1 -1
- data/lib/react_email_rails.rb +1 -0
- data/lib/tasks/react_email_rails/build.rake +23 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 87e5a6099e4591961f8568f277d6470364c52b35ef9a5f859ddba645834d97e9
|
|
4
|
+
data.tar.gz: 8130ded931b6caa0d9b0c5a72ce2671891cd6eca53ab7cb29704b7ff65e90891
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0654a149d0fc2e8f5bdeafd42e26059ed7b4cf41a223b147a6c45ff42cf5ac8af9d346b13d8a5660682ebf9d7a59b167d3c89e815e2f9cdb719a69b1c2ee9171
|
|
7
|
+
data.tar.gz: 37abce1546d5fc5382bcfc9932030433f1e2a6b557fa83f98a4cd30ad3f9e465613148866933f4801281f2c1229935cc3e09a57e54900164ab97da7d6510f8e6
|
data/CHANGELOG.md
CHANGED
data/CONTRIBUTING.md
CHANGED
|
@@ -22,47 +22,18 @@ cd vite && pnpm run build
|
|
|
22
22
|
|
|
23
23
|
The Ruby gem version in `lib/react_email_rails/version.rb` is the package version source of truth. The renderer protocol version in `lib/react_email_rails/render_protocol.rb` is also synced into the Vite package. Run `cd vite && pnpm run sync:version` after changing either one.
|
|
24
24
|
|
|
25
|
-
## Release Checks
|
|
26
|
-
|
|
27
|
-
Before publishing, verify both packages can be built:
|
|
28
|
-
|
|
29
|
-
```sh
|
|
30
|
-
bundle exec rake build
|
|
31
|
-
cd vite && pnpm pack --dry-run
|
|
32
|
-
```
|
|
33
|
-
|
|
34
25
|
## Publishing
|
|
35
26
|
|
|
36
27
|
Releases are tag-driven. Pushing `vX.Y.Z` to GitHub runs `.github/workflows/release.yml`, publishes the Ruby gem to RubyGems, publishes the Vite package to npm, and creates the GitHub Release with the built `.gem` and `.tgz` artifacts.
|
|
37
28
|
|
|
38
29
|
### Patch, Minor, and Major Releases
|
|
39
30
|
|
|
40
|
-
|
|
31
|
+
Update the source-of-truth gem version in `lib/react_email_rails/version.rb`, update `CHANGELOG.md`, and commit the release prep on `main` or open and merge a release pull request. Then tag the release commit:
|
|
41
32
|
|
|
42
33
|
```sh
|
|
43
|
-
|
|
44
|
-
# or: ruby scripts/prepare_release.rb minor
|
|
45
|
-
# or: ruby scripts/prepare_release.rb major
|
|
34
|
+
bin/release
|
|
46
35
|
```
|
|
47
36
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
```sh
|
|
51
|
-
ruby scripts/check_version_sync.rb
|
|
52
|
-
bin/test
|
|
53
|
-
bin/lint
|
|
54
|
-
cd vite && pnpm run ci && pnpm pack --dry-run
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Commit the release prep on `main` or open and merge a release pull request. Then tag the release commit:
|
|
58
|
-
|
|
59
|
-
```sh
|
|
60
|
-
git switch main
|
|
61
|
-
git pull --ff-only origin main
|
|
62
|
-
VERSION=$(ruby -r ./lib/react_email_rails/version -e 'print ReactEmailRails::VERSION')
|
|
63
|
-
ruby scripts/check_release_tag.rb "v$VERSION"
|
|
64
|
-
git tag -a "v$VERSION" -m "v$VERSION"
|
|
65
|
-
git push origin "v$VERSION"
|
|
66
|
-
```
|
|
37
|
+
`bin/release` fetches `origin/main`, validates the version and changelog, infers whether the release is patch, minor, major, or initial from the existing SemVer tags, creates the annotated `vX.Y.Z` tag on `origin/main`, and pushes it after confirmation.
|
|
67
38
|
|
|
68
39
|
The GitHub release workflow handles the rest. If publishing fails before both registries are updated, do not reuse the same version unless neither registry accepted it; bump to the next patch version and release again.
|
data/README.md
CHANGED
|
@@ -25,7 +25,7 @@ Building HTML emails is painfully archaic. [React Email](https://react.email) is
|
|
|
25
25
|
|
|
26
26
|
**In development,** the gem renders components live through Vite's dev pipeline, so your emails get the same module resolution and transforms as the rest of your frontend.
|
|
27
27
|
|
|
28
|
-
**In production,**
|
|
28
|
+
**In production,** Rails builds a server-side email bundle during `assets:precompile`. The bundled rake task runs an isolated email-only Vite build, using `reactEmailRails()` in your app's Vite config for discovery and options.
|
|
29
29
|
|
|
30
30
|
Delivery, headers, multipart parts, previews, queues, and callbacks all stay normal Action Mailer. If rendering fails, no email is sent and `ReactEmailRails::RenderError` is raised.
|
|
31
31
|
|
|
@@ -64,6 +64,13 @@ bin/rails generate react_email_rails:install
|
|
|
64
64
|
|
|
65
65
|
This creates `config/initializers/react_email_rails.rb`, installs missing JavaScript dependencies when it can detect your package manager, adds `reactEmailRails()` to `vite.config.*`, and creates `app/javascript/emails`.
|
|
66
66
|
|
|
67
|
+
The installed setup follows the normal Rails lifecycle:
|
|
68
|
+
|
|
69
|
+
- `bin/rails generate react_email_rails:email ...` creates matching mailers and React components.
|
|
70
|
+
- Development renders through Vite on demand.
|
|
71
|
+
- `bin/rails assets:precompile` builds the production email bundle automatically.
|
|
72
|
+
- `bin/rails react_email_rails:build` builds the bundle directly when CI or tests need it.
|
|
73
|
+
|
|
67
74
|
### Manual Install
|
|
68
75
|
|
|
69
76
|
Install the npm package and peer dependencies manually:
|
|
@@ -393,9 +400,9 @@ end
|
|
|
393
400
|
|
|
394
401
|
### Vite Configuration
|
|
395
402
|
|
|
396
|
-
Most apps only need the `reactEmailRails()` plugin from [Quick Start](#quick-start). The options below change where components are discovered
|
|
403
|
+
Most apps only need the `reactEmailRails()` plugin from [Quick Start](#quick-start). The options below change where components are discovered, how the bundle handles dependencies, and which email-only Vite transforms run in the isolated renderer.
|
|
397
404
|
|
|
398
|
-
In development, the renderer loads the `reactEmailRails()` plugin, JSX support, and
|
|
405
|
+
In development and production, the isolated renderer loads the `reactEmailRails()` plugin, JSX support, and component-facing Vite config such as `resolve`, `define`, `css`, `json`, `assetsInclude`, `esbuild`, and `oxc` — but none of your other app plugins. Forwarded config is only for compiling and resolving email components; server, preview, dependency optimization, and build output settings stay owned by React Email Rails.
|
|
399
406
|
|
|
400
407
|
#### Plugin Options
|
|
401
408
|
|
|
@@ -405,6 +412,7 @@ In development, the renderer loads the `reactEmailRails()` plugin, JSX support,
|
|
|
405
412
|
| `emails.extension` | `[".tsx", ".jsx"]` | Component extension, or an array of extensions |
|
|
406
413
|
| `emails.ignore` | `["**/_*", "**/_*/**"]` | Glob patterns ignored under `emails.path` |
|
|
407
414
|
| `standalone` | `true` | Inline SSR dependencies with `ssr.noExternal: true` |
|
|
415
|
+
| `vite` | `{}` | Extra email-only Vite config for compilation and resolution |
|
|
408
416
|
|
|
409
417
|
Use a custom directory:
|
|
410
418
|
|
|
@@ -426,6 +434,28 @@ reactEmailRails({
|
|
|
426
434
|
|
|
427
435
|
Component names come from the Vite directory layout (see [Component Names](#component-names)). To map mailer actions to a different layout, override `component_path_resolver` on the Ruby side rather than renaming in the plugin, so both halves stay in sync.
|
|
428
436
|
|
|
437
|
+
#### Advanced: Email-Only Vite Plugins
|
|
438
|
+
|
|
439
|
+
Most apps do not need extra email plugins. If email components need a transform that is not part of Vite's default pipeline, add that transform to the email renderer:
|
|
440
|
+
|
|
441
|
+
```ts
|
|
442
|
+
import mdx from "@mdx-js/rollup"
|
|
443
|
+
import { defineConfig } from "vite"
|
|
444
|
+
import { reactEmailRails } from "react-email-rails"
|
|
445
|
+
|
|
446
|
+
export default defineConfig({
|
|
447
|
+
plugins: [
|
|
448
|
+
reactEmailRails({
|
|
449
|
+
vite: {
|
|
450
|
+
plugins: [mdx()],
|
|
451
|
+
},
|
|
452
|
+
}),
|
|
453
|
+
],
|
|
454
|
+
})
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
These `vite` options are used by `react-email-rails-dev` and `react-email-rails-build`. They are intentionally scoped to React Email. Only `assetsInclude`, `css`, `define`, `esbuild`, `json`, `oxc`, `plugins`, and `resolve` are accepted here; output settings such as `build.outDir` and `build.rollupOptions` are ignored so the Ruby renderer can always find the generated bundle.
|
|
458
|
+
|
|
429
459
|
#### Standalone Builds
|
|
430
460
|
|
|
431
461
|
By default the email bundle inlines React, `@react-email/render`, and other Node dependencies. That makes the bundle larger, but it works well for Rails deploys that build assets in one stage and run without `node_modules` in the final runtime image.
|
|
@@ -442,23 +472,29 @@ Externalized bundles are smaller and may build faster, but the renderer needs th
|
|
|
442
472
|
|
|
443
473
|
## Deployment
|
|
444
474
|
|
|
445
|
-
For
|
|
475
|
+
For production deploys, run the normal Rails asset task:
|
|
446
476
|
|
|
447
|
-
|
|
477
|
+
```sh
|
|
478
|
+
bin/rails assets:precompile
|
|
479
|
+
```
|
|
448
480
|
|
|
449
|
-
The
|
|
481
|
+
The `react_email_rails:build` task is hooked into `assets:precompile` automatically. It loads your Vite config to find `reactEmailRails()` and its options, then writes `tmp/react-email-rails/emails.js` with the isolated React Email pipeline.
|
|
450
482
|
|
|
451
|
-
|
|
483
|
+
You can run it directly when needed:
|
|
452
484
|
|
|
453
|
-
|
|
485
|
+
```sh
|
|
486
|
+
bin/rails react_email_rails:build
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
Production rendering runs that bundle with Node. Set `SKIP_REACT_EMAIL_RAILS_BUILD=1` to skip the automatic asset hook. Directly running `bin/rails react_email_rails:build` always attempts the build.
|
|
490
|
+
|
|
491
|
+
The npm package, Vite, React, and `@react-email/render` must be available when Rails runs `assets:precompile`. This is the same stage where Rails apps normally install JavaScript dependencies and build frontend assets.
|
|
454
492
|
|
|
455
|
-
|
|
493
|
+
The bundle is required, not an optimization. If it's missing, renders raise `ReactEmailRails::RenderError` and no mail is sent.
|
|
456
494
|
|
|
457
|
-
|
|
495
|
+
The Ruby gem and npm package must stay on the same version. The renderer includes a small protocol/version handshake, so mismatched installs fail with an actionable `ReactEmailRails::RenderError` instead of silently returning malformed output.
|
|
458
496
|
|
|
459
|
-
|
|
460
|
-
- If you've defined other Vite environments, such as a custom `ssr` build, they build in the same pass too.
|
|
461
|
-
- If your Vite config defines a custom `builder.buildApp`, make sure it builds `builder.environments.email` alongside your other environments. Custom builders replace Vite's default whole-app build orchestration.
|
|
497
|
+
The build command preserves `emails.path`, `emails.extension`, `emails.ignore`, `standalone`, and email-only `vite` options.
|
|
462
498
|
|
|
463
499
|
### Runtime Dependencies
|
|
464
500
|
|
|
@@ -470,8 +506,8 @@ Boot verification is disabled by default. If you want the app to check the rende
|
|
|
470
506
|
|
|
471
507
|
```ruby
|
|
472
508
|
ReactEmailRails.configure do |config|
|
|
473
|
-
config.verify_render_on_boot = -> { Rails.env.production? && Sidekiq.server? }
|
|
474
509
|
config.render_mode = :persistent if Rails.env.production? && Sidekiq.server?
|
|
510
|
+
config.verify_render_on_boot = -> { Rails.env.production? && Sidekiq.server? }
|
|
475
511
|
end
|
|
476
512
|
```
|
|
477
513
|
|
|
@@ -5,6 +5,8 @@ class ReactEmailRails::Railtie < Rails::Railtie
|
|
|
5
5
|
end
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
+
rake_tasks { load(File.expand_path("../tasks/react_email_rails/build.rake", __dir__)) }
|
|
9
|
+
|
|
8
10
|
config.after_initialize do
|
|
9
11
|
if ReactEmailRails.configuration.verify_render_on_boot? && !ReactEmailRails.healthy?
|
|
10
12
|
Rails.logger.error(
|
|
@@ -82,7 +82,7 @@ class ReactEmailRails::RenderModes::Subprocess
|
|
|
82
82
|
return unless command_path == "node" && bundle_path.end_with?(ReactEmailRails::Configuration::BUNDLE_PATH)
|
|
83
83
|
return if File.file?(bundle_path)
|
|
84
84
|
|
|
85
|
-
raise(render_error("email bundle not found at #{bundle_path.inspect}; run
|
|
85
|
+
raise(render_error("email bundle not found at #{bundle_path.inspect}; run react-email-rails-build before rendering React emails"))
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
def validate_response!(body)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require("fileutils")
|
|
2
|
+
|
|
3
|
+
module ReactEmailRails::Tasks
|
|
4
|
+
class << self
|
|
5
|
+
def build
|
|
6
|
+
command = build_command
|
|
7
|
+
raise("react-email-rails build command not found at #{command.inspect}; run JavaScript package install first") unless File.exist?(command)
|
|
8
|
+
|
|
9
|
+
system(command, exception: true, chdir: Rails.root.to_s)
|
|
10
|
+
raise("react-email-rails build completed, but the email bundle was not found at #{bundle_path.inspect}") unless File.file?(bundle_path)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def clobber
|
|
14
|
+
FileUtils.rm_rf(Rails.root.join(File.dirname(ReactEmailRails::Configuration::BUNDLE_PATH)))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def build_command
|
|
20
|
+
candidates = [
|
|
21
|
+
ReactEmailRails::Configuration::BUILD_BIN,
|
|
22
|
+
"#{ReactEmailRails::Configuration::BUILD_BIN}.cmd",
|
|
23
|
+
]
|
|
24
|
+
candidates.map { |path| Rails.root.join(path).to_s }.find { |path| File.exist?(path) } ||
|
|
25
|
+
Rails.root.join(ReactEmailRails::Configuration::BUILD_BIN).to_s
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def bundle_path
|
|
29
|
+
Rails.root.join(ReactEmailRails::Configuration::BUNDLE_PATH).to_s
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
data/lib/react_email_rails.rb
CHANGED
|
@@ -22,6 +22,7 @@ require_relative("react_email_rails/render_modes/persistent")
|
|
|
22
22
|
require_relative("react_email_rails/render_modes/persistent/server")
|
|
23
23
|
require_relative("react_email_rails/render_modes/persistent/command_runner")
|
|
24
24
|
require_relative("react_email_rails/configuration")
|
|
25
|
+
require_relative("react_email_rails/tasks")
|
|
25
26
|
require_relative("react_email_rails/props_resolver")
|
|
26
27
|
require_relative("react_email_rails/railtie")
|
|
27
28
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
namespace(:react_email_rails) do
|
|
2
|
+
desc("Build the React Email Rails production bundle")
|
|
3
|
+
task(build: :environment) { ReactEmailRails::Tasks.build }
|
|
4
|
+
|
|
5
|
+
desc("Remove the React Email Rails production bundle")
|
|
6
|
+
task(clobber: :environment) { ReactEmailRails::Tasks.clobber }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
unless ENV["SKIP_REACT_EMAIL_RAILS_BUILD"]
|
|
10
|
+
if Rake::Task.task_defined?("assets:precompile")
|
|
11
|
+
Rake::Task["assets:precompile"].enhance(["react_email_rails:build"])
|
|
12
|
+
else
|
|
13
|
+
desc("Compile assets")
|
|
14
|
+
Rake::Task.define_task("assets:precompile" => "react_email_rails:build")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
if Rake::Task.task_defined?("assets:clobber")
|
|
18
|
+
Rake::Task["assets:clobber"].enhance(["react_email_rails:clobber"])
|
|
19
|
+
else
|
|
20
|
+
desc("Remove compiled assets")
|
|
21
|
+
Rake::Task.define_task("assets:clobber" => "react_email_rails:clobber")
|
|
22
|
+
end
|
|
23
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: react-email-rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Supertape
|
|
@@ -163,7 +163,9 @@ files:
|
|
|
163
163
|
- lib/react_email_rails/render_modes/subprocess/command_runner.rb
|
|
164
164
|
- lib/react_email_rails/render_protocol.rb
|
|
165
165
|
- lib/react_email_rails/rendered_email.rb
|
|
166
|
+
- lib/react_email_rails/tasks.rb
|
|
166
167
|
- lib/react_email_rails/version.rb
|
|
168
|
+
- lib/tasks/react_email_rails/build.rake
|
|
167
169
|
homepage: https://github.com/heysupertape/react-email-rails
|
|
168
170
|
licenses:
|
|
169
171
|
- MIT
|