react-email-rails 0.1.0 → 0.1.2
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.
- package/bin/build.mjs +75 -0
- package/bin/config.mjs +5 -15
- package/bin/dev.mjs +30 -25
- package/bin/shared.mjs +76 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +42 -30
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -1
- package/src/index.ts +50 -30
- package/src/version.ts +1 -1
package/bin/build.mjs
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createBuilder } from "vite"
|
|
3
|
+
import { fail, isolatedViteConfig, loadReactEmailRailsConfig } from "./shared.mjs"
|
|
4
|
+
import { RENDER_PROTOCOL_VERSION, VERSION } from "../dist/version.js"
|
|
5
|
+
|
|
6
|
+
if (process.argv.includes("--health")) {
|
|
7
|
+
process.stdout.write(
|
|
8
|
+
JSON.stringify({ ok: true, protocolVersion: RENDER_PROTOCOL_VERSION, packageVersion: VERSION }),
|
|
9
|
+
)
|
|
10
|
+
process.exit(0)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const args = process.argv.slice(2)
|
|
14
|
+
const readOption = (long, short) => {
|
|
15
|
+
const prefixed = args.find((arg) => arg.startsWith(`${long}=`))
|
|
16
|
+
if (prefixed) return prefixed.slice(long.length + 1)
|
|
17
|
+
|
|
18
|
+
const longIndex = args.indexOf(long)
|
|
19
|
+
if (longIndex !== -1) return args[longIndex + 1]
|
|
20
|
+
|
|
21
|
+
if (!short) return undefined
|
|
22
|
+
const shortIndex = args.indexOf(short)
|
|
23
|
+
return shortIndex === -1 ? undefined : args[shortIndex + 1]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const root = args.find((arg, index) => {
|
|
27
|
+
if (arg.startsWith("-")) return false
|
|
28
|
+
const previous = args[index - 1]
|
|
29
|
+
return (
|
|
30
|
+
previous !== "--mode" &&
|
|
31
|
+
previous !== "-m" &&
|
|
32
|
+
previous !== "--config" &&
|
|
33
|
+
previous !== "-c" &&
|
|
34
|
+
previous !== "--configLoader" &&
|
|
35
|
+
previous !== "--logLevel" &&
|
|
36
|
+
previous !== "-l"
|
|
37
|
+
)
|
|
38
|
+
})
|
|
39
|
+
const mode = readOption("--mode", "-m") ?? "production"
|
|
40
|
+
const configFile = readOption("--config", "-c")
|
|
41
|
+
const configLoader = readOption("--configLoader")
|
|
42
|
+
const logLevel = readOption("--logLevel", "-l")
|
|
43
|
+
|
|
44
|
+
process.env.NODE_ENV ??= "production"
|
|
45
|
+
|
|
46
|
+
const { userConfig, plugin, vite } = await loadReactEmailRailsConfig({
|
|
47
|
+
command: "build",
|
|
48
|
+
mode,
|
|
49
|
+
root,
|
|
50
|
+
configFile,
|
|
51
|
+
logLevel,
|
|
52
|
+
configLoader,
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
// Build production emails with the same isolation principle as the dev renderer:
|
|
56
|
+
// keep component resolution and transforms, but leave unrelated app plugins out
|
|
57
|
+
// of the email environment so client/global plugin hooks cannot break SSR output.
|
|
58
|
+
const builder = await createBuilder(
|
|
59
|
+
isolatedViteConfig(userConfig, vite, {
|
|
60
|
+
root: root ?? userConfig.root,
|
|
61
|
+
configFile: false,
|
|
62
|
+
mode,
|
|
63
|
+
builder: {},
|
|
64
|
+
plugins: [plugin],
|
|
65
|
+
appType: "custom",
|
|
66
|
+
clearScreen: false,
|
|
67
|
+
logLevel,
|
|
68
|
+
}),
|
|
69
|
+
null,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
const environment = builder.environments.email
|
|
73
|
+
if (!environment) fail("react-email-rails: email build environment not found")
|
|
74
|
+
|
|
75
|
+
await builder.build(environment)
|
package/bin/config.mjs
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { loadReactEmailRailsConfig } from "./shared.mjs"
|
|
3
3
|
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (!plugin) {
|
|
10
|
-
process.stderr.write("react-email-rails: reactEmailRails() plugin not found in the Vite config\n")
|
|
11
|
-
process.exit(1)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (!metadata) {
|
|
15
|
-
process.stderr.write("react-email-rails: reactEmailRails() plugin metadata not found\n")
|
|
16
|
-
process.exit(1)
|
|
17
|
-
}
|
|
4
|
+
const { metadata } = await loadReactEmailRailsConfig({
|
|
5
|
+
command: "serve",
|
|
6
|
+
mode: process.env.NODE_ENV ?? "development",
|
|
7
|
+
})
|
|
18
8
|
|
|
19
9
|
process.stdout.write(JSON.stringify(metadata))
|
package/bin/dev.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createServer, isRunnableDevEnvironment
|
|
2
|
+
import { createServer, isRunnableDevEnvironment } from "vite"
|
|
3
|
+
import { fail, isolatedViteConfig, loadReactEmailRailsConfig } from "./shared.mjs"
|
|
3
4
|
import { RENDER_PROTOCOL_VERSION, VERSION } from "../dist/version.js"
|
|
4
5
|
|
|
5
6
|
if (process.argv.includes("--health")) {
|
|
@@ -18,45 +19,49 @@ const logger = {
|
|
|
18
19
|
hasWarned: false,
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
process.exit(1)
|
|
22
|
+
const divertStdout = () => {
|
|
23
|
+
const write = process.stdout.write.bind(process.stdout)
|
|
24
|
+
process.stdout.write = (chunk, encoding, callback) => {
|
|
25
|
+
if (typeof encoding === "function") return process.stderr.write(chunk, encoding)
|
|
26
|
+
return process.stderr.write(chunk, encoding, callback)
|
|
27
|
+
}
|
|
28
|
+
return () => {
|
|
29
|
+
process.stdout.write = write
|
|
30
|
+
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
// Load only this plugin and aliases; host dev-server plugins have global side effects.
|
|
34
|
+
const restoreStdout = divertStdout()
|
|
35
|
+
const { userConfig, plugin, vite } = await loadReactEmailRailsConfig({
|
|
36
|
+
command: "serve",
|
|
37
|
+
mode: "development",
|
|
38
|
+
})
|
|
39
|
+
|
|
33
40
|
// Forward config that affects how components resolve and compile (but not the
|
|
34
41
|
// host's dev-server plugins, which have global side effects), so dev rendering
|
|
35
42
|
// stays close to the production email bundle.
|
|
36
|
-
const server = await createServer(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
customLogger: logger,
|
|
47
|
-
})
|
|
43
|
+
const server = await createServer(
|
|
44
|
+
isolatedViteConfig(userConfig, vite, {
|
|
45
|
+
configFile: false,
|
|
46
|
+
plugins: [plugin],
|
|
47
|
+
server: { middlewareMode: true },
|
|
48
|
+
appType: "custom",
|
|
49
|
+
clearScreen: false,
|
|
50
|
+
customLogger: logger,
|
|
51
|
+
}),
|
|
52
|
+
)
|
|
48
53
|
|
|
49
54
|
// Render through the same `email` environment the production build uses, so dev
|
|
50
55
|
// and build resolve and compile components identically.
|
|
51
56
|
const environment = server.environments.email
|
|
52
57
|
if (!isRunnableDevEnvironment(environment)) {
|
|
53
58
|
await server.close()
|
|
54
|
-
|
|
55
|
-
process.exit(1)
|
|
59
|
+
fail("react-email-rails: the email environment is not runnable")
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
try {
|
|
59
63
|
const { run } = await environment.runner.import("virtual:react-email-rails/server")
|
|
64
|
+
restoreStdout()
|
|
60
65
|
await run()
|
|
61
66
|
} finally {
|
|
62
67
|
await server.close()
|
package/bin/shared.mjs
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { loadConfigFromFile, mergeConfig } from "vite"
|
|
2
|
+
|
|
3
|
+
const CONFIG_SYMBOL = Symbol.for("react-email-rails.config")
|
|
4
|
+
const VITE_CONFIG_SYMBOL = Symbol.for("react-email-rails.vite")
|
|
5
|
+
const EMAIL_VITE_CONFIG_KEYS = [
|
|
6
|
+
"assetsInclude",
|
|
7
|
+
"css",
|
|
8
|
+
"define",
|
|
9
|
+
"esbuild",
|
|
10
|
+
"json",
|
|
11
|
+
"oxc",
|
|
12
|
+
"plugins",
|
|
13
|
+
"resolve",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
export async function loadReactEmailRailsConfig({
|
|
17
|
+
command,
|
|
18
|
+
mode,
|
|
19
|
+
root,
|
|
20
|
+
configFile,
|
|
21
|
+
logLevel,
|
|
22
|
+
configLoader,
|
|
23
|
+
}) {
|
|
24
|
+
const loaded = await loadConfigFromFile(
|
|
25
|
+
{ command, mode },
|
|
26
|
+
configFile,
|
|
27
|
+
root,
|
|
28
|
+
logLevel,
|
|
29
|
+
undefined,
|
|
30
|
+
configLoader,
|
|
31
|
+
)
|
|
32
|
+
const userConfig = loaded?.config ?? {}
|
|
33
|
+
const plugin = (userConfig.plugins ?? [])
|
|
34
|
+
.flat(Infinity)
|
|
35
|
+
.find((plugin) => plugin?.name === "react-email-rails")
|
|
36
|
+
const metadata = plugin?.[CONFIG_SYMBOL]
|
|
37
|
+
|
|
38
|
+
if (!plugin) fail("react-email-rails: reactEmailRails() plugin not found in the Vite config")
|
|
39
|
+
if (!metadata) fail("react-email-rails: reactEmailRails() plugin metadata not found")
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
userConfig,
|
|
43
|
+
plugin,
|
|
44
|
+
metadata,
|
|
45
|
+
vite: plugin[VITE_CONFIG_SYMBOL] ?? {},
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function isolatedViteConfig(userConfig, emailViteConfig, baseConfig) {
|
|
50
|
+
const userEsbuild =
|
|
51
|
+
userConfig.esbuild && typeof userConfig.esbuild === "object" ? userConfig.esbuild : {}
|
|
52
|
+
const forwarded = {
|
|
53
|
+
assetsInclude: userConfig.assetsInclude,
|
|
54
|
+
resolve: userConfig.resolve,
|
|
55
|
+
define: userConfig.define,
|
|
56
|
+
css: userConfig.css,
|
|
57
|
+
json: userConfig.json,
|
|
58
|
+
oxc: userConfig.oxc,
|
|
59
|
+
esbuild: { ...userEsbuild, jsx: userEsbuild.jsx ?? "automatic" },
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return mergeConfig({ ...forwarded, ...baseConfig }, pickEmailViteConfig(emailViteConfig))
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function pickEmailViteConfig(config) {
|
|
66
|
+
return Object.fromEntries(
|
|
67
|
+
EMAIL_VITE_CONFIG_KEYS.flatMap((key) =>
|
|
68
|
+
config && Object.hasOwn(config, key) ? [[key, config[key]]] : [],
|
|
69
|
+
),
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function fail(message) {
|
|
74
|
+
process.stderr.write(`${message}\n`)
|
|
75
|
+
process.exit(1)
|
|
76
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Plugin } from "vite";
|
|
1
|
+
import type { Plugin, UserConfig } from "vite";
|
|
2
2
|
export type EmailsOption = string | {
|
|
3
3
|
path?: string;
|
|
4
4
|
extension?: string | string[];
|
|
@@ -7,6 +7,10 @@ export type EmailsOption = string | {
|
|
|
7
7
|
export type ReactEmailRailsOptions = {
|
|
8
8
|
emails?: EmailsOption;
|
|
9
9
|
standalone?: boolean;
|
|
10
|
+
vite?: ReactEmailRailsViteOptions;
|
|
11
|
+
};
|
|
12
|
+
export type ReactEmailRailsViteOptions = Pick<UserConfig, "assetsInclude" | "css" | "define" | "esbuild" | "json" | "plugins" | "resolve"> & {
|
|
13
|
+
oxc?: unknown;
|
|
10
14
|
};
|
|
11
15
|
export declare const EMAIL_ENVIRONMENT = "email";
|
|
12
16
|
export declare function reactEmailRails(options?: ReactEmailRailsOptions): Plugin;
|
package/dist/index.js
CHANGED
|
@@ -4,9 +4,11 @@ const VIRTUAL_SERVER = "virtual:react-email-rails/server";
|
|
|
4
4
|
const VIRTUAL_MAIN = "virtual:react-email-rails/main";
|
|
5
5
|
const RESOLVED_SERVER = `\0${VIRTUAL_SERVER}`;
|
|
6
6
|
const RESOLVED_MAIN = `\0${VIRTUAL_MAIN}`;
|
|
7
|
+
const VIRTUAL_MODULE_PATTERN = /virtual:react-email-rails\/(?:server|main)$/;
|
|
7
8
|
// The dedicated build environment that emits the server-side email bundle.
|
|
8
9
|
export const EMAIL_ENVIRONMENT = "email";
|
|
9
10
|
const CONFIG_SYMBOL = Symbol.for("react-email-rails.config");
|
|
11
|
+
const VITE_CONFIG_SYMBOL = Symbol.for("react-email-rails.vite");
|
|
10
12
|
const OUT_DIR = "tmp/react-email-rails";
|
|
11
13
|
const BUNDLE_FILE = "emails.js";
|
|
12
14
|
export function reactEmailRails(options = {}) {
|
|
@@ -34,41 +36,48 @@ export function reactEmailRails(options = {}) {
|
|
|
34
36
|
const globArg = JSON.stringify(globPatterns.length === 1 ? globPatterns[0] : globPatterns);
|
|
35
37
|
const plugin = {
|
|
36
38
|
name: "react-email-rails",
|
|
37
|
-
resolveId
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
resolveId: {
|
|
40
|
+
filter: { id: VIRTUAL_MODULE_PATTERN },
|
|
41
|
+
handler(id) {
|
|
42
|
+
if (id === VIRTUAL_SERVER)
|
|
43
|
+
return RESOLVED_SERVER;
|
|
44
|
+
if (id === VIRTUAL_MAIN)
|
|
45
|
+
return RESOLVED_MAIN;
|
|
46
|
+
},
|
|
42
47
|
},
|
|
43
|
-
load
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
48
|
+
load: {
|
|
49
|
+
filter: { id: VIRTUAL_MODULE_PATTERN },
|
|
50
|
+
handler(id) {
|
|
51
|
+
if (id === RESOLVED_SERVER) {
|
|
52
|
+
return [
|
|
53
|
+
`import { serve, toComponentName } from "react-email-rails/runtime"`,
|
|
54
|
+
`const modules = import.meta.glob(${globArg})`,
|
|
55
|
+
`const extensions = ${JSON.stringify(extensions)}`,
|
|
56
|
+
`const registry = Object.create(null)`,
|
|
57
|
+
`for (const path in modules) {`,
|
|
58
|
+
` const extension = extensions.find((extension) => path.endsWith(extension)) ?? path.slice(path.lastIndexOf("."))`,
|
|
59
|
+
` registry[toComponentName(path, ${JSON.stringify(root)}, extension)] = modules[path]`,
|
|
60
|
+
`}`,
|
|
61
|
+
`export const run = () => serve(registry)`,
|
|
62
|
+
].join("\n");
|
|
63
|
+
}
|
|
64
|
+
if (id === RESOLVED_MAIN) {
|
|
65
|
+
return `import { run } from ${JSON.stringify(VIRTUAL_SERVER)}\nrun()\n`;
|
|
66
|
+
}
|
|
67
|
+
},
|
|
60
68
|
},
|
|
61
|
-
config() {
|
|
62
|
-
// Register a dedicated `email` build environment
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
// The environment is a server consumer.
|
|
66
|
-
// dependencies by default so Rails runtime images do not need
|
|
69
|
+
config(_config, env) {
|
|
70
|
+
// Register a dedicated `email` build environment. The official
|
|
71
|
+
// react-email-rails-build bin opts into building it with an isolated
|
|
72
|
+
// plugin stack so host app plugins cannot break email SSR builds.
|
|
73
|
+
// The environment is a server consumer. Production standalone builds inline
|
|
74
|
+
// Node dependencies by default so Rails runtime images do not need
|
|
75
|
+
// node_modules; dev rendering keeps dependencies external for Vite's module
|
|
76
|
+
// runner.
|
|
67
77
|
return {
|
|
68
|
-
builder: {},
|
|
69
78
|
environments: {
|
|
70
79
|
[EMAIL_ENVIRONMENT]: {
|
|
71
|
-
...(standalone ? { resolve: { noExternal: true } } : {}),
|
|
80
|
+
...(standalone && env.command === "build" ? { resolve: { noExternal: true } } : {}),
|
|
72
81
|
build: {
|
|
73
82
|
ssr: true,
|
|
74
83
|
outDir: OUT_DIR,
|
|
@@ -98,6 +107,9 @@ export function reactEmailRails(options = {}) {
|
|
|
98
107
|
...metadata,
|
|
99
108
|
},
|
|
100
109
|
});
|
|
110
|
+
Object.defineProperty(plugin, VITE_CONFIG_SYMBOL, {
|
|
111
|
+
value: options.vite ?? {},
|
|
112
|
+
});
|
|
101
113
|
return plugin;
|
|
102
114
|
}
|
|
103
115
|
export { RENDER_PROTOCOL_VERSION, VERSION } from "./version.js";
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.1.
|
|
1
|
+
export declare const VERSION = "0.1.2";
|
|
2
2
|
export declare const RENDER_PROTOCOL_VERSION = 1;
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = "0.1.
|
|
1
|
+
export const VERSION = "0.1.2";
|
|
2
2
|
export const RENDER_PROTOCOL_VERSION = 1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-email-rails",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Build and send emails using React and Rails",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"types": "./dist/index.d.ts",
|
|
39
39
|
"bin": {
|
|
40
|
+
"react-email-rails-build": "./bin/build.mjs",
|
|
40
41
|
"react-email-rails-config": "./bin/config.mjs",
|
|
41
42
|
"react-email-rails-dev": "./bin/dev.mjs"
|
|
42
43
|
},
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Plugin } from "vite"
|
|
1
|
+
import type { ConfigEnv, Plugin, UserConfig } from "vite"
|
|
2
2
|
|
|
3
3
|
export type EmailsOption =
|
|
4
4
|
| string
|
|
@@ -11,6 +11,14 @@ export type EmailsOption =
|
|
|
11
11
|
export type ReactEmailRailsOptions = {
|
|
12
12
|
emails?: EmailsOption
|
|
13
13
|
standalone?: boolean
|
|
14
|
+
vite?: ReactEmailRailsViteOptions
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type ReactEmailRailsViteOptions = Pick<
|
|
18
|
+
UserConfig,
|
|
19
|
+
"assetsInclude" | "css" | "define" | "esbuild" | "json" | "plugins" | "resolve"
|
|
20
|
+
> & {
|
|
21
|
+
oxc?: unknown
|
|
14
22
|
}
|
|
15
23
|
|
|
16
24
|
type PluginMetadata = {
|
|
@@ -31,10 +39,12 @@ const VIRTUAL_SERVER = "virtual:react-email-rails/server"
|
|
|
31
39
|
const VIRTUAL_MAIN = "virtual:react-email-rails/main"
|
|
32
40
|
const RESOLVED_SERVER = `\0${VIRTUAL_SERVER}`
|
|
33
41
|
const RESOLVED_MAIN = `\0${VIRTUAL_MAIN}`
|
|
42
|
+
const VIRTUAL_MODULE_PATTERN = /virtual:react-email-rails\/(?:server|main)$/
|
|
34
43
|
|
|
35
44
|
// The dedicated build environment that emits the server-side email bundle.
|
|
36
45
|
export const EMAIL_ENVIRONMENT = "email"
|
|
37
46
|
const CONFIG_SYMBOL = Symbol.for("react-email-rails.config")
|
|
47
|
+
const VITE_CONFIG_SYMBOL = Symbol.for("react-email-rails.vite")
|
|
38
48
|
const OUT_DIR = "tmp/react-email-rails"
|
|
39
49
|
const BUNDLE_FILE = "emails.js"
|
|
40
50
|
|
|
@@ -72,42 +82,49 @@ export function reactEmailRails(options: ReactEmailRailsOptions = {}): Plugin {
|
|
|
72
82
|
const plugin: Plugin = {
|
|
73
83
|
name: "react-email-rails",
|
|
74
84
|
|
|
75
|
-
resolveId
|
|
76
|
-
|
|
77
|
-
|
|
85
|
+
resolveId: {
|
|
86
|
+
filter: { id: VIRTUAL_MODULE_PATTERN },
|
|
87
|
+
handler(id) {
|
|
88
|
+
if (id === VIRTUAL_SERVER) return RESOLVED_SERVER
|
|
89
|
+
if (id === VIRTUAL_MAIN) return RESOLVED_MAIN
|
|
90
|
+
},
|
|
78
91
|
},
|
|
79
92
|
|
|
80
|
-
load
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
load: {
|
|
94
|
+
filter: { id: VIRTUAL_MODULE_PATTERN },
|
|
95
|
+
handler(id) {
|
|
96
|
+
if (id === RESOLVED_SERVER) {
|
|
97
|
+
return [
|
|
98
|
+
`import { serve, toComponentName } from "react-email-rails/runtime"`,
|
|
99
|
+
`const modules = import.meta.glob(${globArg})`,
|
|
100
|
+
`const extensions = ${JSON.stringify(extensions)}`,
|
|
101
|
+
`const registry = Object.create(null)`,
|
|
102
|
+
`for (const path in modules) {`,
|
|
103
|
+
` const extension = extensions.find((extension) => path.endsWith(extension)) ?? path.slice(path.lastIndexOf("."))`,
|
|
104
|
+
` registry[toComponentName(path, ${JSON.stringify(root)}, extension)] = modules[path]`,
|
|
105
|
+
`}`,
|
|
106
|
+
`export const run = () => serve(registry)`,
|
|
107
|
+
].join("\n")
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (id === RESOLVED_MAIN) {
|
|
111
|
+
return `import { run } from ${JSON.stringify(VIRTUAL_SERVER)}\nrun()\n`
|
|
112
|
+
}
|
|
113
|
+
},
|
|
98
114
|
},
|
|
99
115
|
|
|
100
|
-
config() {
|
|
101
|
-
// Register a dedicated `email` build environment
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
// The environment is a server consumer.
|
|
105
|
-
// dependencies by default so Rails runtime images do not need
|
|
116
|
+
config(_config, env: ConfigEnv) {
|
|
117
|
+
// Register a dedicated `email` build environment. The official
|
|
118
|
+
// react-email-rails-build bin opts into building it with an isolated
|
|
119
|
+
// plugin stack so host app plugins cannot break email SSR builds.
|
|
120
|
+
// The environment is a server consumer. Production standalone builds inline
|
|
121
|
+
// Node dependencies by default so Rails runtime images do not need
|
|
122
|
+
// node_modules; dev rendering keeps dependencies external for Vite's module
|
|
123
|
+
// runner.
|
|
106
124
|
return {
|
|
107
|
-
builder: {},
|
|
108
125
|
environments: {
|
|
109
126
|
[EMAIL_ENVIRONMENT]: {
|
|
110
|
-
...(standalone ? { resolve: { noExternal: true } } : {}),
|
|
127
|
+
...(standalone && env.command === "build" ? { resolve: { noExternal: true } } : {}),
|
|
111
128
|
build: {
|
|
112
129
|
ssr: true,
|
|
113
130
|
outDir: OUT_DIR,
|
|
@@ -139,6 +156,9 @@ export function reactEmailRails(options: ReactEmailRailsOptions = {}): Plugin {
|
|
|
139
156
|
...metadata,
|
|
140
157
|
},
|
|
141
158
|
})
|
|
159
|
+
Object.defineProperty(plugin, VITE_CONFIG_SYMBOL, {
|
|
160
|
+
value: options.vite ?? {},
|
|
161
|
+
})
|
|
142
162
|
|
|
143
163
|
return plugin
|
|
144
164
|
}
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = "0.1.
|
|
1
|
+
export const VERSION = "0.1.2"
|
|
2
2
|
export const RENDER_PROTOCOL_VERSION = 1
|