Skip to content

Commit

Permalink
Add use client directives to the created mjs wrappers
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist committed Mar 26, 2024
1 parent 9f44a11 commit 985e57f
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 3 deletions.
187 changes: 187 additions & 0 deletions packages/cli/src/build/__tests__/other.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,134 @@ test("use client", async () => {
`);
});

test("use client (importConditionDefaultExport: default)", async () => {
const dir = await testdir({
"package.json": JSON.stringify({
name: "pkg",
main: "dist/pkg.cjs.js",
module: "dist/pkg.esm.js",
exports: {
".": {
types: {
import: "./dist/pkg.cjs.mjs",
default: "./dist/pkg.cjs.js",
},
module: "./dist/pkg.esm.js",
import: "./dist/pkg.cjs.mjs",
default: "./dist/pkg.cjs.js",
},
"./package.json": "./package.json",
},
preconstruct: {
exports: {
importConditionDefaultExport: "default",
},
___experimentalFlags_WILL_CHANGE_IN_PATCH: {
importsConditions: true,
},
},
}),
"src/index.js": js`
export { A } from "./client";
export { C } from "./c";
export { B } from "./b";
`,
"src/client.js": js`
"use client";
export const A = "something";
`,
"src/b.js": js`
export const B = "b";
`,
"src/c.js": js`
import { D } from "./d";
export function C() {
return D;
}
`,
"src/d.js": js`
"use client";
export const D = "d";
`,
});
await build(dir);
expect(await getFiles(dir, ["dist/**"], stripHashes("client", "d")))
.toMatchInlineSnapshot(`
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ dist/client-this-is-not-the-real-hash-58cd7e7ea387bdad7ade6e69ad459a33.cjs.js ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
'use client';
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const A = "something";
exports.A = A;
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ dist/client-this-is-not-the-real-hash-b139dd137c1582a38e35a32f7605ab74.esm.js ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
'use client';
const A = "something";
export { A };
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ dist/d-this-is-not-the-real-hash-24ae31ff9082854e1c87c472a0860694.cjs.js ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
'use client';
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const D = "d";
exports.D = D;
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ dist/d-this-is-not-the-real-hash-edd08facffb57479ea67330357004b7f.esm.js ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
'use client';
const D = "d";
export { D };
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ dist/pkg.cjs.js ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var client = require('./client-some-hash.cjs.js');
var d = require('./d-some-hash.cjs.js');
function C() {
return d.D;
}
const B = "b";
Object.defineProperty(exports, 'A', {
enumerable: true,
get: function () { return client.A; }
});
exports.B = B;
exports.C = C;
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ dist/pkg.cjs.mjs ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
export {
A,
B,
C
} from "./pkg.cjs.js";
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ dist/pkg.esm.js ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
export { A } from './client-some-hash.esm.js';
import { D } from './d-some-hash.esm.js';
function C() {
return D;
}
const B = "b";
export { B, C };
`);
});

test("use client as entrypoint", async () => {
const dir = await testdir({
"package.json": JSON.stringify({
Expand Down Expand Up @@ -1090,6 +1218,65 @@ test("use client as entrypoint", async () => {
`);
});

test("use client as entrypoint (importConditionDefaultExport: default)", async () => {
const dir = await testdir({
"package.json": JSON.stringify({
name: "pkg",
main: "dist/pkg.cjs.js",
module: "dist/pkg.esm.js",
exports: {
".": {
types: {
import: "./dist/pkg.cjs.mjs",
default: "./dist/pkg.cjs.js",
},
module: "./dist/pkg.esm.js",
import: "./dist/pkg.cjs.mjs",
default: "./dist/pkg.cjs.js",
},
"./package.json": "./package.json",
},
preconstruct: {
exports: {
importConditionDefaultExport: "default",
},
___experimentalFlags_WILL_CHANGE_IN_PATCH: {
importsConditions: true,
},
},
}),
"src/index.js": js`
"use client";
export const a = true;
`,
});
await build(dir);
expect(await getFiles(dir, ["dist/**"])).toMatchInlineSnapshot(`
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ dist/pkg.cjs.js ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
'use client';
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const a = true;
exports.a = a;
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ dist/pkg.cjs.mjs ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
'use client';
export {
a
} from "./pkg.cjs.js";
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ dist/pkg.esm.js ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
'use client';
const a = true;
export { a };
`);
});

test("use client with typescript", async () => {
const dir = await testdir({
...typescriptFixture,
Expand Down
11 changes: 10 additions & 1 deletion packages/cli/src/rollup-plugins/mjs-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,21 @@ export default function mjsProxyPlugin(pkg: Package): Plugin {
continue;
}

const moduleInfo = this.getModuleInfo(file.facadeModuleId);
let directive: "use client" | "use server" | undefined =
moduleInfo?.meta.directivePreservedFile?.directive;

let mjsPath = file.fileName.replace(/(?:\.prod)?\.js$/, ".mjs");
const cjsRelativePath = `./${path.basename(mjsPath, ".mjs")}.js`;
this.emitFile({
type: "asset",
fileName: mjsPath,
source: mjsTemplate(file.exports, cjsRelativePath, mjsPath),
source: mjsTemplate(
file.exports,
cjsRelativePath,
mjsPath,
directive
),
});
if (file.exports.includes("default")) {
this.emitFile({
Expand Down
8 changes: 6 additions & 2 deletions packages/cli/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -449,12 +449,16 @@ export function dtsDefaultForDmtsTemplate(relativePath: string) {
export function mjsTemplate(
exports: string[],
relativePath: string,
mjsPath: string
mjsPath: string,
directive?: "use client" | "use server"
) {
const escapedPath = JSON.stringify(relativePath);
const nonDefaultExports = exports.filter((name) => name !== "default");
const hasDefaultExport = exports.length !== nonDefaultExports.length;
return `${getReexportStatement(nonDefaultExports, escapedPath)}\n${
return `${directive ? `'${directive}';\n` : ""}${getReexportStatement(
nonDefaultExports,
escapedPath
)}\n${
hasDefaultExport
? `export { _default as default } from ${JSON.stringify(
"./" + getJsDefaultForMjsFilepath(nodePath.basename(mjsPath))
Expand Down

0 comments on commit 985e57f

Please sign in to comment.