@netlify/vite-plugin-react-router 2.1.1 → 2.1.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.1.3](https://github.com/netlify/remix-compute/compare/vite-plugin-react-router-v2.1.2...vite-plugin-react-router-v2.1.3) (2026-01-19)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **vite-plugin-react-router:** fix prerendering by not clobbering SSR bundle entries ([#620](https://github.com/netlify/remix-compute/issues/620)) ([54851a9](https://github.com/netlify/remix-compute/commit/54851a92c4361c9987dc1cb34186bf73ddb1a38e))
9
+
10
+ ## [2.1.2](https://github.com/netlify/remix-compute/compare/vite-plugin-react-router-v2.1.1...vite-plugin-react-router-v2.1.2) (2025-11-08)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **vite-plugin-react-router:** fix custom `build.assetsDir` edge case ([#578](https://github.com/netlify/remix-compute/issues/578)) ([7316d95](https://github.com/netlify/remix-compute/commit/7316d95ea087e19dffe9414749c891642096c4cd))
16
+
3
17
  ## [2.1.1](https://github.com/netlify/remix-compute/compare/vite-plugin-react-router-v2.1.0...vite-plugin-react-router-v2.1.1) (2025-11-06)
4
18
 
5
19
 
package/dist/index.js CHANGED
@@ -107,12 +107,38 @@ function createRequestHandler({
107
107
 
108
108
  // src/plugin.ts
109
109
  var import_promises = require("fs/promises");
110
- var import_node_path = require("path");
110
+ var import_node_path2 = require("path");
111
111
  var import_posix = require("path/posix");
112
+ var import_tinyglobby = require("tinyglobby");
112
113
 
113
114
  // package.json
114
115
  var name = "@netlify/vite-plugin-react-router";
115
- var version = "2.1.1";
116
+ var version = "2.1.3";
117
+
118
+ // src/lib/rollup.ts
119
+ var import_node_path = require("path");
120
+ var getAliasName = (id) => {
121
+ const base = (0, import_node_path.basename)(id);
122
+ return base.slice(0, Math.max(0, base.length - (0, import_node_path.extname)(id).length));
123
+ };
124
+ var normalizeRollupInput = (input) => {
125
+ if (input == null) {
126
+ return {};
127
+ }
128
+ if (typeof input === "string") {
129
+ return { [getAliasName(input)]: input };
130
+ }
131
+ if (Array.isArray(input)) {
132
+ return Object.fromEntries(input.map((entry) => [getAliasName(entry), entry]));
133
+ }
134
+ return input;
135
+ };
136
+ var mergeRollupInput = (existing, newEntries) => {
137
+ return {
138
+ ...normalizeRollupInput(existing),
139
+ ...newEntries
140
+ };
141
+ };
116
142
 
117
143
  // src/plugin.ts
118
144
  var NETLIFY_FUNCTIONS_DIR = ".netlify/v1/functions";
@@ -122,7 +148,7 @@ var FUNCTION_HANDLER_CHUNK = "server";
122
148
  var FUNCTION_HANDLER_MODULE_ID = "virtual:netlify-server";
123
149
  var RESOLVED_FUNCTION_HANDLER_MODULE_ID = `\0${FUNCTION_HANDLER_MODULE_ID}`;
124
150
  var SERVER_ENTRY_MODULE_ID = "virtual:netlify-server-entry";
125
- var toPosixPath = (path) => path.split(import_node_path.sep).join(import_posix.sep);
151
+ var toPosixPath = (path) => path.split(import_node_path2.sep).join(import_posix.sep);
126
152
  var FUNCTION_HANDLER = (
127
153
  /* js */
128
154
  `
@@ -183,36 +209,37 @@ function netlifyPlugin(options = {}) {
183
209
  let currentCommand;
184
210
  return {
185
211
  name: "vite-plugin-netlify-react-router",
186
- config(config, { command, isSsrBuild }) {
212
+ config(_config, { command, isSsrBuild }) {
187
213
  currentCommand = command;
188
214
  isProductionSsrBuild = isSsrBuild === true && command === "build";
189
215
  if (isProductionSsrBuild) {
190
- config.build ??= {};
191
- config.build.rollupOptions ??= {};
192
- config.build.rollupOptions.input = {
216
+ const functionHandlerInput = {
193
217
  [FUNCTION_HANDLER_CHUNK]: FUNCTION_HANDLER_MODULE_ID
194
218
  };
195
- config.build.rollupOptions.output ??= {};
196
- if (Array.isArray(config.build.rollupOptions.output)) {
197
- console.warn(
198
- "Expected Vite config `build.rollupOptions.output` to be an object, but it is an array - overwriting it, but this may cause issues with your custom configuration"
199
- );
200
- config.build.rollupOptions.output = {};
201
- }
202
- config.build.rollupOptions.output.entryFileNames = "[name].js";
203
- if (edge) {
204
- config.ssr = {
205
- ...config.ssr,
206
- target: "webworker",
207
- // Bundle everything except Node.js built-ins (which are supported but must use the `node:` prefix):
208
- // https://docs.netlify.com/build/edge-functions/api/#runtime-environment
209
- noExternal: /^(?!node:).*$/,
210
- resolve: {
211
- ...config.resolve,
212
- conditions: ["worker", "deno", "browser"]
219
+ const mergedInput = mergeRollupInput(_config.build?.rollupOptions?.input, functionHandlerInput);
220
+ const configChanges = {
221
+ build: {
222
+ rollupOptions: {
223
+ input: mergedInput,
224
+ output: {
225
+ entryFileNames: "[name].js"
226
+ }
213
227
  }
214
- };
215
- }
228
+ },
229
+ // Additional config needed for Edge Functions if enabled
230
+ ...edge ? {
231
+ ssr: {
232
+ target: "webworker",
233
+ // Bundle everything except Node.js built-ins (which are supported but must use the `node:` prefix):
234
+ // https://docs.netlify.com/build/edge-functions/api/#runtime-environment
235
+ noExternal: /^(?!node:).*$/,
236
+ resolve: {
237
+ conditions: ["worker", "deno", "browser"]
238
+ }
239
+ }
240
+ } : {}
241
+ };
242
+ return configChanges;
216
243
  }
217
244
  },
218
245
  async resolveId(source, importer, options2) {
@@ -225,7 +252,7 @@ function netlifyPlugin(options = {}) {
225
252
  if (!reactRouterDev) {
226
253
  throw new Error("The @react-router/dev package is required for local development. Please install it.");
227
254
  }
228
- return (0, import_node_path.resolve)((0, import_node_path.dirname)(reactRouterDev.id), "config/defaults/entry.server.node.tsx");
255
+ return (0, import_node_path2.resolve)((0, import_node_path2.dirname)(reactRouterDev.id), "config/defaults/entry.server.node.tsx");
229
256
  }
230
257
  return this.resolve("@netlify/vite-plugin-react-router/entry.server.edge", importer, options2);
231
258
  }
@@ -242,29 +269,31 @@ function netlifyPlugin(options = {}) {
242
269
  // See https://rollupjs.org/plugin-development/#writebundle.
243
270
  async writeBundle() {
244
271
  if (isProductionSsrBuild) {
245
- const handlerPath = (0, import_node_path.join)(resolvedConfig.build.outDir, `${FUNCTION_HANDLER_CHUNK}.js`);
272
+ const handlerPath = (0, import_node_path2.join)(resolvedConfig.build.outDir, `${FUNCTION_HANDLER_CHUNK}.js`);
246
273
  if (edge) {
247
- const clientDir = (0, import_node_path.join)(resolvedConfig.build.outDir, "..", "client");
248
- const entries = await (0, import_promises.readdir)(clientDir, { withFileTypes: true });
249
- const excludedPath = [
250
- "/.netlify/*",
251
- ...entries.map((entry) => entry.isDirectory() ? `/${entry.name}/*` : `/${entry.name}`),
252
- ...additionalExcludedPaths
253
- ];
254
- const edgeFunctionsDir = (0, import_node_path.join)(resolvedConfig.root, NETLIFY_EDGE_FUNCTIONS_DIR);
274
+ const clientDir = (0, import_node_path2.join)(resolvedConfig.build.outDir, "..", "client");
275
+ const clientFiles = await (0, import_tinyglobby.glob)("**/*", {
276
+ cwd: clientDir,
277
+ // We can't exclude entire directories because there could be `foo/bar.baz` in the
278
+ // client dir and a `/foo` route handled by the server function.
279
+ onlyFiles: true,
280
+ dot: true
281
+ });
282
+ const excludedPath = ["/.netlify/*", ...clientFiles.map((file) => `/${file}`), ...additionalExcludedPaths];
283
+ const edgeFunctionsDir = (0, import_node_path2.join)(resolvedConfig.root, NETLIFY_EDGE_FUNCTIONS_DIR);
255
284
  await (0, import_promises.mkdir)(edgeFunctionsDir, { recursive: true });
256
- const relativeHandlerPath = toPosixPath((0, import_node_path.relative)(edgeFunctionsDir, handlerPath));
285
+ const relativeHandlerPath = toPosixPath((0, import_node_path2.relative)(edgeFunctionsDir, handlerPath));
257
286
  await (0, import_promises.writeFile)(
258
- (0, import_node_path.join)(edgeFunctionsDir, FUNCTION_FILENAME),
287
+ (0, import_node_path2.join)(edgeFunctionsDir, FUNCTION_FILENAME),
259
288
  generateEdgeFunction(relativeHandlerPath, excludedPath)
260
289
  );
261
290
  } else {
262
- const functionsDir = (0, import_node_path.join)(resolvedConfig.root, NETLIFY_FUNCTIONS_DIR);
291
+ const functionsDir = (0, import_node_path2.join)(resolvedConfig.root, NETLIFY_FUNCTIONS_DIR);
263
292
  await (0, import_promises.mkdir)(functionsDir, { recursive: true });
264
- const relativeHandlerPath = toPosixPath((0, import_node_path.relative)(functionsDir, handlerPath));
293
+ const relativeHandlerPath = toPosixPath((0, import_node_path2.relative)(functionsDir, handlerPath));
265
294
  const excludedPath = ["/.netlify/*", ...additionalExcludedPaths];
266
295
  await (0, import_promises.writeFile)(
267
- (0, import_node_path.join)(functionsDir, FUNCTION_FILENAME),
296
+ (0, import_node_path2.join)(functionsDir, FUNCTION_FILENAME),
268
297
  generateNetlifyFunction(relativeHandlerPath, excludedPath)
269
298
  );
270
299
  }
package/dist/index.mjs CHANGED
@@ -5,13 +5,39 @@ import {
5
5
  import "./chunk-J5PMA2AP.mjs";
6
6
 
7
7
  // src/plugin.ts
8
- import { mkdir, writeFile, readdir } from "node:fs/promises";
8
+ import { mkdir, writeFile } from "node:fs/promises";
9
9
  import { dirname, join, relative, resolve, sep } from "node:path";
10
10
  import { sep as posixSep } from "node:path/posix";
11
+ import { glob } from "tinyglobby";
11
12
 
12
13
  // package.json
13
14
  var name = "@netlify/vite-plugin-react-router";
14
- var version = "2.1.1";
15
+ var version = "2.1.3";
16
+
17
+ // src/lib/rollup.ts
18
+ import { basename, extname } from "node:path";
19
+ var getAliasName = (id) => {
20
+ const base = basename(id);
21
+ return base.slice(0, Math.max(0, base.length - extname(id).length));
22
+ };
23
+ var normalizeRollupInput = (input) => {
24
+ if (input == null) {
25
+ return {};
26
+ }
27
+ if (typeof input === "string") {
28
+ return { [getAliasName(input)]: input };
29
+ }
30
+ if (Array.isArray(input)) {
31
+ return Object.fromEntries(input.map((entry) => [getAliasName(entry), entry]));
32
+ }
33
+ return input;
34
+ };
35
+ var mergeRollupInput = (existing, newEntries) => {
36
+ return {
37
+ ...normalizeRollupInput(existing),
38
+ ...newEntries
39
+ };
40
+ };
15
41
 
16
42
  // src/plugin.ts
17
43
  var NETLIFY_FUNCTIONS_DIR = ".netlify/v1/functions";
@@ -82,36 +108,37 @@ function netlifyPlugin(options = {}) {
82
108
  let currentCommand;
83
109
  return {
84
110
  name: "vite-plugin-netlify-react-router",
85
- config(config, { command, isSsrBuild }) {
111
+ config(_config, { command, isSsrBuild }) {
86
112
  currentCommand = command;
87
113
  isProductionSsrBuild = isSsrBuild === true && command === "build";
88
114
  if (isProductionSsrBuild) {
89
- config.build ??= {};
90
- config.build.rollupOptions ??= {};
91
- config.build.rollupOptions.input = {
115
+ const functionHandlerInput = {
92
116
  [FUNCTION_HANDLER_CHUNK]: FUNCTION_HANDLER_MODULE_ID
93
117
  };
94
- config.build.rollupOptions.output ??= {};
95
- if (Array.isArray(config.build.rollupOptions.output)) {
96
- console.warn(
97
- "Expected Vite config `build.rollupOptions.output` to be an object, but it is an array - overwriting it, but this may cause issues with your custom configuration"
98
- );
99
- config.build.rollupOptions.output = {};
100
- }
101
- config.build.rollupOptions.output.entryFileNames = "[name].js";
102
- if (edge) {
103
- config.ssr = {
104
- ...config.ssr,
105
- target: "webworker",
106
- // Bundle everything except Node.js built-ins (which are supported but must use the `node:` prefix):
107
- // https://docs.netlify.com/build/edge-functions/api/#runtime-environment
108
- noExternal: /^(?!node:).*$/,
109
- resolve: {
110
- ...config.resolve,
111
- conditions: ["worker", "deno", "browser"]
118
+ const mergedInput = mergeRollupInput(_config.build?.rollupOptions?.input, functionHandlerInput);
119
+ const configChanges = {
120
+ build: {
121
+ rollupOptions: {
122
+ input: mergedInput,
123
+ output: {
124
+ entryFileNames: "[name].js"
125
+ }
112
126
  }
113
- };
114
- }
127
+ },
128
+ // Additional config needed for Edge Functions if enabled
129
+ ...edge ? {
130
+ ssr: {
131
+ target: "webworker",
132
+ // Bundle everything except Node.js built-ins (which are supported but must use the `node:` prefix):
133
+ // https://docs.netlify.com/build/edge-functions/api/#runtime-environment
134
+ noExternal: /^(?!node:).*$/,
135
+ resolve: {
136
+ conditions: ["worker", "deno", "browser"]
137
+ }
138
+ }
139
+ } : {}
140
+ };
141
+ return configChanges;
115
142
  }
116
143
  },
117
144
  async resolveId(source, importer, options2) {
@@ -144,12 +171,14 @@ function netlifyPlugin(options = {}) {
144
171
  const handlerPath = join(resolvedConfig.build.outDir, `${FUNCTION_HANDLER_CHUNK}.js`);
145
172
  if (edge) {
146
173
  const clientDir = join(resolvedConfig.build.outDir, "..", "client");
147
- const entries = await readdir(clientDir, { withFileTypes: true });
148
- const excludedPath = [
149
- "/.netlify/*",
150
- ...entries.map((entry) => entry.isDirectory() ? `/${entry.name}/*` : `/${entry.name}`),
151
- ...additionalExcludedPaths
152
- ];
174
+ const clientFiles = await glob("**/*", {
175
+ cwd: clientDir,
176
+ // We can't exclude entire directories because there could be `foo/bar.baz` in the
177
+ // client dir and a `/foo` route handled by the server function.
178
+ onlyFiles: true,
179
+ dot: true
180
+ });
181
+ const excludedPath = ["/.netlify/*", ...clientFiles.map((file) => `/${file}`), ...additionalExcludedPaths];
153
182
  const edgeFunctionsDir = join(resolvedConfig.root, NETLIFY_EDGE_FUNCTIONS_DIR);
154
183
  await mkdir(edgeFunctionsDir, { recursive: true });
155
184
  const relativeHandlerPath = toPosixPath(relative(edgeFunctionsDir, handlerPath));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/vite-plugin-react-router",
3
- "version": "2.1.1",
3
+ "version": "2.1.3",
4
4
  "description": "React Router 7+ Vite plugin for Netlify",
5
5
  "type": "commonjs",
6
6
  "main": "./dist/index.js",
@@ -52,9 +52,10 @@
52
52
  },
53
53
  "homepage": "https://github.com/netlify/remix-compute#readme",
54
54
  "dependencies": {
55
- "@netlify/edge-functions": "^3.0.2",
56
- "@netlify/functions": "^5.1.0",
57
- "isbot": "^5.1.25"
55
+ "@netlify/edge-functions": "^3.0.3",
56
+ "@netlify/functions": "^5.1.2",
57
+ "isbot": "^5.1.25",
58
+ "tinyglobby": "^0.2.10"
58
59
  },
59
60
  "devDependencies": {
60
61
  "@types/react": "^18.0.27",