rails-vite-plugin 0.1.0-beta.1 → 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.
- package/dev-server-index.html +185 -5
- package/dist/index.d.ts +4 -2
- package/dist/index.js +20 -23
- package/package.json +1 -1
package/dev-server-index.html
CHANGED
|
@@ -1,6 +1,186 @@
|
|
|
1
|
-
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Rails Vite</title>
|
|
7
|
+
<style>
|
|
8
|
+
*,
|
|
9
|
+
*::before,
|
|
10
|
+
*::after {
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
margin: 0;
|
|
13
|
+
padding: 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
html {
|
|
17
|
+
-webkit-font-smoothing: antialiased;
|
|
18
|
+
-moz-osx-font-smoothing: grayscale;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
body {
|
|
22
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
|
23
|
+
Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
|
24
|
+
min-height: 100vh;
|
|
25
|
+
display: flex;
|
|
26
|
+
align-items: center;
|
|
27
|
+
justify-content: center;
|
|
28
|
+
background-color: #f8f9fa;
|
|
29
|
+
color: #374151;
|
|
30
|
+
line-height: 1.6;
|
|
31
|
+
padding: 1.5rem;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@media (prefers-color-scheme: dark) {
|
|
35
|
+
body {
|
|
36
|
+
background-color: #111827;
|
|
37
|
+
color: #9ca3af;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.card {
|
|
42
|
+
background: #fff;
|
|
43
|
+
border-radius: 12px;
|
|
44
|
+
box-shadow:
|
|
45
|
+
0 1px 3px rgba(0, 0, 0, 0.06),
|
|
46
|
+
0 20px 40px rgba(0, 0, 0, 0.07);
|
|
47
|
+
max-width: 520px;
|
|
48
|
+
width: 100%;
|
|
49
|
+
padding: 2.5rem 2rem;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@media (prefers-color-scheme: dark) {
|
|
53
|
+
.card {
|
|
54
|
+
background: #1f2937;
|
|
55
|
+
box-shadow:
|
|
56
|
+
0 1px 3px rgba(0, 0, 0, 0.2),
|
|
57
|
+
0 20px 40px rgba(0, 0, 0, 0.3);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.logos {
|
|
62
|
+
display: flex;
|
|
63
|
+
align-items: center;
|
|
64
|
+
justify-content: center;
|
|
65
|
+
gap: 1.25rem;
|
|
66
|
+
margin-bottom: 2rem;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.logos svg {
|
|
70
|
+
flex-shrink: 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.plus {
|
|
74
|
+
color: #9ca3af;
|
|
75
|
+
font-size: 1.25rem;
|
|
76
|
+
font-weight: 300;
|
|
77
|
+
user-select: none;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.content p {
|
|
81
|
+
margin-bottom: 1rem;
|
|
82
|
+
font-size: 0.9375rem;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.content p:last-child {
|
|
86
|
+
margin-bottom: 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.divider {
|
|
90
|
+
border: none;
|
|
91
|
+
border-top: 1px solid #e5e7eb;
|
|
92
|
+
margin: 1.5rem 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@media (prefers-color-scheme: dark) {
|
|
96
|
+
.divider {
|
|
97
|
+
border-top-color: #374151;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.hint {
|
|
102
|
+
font-size: 0.8125rem;
|
|
103
|
+
color: #6b7280;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@media (prefers-color-scheme: dark) {
|
|
107
|
+
.hint {
|
|
108
|
+
color: #6b7280;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
code {
|
|
113
|
+
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
|
|
114
|
+
"Liberation Mono", monospace;
|
|
115
|
+
font-size: 0.8125rem;
|
|
116
|
+
background: #f3f4f6;
|
|
117
|
+
color: #1f2937;
|
|
118
|
+
padding: 0.15em 0.4em;
|
|
119
|
+
border-radius: 4px;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@media (prefers-color-scheme: dark) {
|
|
123
|
+
code {
|
|
124
|
+
background: #374151;
|
|
125
|
+
color: #e5e7eb;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
a {
|
|
130
|
+
color: #cc342d;
|
|
131
|
+
text-decoration: none;
|
|
132
|
+
font-weight: 600;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
a:hover {
|
|
136
|
+
color: #a02a24;
|
|
137
|
+
text-decoration: underline;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@media (prefers-color-scheme: dark) {
|
|
141
|
+
a {
|
|
142
|
+
color: #ef4444;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
a:hover {
|
|
146
|
+
color: #f87171;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
</style>
|
|
150
|
+
</head>
|
|
151
|
+
<body>
|
|
152
|
+
<div class="card">
|
|
153
|
+
<div class="logos">
|
|
154
|
+
<a href="https://rubyonrails.org" aria-label="Ruby on Rails">
|
|
155
|
+
<svg width="42" height="42" fill="#D30001" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Ruby on Rails</title><path d="M.741 19.365h8.36s-1.598-7.291 3.693-10.243l.134-.066c1.286-.637 4.907-2.431 10.702 1.854.19-.159.37-.286.37-.286s-5.503-5.492-11.63-4.878c-3.079.275-6.867 3.079-9.09 6.783C1.058 16.233.741 19.365.741 19.365Zm8.804-.783a10.682 10.682 0 0 1-.127-1.333l1.143.412c.063.498.159.963.254 1.376l-1.27-.455Zm-7.799-4.317L.529 13.82c-.201.455-.423.984-.529 1.27l1.217.444c.137-.359.36-.878.529-1.269Zm7.831.296.857.677c.042-.413.116-.825.222-1.238l-.762-.603c-.137.391-.233.783-.317 1.164Zm2.042-2.646-.508-.762c.191-.243.413-.486.656-.709l.476.72a5.958 5.958 0 0 0-.624.751ZM4.19 8.878l.752.656c-.254.265-.498.551-.72.836l-.815-.698c.244-.265.508-.529.783-.794Zm9.799 1.027-.243-.73c.265-.117.571-.233.931-.339l.233.698a6.82 6.82 0 0 0-.921.371Zm3.122-.656.042-.667c.339.021.688.064 1.048.138l-.042.656a5.859 5.859 0 0 0-1.048-.127ZM8.942 6.392l-.476-.731c-.265.138-.54.286-.826.455l.487.741c.275-.169.54-.328.815-.465Zm9.217-.053.042-.709c-.095-.053-.36-.18-1.026-.371l-.043.699c.349.116.688.243 1.027.381ZM13.238 5.28h.106l-.212-.645c-.328 0-.666.021-1.016.063l.201.625a8.87 8.87 0 0 1 .921-.043Z"/></svg>
|
|
156
|
+
</a>
|
|
157
|
+
<span class="plus">+</span>
|
|
158
|
+
<a href="https://vite.dev" aria-label="Vite">
|
|
159
|
+
<svg width="38" height="38" viewBox="0 0 410 404" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
160
|
+
<path d="M399.641 59.525 215.643 388.545c-3.816 6.826-13.638 6.994-17.69.304L7.876 59.221c-4.456-7.348 2.596-15.985 10.707-13.608l187.033 54.783c1.318.386 2.706.395 4.028.025L393.244 45.9c8.124-2.32 15.053 6.396 10.397 13.625Z" fill="url(#vite-a)"/>
|
|
161
|
+
<path d="M293.573 1.34 163.46 28.672c-2.2.462-3.834 2.347-3.967 4.577l-8.624 144.716c-.178 2.991 2.798 5.224 5.667 4.254l25.488-8.625c3.14-1.063 6.209 1.589 5.67 4.9l-7.828 48.08c-.555 3.412 2.72 6.085 5.882 4.8l19.6-7.952c3.16-1.282 6.433 1.39 5.878 4.8l-12.44 76.427c-.857 5.265 5.727 8.142 8.808 3.85l2.06-2.867L341.3 103.14c1.665-3.2-1.17-6.855-4.633-5.975l-26.357 6.698c-3.28.834-6.227-2.18-5.286-5.406L331.34 7.21c.95-3.25-2.065-6.296-5.3-5.358l-32.467 8.488Z" fill="url(#vite-b)"/>
|
|
162
|
+
<defs>
|
|
163
|
+
<linearGradient id="vite-a" x1="6.715" y1="32.086" x2="235.479" y2="344.885" gradientUnits="userSpaceOnUse">
|
|
164
|
+
<stop stop-color="#41D1FF"/>
|
|
165
|
+
<stop offset="1" stop-color="#BD34FE"/>
|
|
166
|
+
</linearGradient>
|
|
167
|
+
<linearGradient id="vite-b" x1="194.651" y1="8.818" x2="236.076" y2="292.989" gradientUnits="userSpaceOnUse">
|
|
168
|
+
<stop stop-color="#FFBD4F"/>
|
|
169
|
+
<stop offset="1" stop-color="#FF9640"/>
|
|
170
|
+
</linearGradient>
|
|
171
|
+
</defs>
|
|
172
|
+
</svg>
|
|
173
|
+
</a>
|
|
174
|
+
</div>
|
|
175
|
+
<div class="content">
|
|
176
|
+
<p>This is the <strong>Vite development server</strong> providing Hot Module Replacement for your Rails application.</p>
|
|
177
|
+
<p>Your Rails app is running on a different port. Start it with:</p>
|
|
178
|
+
<p><code>bin/dev</code></p>
|
|
179
|
+
<hr class="divider">
|
|
180
|
+
<p class="hint">
|
|
181
|
+
Need help? Read the <a href="https://github.com/skryukov/rails_vite#readme">docs →</a>
|
|
182
|
+
</p>
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
</body>
|
|
6
186
|
</html>
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
|
+
export type InputOption = string | string[] | Record<string, string>;
|
|
2
3
|
export interface RailsViteOptions {
|
|
3
|
-
input?:
|
|
4
|
+
input?: InputOption;
|
|
4
5
|
sourceDir?: string;
|
|
5
|
-
ssr?:
|
|
6
|
+
ssr?: InputOption;
|
|
6
7
|
ssrOutputDirectory?: string;
|
|
7
8
|
devMetaFile?: string;
|
|
8
9
|
buildDirectory?: string;
|
|
9
10
|
publicDirectory?: string;
|
|
10
11
|
refresh?: boolean | string | string[];
|
|
11
12
|
}
|
|
13
|
+
export declare const refreshPaths: string[];
|
|
12
14
|
export default function rails(options?: RailsViteOptions): Plugin;
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import path from 'path';
|
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import picomatch from 'picomatch';
|
|
5
5
|
import { loadEnv, defaultAllowedOrigins, } from 'vite';
|
|
6
|
-
const
|
|
6
|
+
export const refreshPaths = [
|
|
7
7
|
'app/views/**/*.{erb,slim,haml}',
|
|
8
8
|
'app/helpers/**/*.rb',
|
|
9
9
|
];
|
|
@@ -16,9 +16,8 @@ export default function rails(options = {}) {
|
|
|
16
16
|
const devMetaPath = options.devMetaFile ?? path.join('tmp', 'rails-vite.json');
|
|
17
17
|
const ssrOutputDirectory = options.ssrOutputDirectory ?? 'ssr';
|
|
18
18
|
const resolvedInput = resolveInput(input, sourceDir);
|
|
19
|
-
const resolvedSsr = options.ssr ? resolveInput(options.ssr, sourceDir) : undefined;
|
|
19
|
+
const resolvedSsr = options.ssr !== undefined ? resolveInput(options.ssr, sourceDir) : undefined;
|
|
20
20
|
let resolvedConfig;
|
|
21
|
-
let devServerUrl;
|
|
22
21
|
let reactRefresh = false;
|
|
23
22
|
return {
|
|
24
23
|
name: 'rails-vite',
|
|
@@ -74,7 +73,7 @@ export default function rails(options = {}) {
|
|
|
74
73
|
server.httpServer?.once('listening', () => {
|
|
75
74
|
const address = server.httpServer?.address();
|
|
76
75
|
if (isAddressInfo(address)) {
|
|
77
|
-
devServerUrl = resolveDevServerUrl(address, resolvedConfig);
|
|
76
|
+
const devServerUrl = resolveDevServerUrl(address, resolvedConfig);
|
|
78
77
|
resolvedConfig.server.origin = devServerUrl;
|
|
79
78
|
const meta = { url: devServerUrl, sourceDir };
|
|
80
79
|
if (reactRefresh)
|
|
@@ -96,10 +95,10 @@ export default function rails(options = {}) {
|
|
|
96
95
|
exitHandlersBound = true;
|
|
97
96
|
}
|
|
98
97
|
// Watch view templates for full-page reload
|
|
99
|
-
const
|
|
100
|
-
if (
|
|
101
|
-
const match = picomatch(
|
|
102
|
-
server.watcher.add(
|
|
98
|
+
const resolvedRefreshPaths = resolveRefreshPaths(options.refresh);
|
|
99
|
+
if (resolvedRefreshPaths.length) {
|
|
100
|
+
const match = picomatch(resolvedRefreshPaths);
|
|
101
|
+
server.watcher.add(resolvedRefreshPaths);
|
|
103
102
|
server.watcher.on('change', (filePath) => {
|
|
104
103
|
const relativePath = path.relative(process.cwd(), filePath);
|
|
105
104
|
if (match(relativePath)) {
|
|
@@ -121,6 +120,9 @@ export default function rails(options = {}) {
|
|
|
121
120
|
};
|
|
122
121
|
}
|
|
123
122
|
function resolveInput(input, sourceDir) {
|
|
123
|
+
if (typeof input === 'object' && !Array.isArray(input)) {
|
|
124
|
+
return Object.fromEntries(Object.entries(input).map(([key, value]) => [key, prefixWithSourceDir(value, sourceDir)]));
|
|
125
|
+
}
|
|
124
126
|
if (Array.isArray(input)) {
|
|
125
127
|
return input.map((entry) => prefixWithSourceDir(entry, sourceDir));
|
|
126
128
|
}
|
|
@@ -143,34 +145,29 @@ function detectEntrypoint(sourceDir) {
|
|
|
143
145
|
return 'application.js';
|
|
144
146
|
}
|
|
145
147
|
function resolveRefreshPaths(refresh) {
|
|
146
|
-
if (refresh === false
|
|
147
|
-
return
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
if (typeof refresh === 'string') {
|
|
148
|
+
if (refresh === false)
|
|
149
|
+
return [];
|
|
150
|
+
if (!refresh || refresh === true)
|
|
151
|
+
return refreshPaths;
|
|
152
|
+
if (typeof refresh === 'string')
|
|
153
153
|
return [refresh];
|
|
154
|
-
}
|
|
155
154
|
return refresh;
|
|
156
155
|
}
|
|
157
156
|
function resolveDevServerUrl(address, config) {
|
|
158
|
-
const
|
|
159
|
-
const clientProtocol =
|
|
160
|
-
?
|
|
157
|
+
const hmr = typeof config.server.hmr === 'object' ? config.server.hmr : null;
|
|
158
|
+
const clientProtocol = hmr?.protocol
|
|
159
|
+
? hmr.protocol === 'wss'
|
|
161
160
|
? 'https'
|
|
162
161
|
: 'http'
|
|
163
162
|
: null;
|
|
164
163
|
const serverProtocol = config.server.https ? 'https' : 'http';
|
|
165
164
|
const protocol = clientProtocol ?? serverProtocol;
|
|
166
|
-
const configHmrHost = typeof config.server.hmr === 'object' ? config.server.hmr.host : null;
|
|
167
165
|
const configHost = typeof config.server.host === 'string' ? config.server.host : null;
|
|
168
166
|
const serverAddress = address.family === 'IPv6' || address.family === 6
|
|
169
167
|
? `[${address.address}]`
|
|
170
168
|
: address.address;
|
|
171
|
-
const host =
|
|
172
|
-
const
|
|
173
|
-
const port = configHmrClientPort ?? address.port;
|
|
169
|
+
const host = hmr?.host ?? configHost ?? serverAddress;
|
|
170
|
+
const port = hmr?.clientPort ?? address.port;
|
|
174
171
|
return `${protocol}://${host}:${port}`;
|
|
175
172
|
}
|
|
176
173
|
function isAddressInfo(x) {
|