Skip to content

Commit 37f2ab5

Browse files
Merge pull request #113 from codesandbox/decoupling
Decoupling
2 parents 10b0b1d + 790f08c commit 37f2ab5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+8873
-1860
lines changed

build/plugins.cjs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
module.exports.moduleReplacementPlugin = function moduleReplacementPlugin(
2+
replacements
3+
) {
4+
return {
5+
name: "module-replacement",
6+
setup(build) {
7+
for (const [key, value] of Object.entries(replacements)) {
8+
build.onResolve({ filter: new RegExp(`^${value}$`) }, (args) => {
9+
return { path: require.resolve(key) };
10+
});
11+
}
12+
},
13+
};
14+
};
15+
16+
module.exports.forbidImportsPlugin = function forbidImportsPlugin(imports) {
17+
return {
18+
name: "forbid-imports",
19+
setup(build) {
20+
for (const packageName of imports) {
21+
// catch `import ... from 'packageName'` **and** sub-paths `packageName/foo`
22+
const pkgFilter = new RegExp(`^${packageName}($|/)`);
23+
build.onResolve({ filter: pkgFilter }, (args) => {
24+
return {
25+
errors: [
26+
{
27+
text: `❌ Importing “${packageName}” is forbidden in this project.`,
28+
notes: [
29+
"If you really need it, talk to your team lead about an exception.",
30+
],
31+
},
32+
],
33+
};
34+
});
35+
}
36+
},
37+
};
38+
};

build/utils.cjs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module.exports.nodeExternals = [
2+
...Object.keys(require("../package.json").dependencies),
3+
...require("module").builtinModules,
4+
...require("module").builtinModules.map((mod) => `node:${mod}`),
5+
];
6+
7+
module.exports.define = {
8+
CSB_SDK_VERSION: `"${require("../package.json").version}"`,
9+
};

esbuild.cjs

Lines changed: 126 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,126 +1,143 @@
1+
const fs = require("fs");
12
const esbuild = require("esbuild");
3+
const { nodeExternals, define } = require("./build/utils.cjs");
4+
const {
5+
moduleReplacementPlugin,
6+
forbidImportsPlugin,
7+
} = require("./build/plugins.cjs");
28

3-
// Common plugin for module replacements
4-
const browserifyPlugin = {
5-
name: "alias",
6-
setup(build) {
7-
// Handle os module replacement
8-
build.onResolve({ filter: /^os$/ }, (args) => {
9-
return { path: require.resolve("os-browserify/browser") };
10-
});
9+
// Until pitcher-client is part of SDK we need to forbid these imports in
10+
// Node builds
11+
const preventPitcherClientImportsPlugin = forbidImportsPlugin([
12+
"@codesandbox/pitcher-protocol",
13+
"@codesandbox/pitcher-common",
14+
]);
1115

12-
// Handle path module replacement
13-
build.onResolve({ filter: /^path$/ }, (args) => {
14-
return { path: require.resolve("path-browserify") };
15-
});
16-
},
17-
};
16+
/**
17+
* BROWSER CLIENT BUILD
18+
*/
19+
const browserPlugin = moduleReplacementPlugin({
20+
"os-browserify/browser": /^os$/,
21+
"path-browserify": /^path$/,
22+
});
1823

19-
// Build both CJS and ESM versions
20-
Promise.all([
21-
// Browser builds:
22-
// CommonJS build
23-
esbuild.build({
24-
entryPoints: ["src/browser.ts"],
25-
bundle: true,
26-
format: "cjs",
27-
// .cjs extension is required because "type": "module" is set in package.json
28-
outfile: "dist/cjs/browser.cjs",
29-
platform: "browser",
30-
// pitcher-common currently requires this, but breaks the first experience
31-
banner: {
32-
js: `if (typeof window !== "undefined" && !window.process) {
33-
window.process = {
34-
env: {},
35-
};
24+
const browserCjsBuild = esbuild.build({
25+
entryPoints: ["src/browser/index.ts"],
26+
bundle: true,
27+
format: "cjs",
28+
// .cjs extension is required because "type": "module" is set in package.json
29+
outfile: "dist/cjs/browser.cjs",
30+
platform: "browser",
31+
// pitcher-common currently requires this, but breaks the first experience
32+
banner: {
33+
js: `if (typeof window !== "undefined" && !window.process) {
34+
window.process = {
35+
env: {},
36+
};
3637
}
3738
`,
38-
},
39-
plugins: [browserifyPlugin],
40-
}),
39+
},
40+
plugins: [browserPlugin],
41+
// pitcher-client seems to have some dynamic dependency on @sentry/node
42+
external: ["@sentry/node"],
43+
});
4144

42-
// ESM build
43-
esbuild.build({
44-
entryPoints: ["src/browser.ts"],
45-
bundle: true,
46-
format: "esm",
47-
outdir: "dist/esm",
48-
platform: "browser",
49-
// pitcher-common currently requires this, but breaks the first experience
50-
banner: {
51-
js: `if (typeof window !== "undefined" && !window.process) {
52-
window.process = {
53-
env: {},
54-
};
45+
const browserEsmBuild = esbuild.build({
46+
entryPoints: ["src/browser/index.ts"],
47+
bundle: true,
48+
format: "esm",
49+
outfile: "dist/esm/browser.js",
50+
platform: "browser",
51+
metafile: true,
52+
// pitcher-common currently requires this, but breaks the first experience
53+
banner: {
54+
js: `if (typeof window !== "undefined" && !window.process) {
55+
window.process = {
56+
env: {},
57+
};
5558
}
5659
`,
57-
},
58-
plugins: [browserifyPlugin],
59-
}),
60+
},
61+
plugins: [browserPlugin],
62+
// pitcher-client seems to have some dynamic dependency on @sentry/node
63+
external: ["@sentry/node"],
64+
});
6065

61-
// Index builds:
62-
// Node:
63-
// CommonJS build
64-
esbuild.build({
65-
entryPoints: ["src/index.ts"],
66-
bundle: true,
67-
format: "cjs",
68-
platform: "node",
69-
// .cjs extension is required because "type": "module" is set in package.json
70-
outfile: "dist/cjs/index.cjs",
71-
plugins: [browserifyPlugin],
72-
}),
66+
/**
67+
* NODE CLIENT BUILD
68+
*/
7369

74-
// ESM build
75-
esbuild.build({
76-
entryPoints: ["src/index.ts"],
77-
bundle: true,
78-
format: "esm",
79-
platform: "node",
80-
banner: {
81-
js: `
82-
import { fileURLToPath } from 'url';
83-
import { createRequire as topLevelCreateRequire } from 'module';
84-
const require = topLevelCreateRequire(import.meta.url);
85-
`.trim(),
86-
},
87-
outfile: "dist/esm/index.js",
88-
plugins: [browserifyPlugin],
89-
}),
70+
const nodeClientCjsBuild = esbuild.build({
71+
entryPoints: ["src/node/index.ts"],
72+
bundle: true,
73+
format: "cjs",
74+
// .cjs extension is required because "type": "module" is set in package.json
75+
outfile: "dist/cjs/node.cjs",
76+
platform: "node",
77+
external: nodeExternals,
78+
plugins: [preventPitcherClientImportsPlugin],
79+
});
9080

91-
// Edge:
92-
// CommonJS build
93-
esbuild.build({
94-
entryPoints: ["src/index.ts"],
95-
// .cjs extension is required because "type": "module" is set in package.json
96-
outfile: "dist/cjs/index.edge.cjs",
97-
bundle: true,
98-
format: "cjs",
99-
platform: "browser",
100-
plugins: [browserifyPlugin],
101-
}),
81+
const nodeClientEsmBuild = esbuild.build({
82+
entryPoints: ["src/node/index.ts"],
83+
bundle: true,
84+
format: "esm",
85+
outfile: "dist/esm/node.js",
86+
platform: "node",
87+
external: nodeExternals,
88+
plugins: [preventPitcherClientImportsPlugin],
89+
});
10290

103-
// ESM build
104-
esbuild.build({
105-
entryPoints: ["src/index.ts"],
106-
outfile: "dist/esm/index.edge.js",
107-
bundle: true,
108-
format: "esm",
109-
platform: "browser",
110-
plugins: [browserifyPlugin],
111-
}),
91+
/**
92+
* SDK BUILD
93+
*/
94+
const sdkCjsBuild = esbuild.build({
95+
entryPoints: ["src/index.ts"],
96+
bundle: true,
97+
format: "cjs",
98+
define,
99+
platform: "node",
100+
// .cjs extension is required because "type": "module" is set in package.json
101+
outfile: "dist/cjs/index.cjs",
102+
external: nodeExternals,
103+
});
104+
105+
const sdkEsmBuild = esbuild.build({
106+
entryPoints: ["src/index.ts"],
107+
bundle: true,
108+
format: "esm",
109+
define,
110+
platform: "node",
111+
outfile: "dist/esm/index.js",
112+
external: nodeExternals,
113+
plugins: [preventPitcherClientImportsPlugin],
114+
});
112115

113-
// Bin builds:
114-
esbuild.build({
115-
entryPoints: ["src/bin/main.ts"],
116-
outfile: "dist/bin/codesandbox.cjs",
117-
bundle: true,
118-
format: "cjs",
119-
platform: "node",
120-
banner: {
121-
js: `#!/usr/bin/env node\n\n`,
122-
},
123-
}),
116+
/**
117+
* CLI BUILD
118+
*/
119+
const cliBuild = esbuild.build({
120+
entryPoints: ["src/bin/main.tsx"],
121+
outfile: "dist/bin/codesandbox.mjs",
122+
bundle: true,
123+
define,
124+
format: "esm",
125+
platform: "node",
126+
banner: {
127+
js: `#!/usr/bin/env node\n\n`,
128+
},
129+
external: [...nodeExternals, "@codesandbox/sdk"],
130+
plugins: [preventPitcherClientImportsPlugin],
131+
});
132+
133+
Promise.all([
134+
browserCjsBuild,
135+
browserEsmBuild,
136+
nodeClientCjsBuild,
137+
nodeClientEsmBuild,
138+
sdkCjsBuild,
139+
sdkEsmBuild,
140+
cliBuild,
124141
]).catch(() => {
125142
process.exit(1);
126143
});

0 commit comments

Comments
 (0)