Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatic code segmentation causes babel plug-in to not work #3081

Open
lovelyyl opened this issue Dec 27, 2024 · 6 comments
Open

Automatic code segmentation causes babel plug-in to not work #3081

lovelyyl opened this issue Dec 27, 2024 · 6 comments
Labels
information needed Further information is requested

Comments

@lovelyyl
Copy link

Image

This will cause this babel plug-in to not take effect. I don't know which problem it is.

Image

remove autoCodeSplitting

@lovelyyl
Copy link
Author

Image

@schiller-manuel
Copy link
Contributor

please provide a complete, minimal example

@schiller-manuel schiller-manuel added the information needed Further information is requested label Dec 29, 2024
@lovelyyl
Copy link
Author

// isOk
Image

It has something to do with the order of vite plug-ins

// It's not working anymore.
Image

@schiller-manuel
Copy link
Contributor

@SeanCassiere can you please have a look, I saw that you used react compiler here SeanCassiere/nv-rental-clone@bc673f8#diff-6a3b01ba97829c9566ef2d8dc466ffcffb4bdac08706d3d6319e42e0aa6890dd

in the order that apparently does not work (anymore?)?

@lovelyyl
Copy link
Author

lovelyyl commented Jan 2, 2025

@SeanCassiere
Copy link
Member

lovelyyl/router-bug@main

The React compiler babel plugin hasn't been correctly configured here.

// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { TanStackRouterVite } from "@tanstack/router-plugin/vite";

// https://vite.dev/config/
export default defineConfig({
	plugins: [
		TanStackRouterVite({ autoCodeSplitting: true }),
		react({
-			babel: { plugins: ["babel-plugin-react-compiler"] },
+			babel: { plugins: [["babel-plugin-react-compiler", { target: "19" }]] },
		}),
	],
	build: {
		minify: false,
	},
});

Although the target is not required and should be auto-detectable, the React compiler installation docs do recommend adding it in. Either ways, it looks like at the very least it expects an empty object ({ }).

Once the correct configuration has been added in, using the above reproduction as a base, if you replace the content in the src/routes/index.tsx file with the following content you are able to see the compiler in action in the final built output.

// src/routes/index.tsx
import React from "react";
import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/")({
	component: RouteComponent,
});

function RouteComponent() {
	const [name, setName] = React.useState({ first: "", last: "" });

	const fullName = `${name.first} ${name.last}`;

	return (
		<div>
			<h1>Hello "/"!</h1>
			<DisplayFullName fullName={fullName} />
			<div>
				<button
					type='button'
					onClick={() => {
						setName({ first: "Tanner", last: "Linsley" });
					}}
				>
					Set name to 'Tanner Linsley'
				</button>
			</div>
		</div>
	);
}

function DisplayFullName({ fullName }: { fullName: string }) {
	return (
		<div>
			<label>
				Full name:
				<input value={fullName} readOnly />
			</label>
		</div>
	);
}

The reason the compiler is being used here is that it only attempts to optimize components when there's a need for it. It isn't overly optimistic in this regard. So, the replaced content from above triggers the compiler since it detects that non-memoized values are being called in a child component, which is a trigger for optimization.

The built output looks as follows. Specifically note the work happening in the DisplayFullName component.

import { r as requireReact, R as React, j as jsxRuntimeExports } from "./index-CdRTZHFm.js";
var compilerRuntime = { exports: {} };
var reactCompilerRuntime_production = {};
/**
 * @license React
 * react-compiler-runtime.production.js
 *
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
var hasRequiredReactCompilerRuntime_production;
function requireReactCompilerRuntime_production() {
  if (hasRequiredReactCompilerRuntime_production) return reactCompilerRuntime_production;
  hasRequiredReactCompilerRuntime_production = 1;
  var ReactSharedInternals = requireReact().__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
  reactCompilerRuntime_production.c = function(size) {
    return ReactSharedInternals.H.useMemoCache(size);
  };
  return reactCompilerRuntime_production;
}
var hasRequiredCompilerRuntime;
function requireCompilerRuntime() {
  if (hasRequiredCompilerRuntime) return compilerRuntime.exports;
  hasRequiredCompilerRuntime = 1;
  {
    compilerRuntime.exports = requireReactCompilerRuntime_production();
  }
  return compilerRuntime.exports;
}
var compilerRuntimeExports = requireCompilerRuntime();
function DisplayFullName(t0) {
  const $ = compilerRuntimeExports.c(2);
  const {
    fullName
  } = t0;
  let t1;
  if ($[0] !== fullName) {
    t1 = /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { children: [
      "Full name:",
      /* @__PURE__ */ jsxRuntimeExports.jsx("input", { value: fullName, readOnly: true })
    ] }) });
    $[0] = fullName;
    $[1] = t1;
  } else {
    t1 = $[1];
  }
  return t1;
}
const component = function RouteComponent() {
  const [name, setName] = React.useState({
    first: "",
    last: ""
  });
  const fullName = `${name.first} ${name.last}`;
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
    /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { children: 'Hello "/"!' }),
    /* @__PURE__ */ jsxRuntimeExports.jsx(DisplayFullName, { fullName }),
    /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", onClick: () => {
      setName({
        first: "Tanner",
        last: "Linsley"
      });
    }, children: "Set name to 'Tanner Linsley'" }) })
  ] });
};
export {
  component
};

As a side note, I'm not sure if further optimization should be happening in the const component = function RouteComponent() { component. I trust the React core team's understanding of the library here more than my own. However, if you believe that compiler should also be making changes in this component, that may be a question to pose to the React core team.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
information needed Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants