-
-
Notifications
You must be signed in to change notification settings - Fork 44
Option to disable dependency inlining for RSC directives #157
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
Comments
I think it's not relate to dependency inlining, but unbundle mode. You can try the config defineConfig({
entry: ["src/**/*.ts"]
}) For preserving directives, maybe you need a plugin https://www.npmjs.com/package/rollup-preserve-directives |
The directive is actually preserved, and here's how it looks: The original client component being built: 'use client'
import { SomeProvider as Provider } from 'some-package';
import type { Props } from 'some-package';
export function ClientProvider({ children, ...rest }: Props) {
return (
<Provider {...rest}>
{children}
</Provider>
);
} The output: import { ClientProvider } from "../client-provider-BvRQnBtH.js";
export { ClientProvider }; import { SomeProvider as Provider } from "some-package";
import { jsx } from "react/jsx-runtime";
//#region src/client-boundary/client-provider.tsx
"use client";
function ClientProvider({ children,...rest }) {
return /* @__PURE__ */ jsx(Provider, {
...rest,
children
});
}
//#endregion
export { ClientProvider };
//# sourceMappingURL=client-provider-BvRQnBtH.js.map Notice where the directive was placed. I'll try to investigate and play around with it... thanks! |
We need a plugin to handle |
Made a custom plugin for this in the meantime import type { RolldownPlugin } from 'rolldown'
function rollDownPreserveUseClient(): RolldownPlugin {
return {
name: 'rolldown-preserve-use-client',
async writeBundle(options, bundle) {
for (const [fileName, file] of Object.entries(bundle)) {
if (file.type !== 'chunk' || !file.code) continue;
let code = file.code;
// Find and remove all "use client" or 'use client' directives (with or without semicolon, possibly surrounded by whitespace/newlines)
const useClientRegex = /^\s*(['"])use client\1\s*;?\s*/gm;
const matches = [...code.matchAll(useClientRegex)];
if (matches.length === 0) continue;
// Remove all occurrences
let newCode = code.replace(useClientRegex, '');
// Insert a single 'use client' at the very top, followed by exactly one newline
const useClientLine = `${matches[0][0].trim()}\n`;
newCode = useClientLine + newCode.trimStart();
// Write the modified code back to the file
const outputPath = path.join(options.dir || path.dirname(options.file), fileName);
await fs.writeFile(outputPath, newCode, 'utf8');
}
}
};
} |
I think the problem is tsup enables directive preserve by default, this may cause unwanted behaviours when migrating from tsup. It's easy to overlook the directive was gone in the output, would be helpful to notify users on |
Also ran into this when migrating from tsup! Here's my simple plugin attempt. I'm no expert at rollup/down etc but I was reading that it may be more performant to perform the modification at the renderChunk phase instead of of the writeBundle phase since you have to read and write back to disk. Since my package is a UI library I didn't want to important any node files (not a big deal but yea). Also my linter always updates my "use client" directive to use double quotes so I made a super simple plugin to replace the directive and put it at the top. Also wanted to avoid regex lol. Maybe someone can make an official plugin but here's my shot at it
I also don't generate any sourcemaps but I was reading that MagicString would help with that? Anyways feel free to modify! |
Maybe I missed this option in the docs, but I'm looking for a way to disable dependency inlining similar to esbuild's bundle option. This is particularly important when building React libraries that use Server Components, as we need to preserve directives like
"use client"
in the output.For example, when building a component like this:
Is this something that's already possible? Thanks!
The text was updated successfully, but these errors were encountered: