rails-vite-plugin 0.2.1 → 0.2.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.
Files changed (2) hide show
  1. package/dist/jsbundling.js +18 -7
  2. package/package.json +1 -1
@@ -80,7 +80,7 @@ export default function jsbundling(options = {}) {
80
80
  if (chunkInfo.facadeModuleId && cssExtensions.test(chunkInfo.facadeModuleId)) {
81
81
  return `${CSS_FACADE_PREFIX}[name].js`;
82
82
  }
83
- return '[name].js';
83
+ return '_[name]-[hash].js';
84
84
  },
85
85
  chunkFileNames: '[name]-[hash].js',
86
86
  assetFileNames: '[name][extname]',
@@ -120,19 +120,30 @@ export default function jsbundling(options = {}) {
120
120
  // SSR bundles are Node.js server code — not served to browsers.
121
121
  if (resolvedConfig.build.ssr)
122
122
  return;
123
- // Copy entry files (JS + CSS) to the asset pipeline directory
124
- // so Propshaft/Sprockets can serve them via Rails helpers.
125
- // Chunks stay in outputDir and are served directly by the web server.
126
123
  fs.mkdirSync(assetPipelineDir, { recursive: true });
127
124
  const outDir = resolvedConfig.build.outDir;
128
- // Only copy CSS files that correspond to entries (entry CSS or CSS extracted
129
- // from JS entries). Shared chunk CSS stays in outputDir.
130
125
  const entryNames = new Set(entries.map(e => e.name));
131
126
  for (const [fileName, chunk] of Object.entries(bundle)) {
132
127
  const isEntryJs = chunk.type === 'chunk' && chunk.isEntry;
133
128
  const isEntryCss = chunk.type === 'asset' && cssExtensions.test(fileName)
134
129
  && entryNames.has(fileName.replace(/\.[^.]+$/, ''));
135
- if (isEntryJs || isEntryCss) {
130
+ if (isEntryJs) {
131
+ // JS entries are built as _[name]-[hash].js (content-hashed).
132
+ // Write a thin shim as [name].js for the asset pipeline so that
133
+ // Propshaft/Sprockets can serve it via javascript_include_tag.
134
+ //
135
+ // Why: Propshaft digests entry filenames (inertia.js → inertia-abc123.js)
136
+ // but cannot rewrite import paths inside Vite's chunks. Without the shim,
137
+ // the <script> tag and chunk imports resolve to different ES module
138
+ // instances — duplicating React, Inertia, and other stateful singletons.
139
+ // The shim ensures both paths chain to the same _[name]-[hash].js module.
140
+ const shimName = chunk.name + '.js';
141
+ const shim = `import "./${fileName}";export * from "./${fileName}";\n`;
142
+ fs.writeFileSync(path.join(outDir, shimName), shim);
143
+ fs.writeFileSync(path.join(assetPipelineDir, shimName), shim);
144
+ }
145
+ else if (isEntryCss) {
146
+ // Copy entry CSS to the asset pipeline. Shared chunk CSS stays in outputDir.
136
147
  const src = path.join(outDir, fileName);
137
148
  const dest = path.join(assetPipelineDir, fileName);
138
149
  fs.mkdirSync(path.dirname(dest), { recursive: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rails-vite-plugin",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Vite plugin for Rails integration",
5
5
  "author": "Svyatoslav Kryukov <me@skryukov.dev>",
6
6
  "license": "MIT",