Skip to content

Commit b6976a9

Browse files
authored
fix: use a more reliable import/export transform for the bootstrap command (#101)
* fix: use a more reliable import/export transform for the bootstrap command * chore: add changeset
1 parent 498d18e commit b6976a9

File tree

7 files changed

+246
-13
lines changed

7 files changed

+246
-13
lines changed

.changeset/thirty-snails-dress.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"bob-the-bundler": patch
3+
---
4+
5+
Use a more reliable import/export transform for the bootstrap command

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
"jest-resolver.js"
2323
],
2424
"dependencies": {
25+
"@babel/core": "^7.18.9",
26+
"@babel/generator": "^7.18.9",
27+
"@babel/parser": "^7.18.9",
28+
"@babel/traverse": "^7.18.9",
2529
"@rollup/plugin-json": "^4.1.0",
2630
"@rollup/plugin-node-resolve": "^13.3.0",
2731
"@vercel/ncc": "^0.34.0",

src/commands/bootstrap.ts

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { buildArtifactDirectories } from "../constants";
77
import { getRootPackageJSON } from "../utils/get-root-package-json";
88
import { getWorkspaces } from "../utils/get-workspaces";
99
import { getWorkspacePackagePaths } from "../utils/get-workspace-package-paths";
10+
import { rewriteCodeImports } from "../utils/rewrite-code-imports";
1011

1112
/** The default bob fields that should be within a package.json */
1213
export const presetFields = Object.freeze({
@@ -56,17 +57,8 @@ export const presetFields = Object.freeze({
5657
},
5758
});
5859

59-
function transformModuleImports(fileContents: string) {
60-
return fileContents.replace(
61-
/* this regex should hopefully catch all kind of import/export expressions that are relative. */
62-
/((?:import|export)\s+[\s\w,{}*]*\s+from\s+["'])((?:\.\/|\.\.\/)(?:(?!\.js).)+)(["'])/g,
63-
(_, importFromPart, modulePath, hyphenEndPart) =>
64-
`${importFromPart}${modulePath}.js${hyphenEndPart}`
65-
);
66-
}
67-
6860
async function applyESMModuleTransform(cwd: string) {
69-
const files = await globby("**/*.ts", {
61+
const filePaths = await globby("**/*.ts", {
7062
cwd,
7163
absolute: true,
7264
ignore: ["**/node_modules/**", ...buildArtifactDirectories],
@@ -75,10 +67,10 @@ async function applyESMModuleTransform(cwd: string) {
7567
const limit = pLimit(20);
7668

7769
await Promise.all(
78-
files.map((file) =>
70+
filePaths.map((filePath) =>
7971
limit(async () => {
80-
const contents = await fse.readFile(file, "utf-8");
81-
await fse.writeFile(file, transformModuleImports(contents));
72+
const contents = await fse.readFile(filePath, "utf-8");
73+
await fse.writeFile(filePath, rewriteCodeImports(contents, filePath));
8274
})
8375
)
8476
);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log("hello");
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { rewriteCodeImports } from "./rewrite-code-imports";
2+
import * as path from "path";
3+
4+
const fixturePath = path.join(__dirname, "__fixtures__", "index.ts");
5+
6+
it("ignores module import statement", () => {
7+
const fixture = "import foo from 'foo'";
8+
const result = rewriteCodeImports(fixture, fixturePath);
9+
expect(result).toEqual("import foo from 'foo';");
10+
});
11+
12+
it("rewrites relative import statement", () => {
13+
const fixture = "import foo from './bar'";
14+
const result = rewriteCodeImports(fixture, fixturePath);
15+
expect(result).toEqual(`import foo from "./bar.js";`);
16+
});
17+
18+
it("rewrites relative import statement for folder", () => {
19+
const fixture = "import foo from './foo'";
20+
const result = rewriteCodeImports(fixture, fixturePath);
21+
expect(result).toEqual(`import foo from "./foo/index.js";`);
22+
});
23+
24+
it("rewrites relative import statement", () => {
25+
const fixture = "import foo from '../foo'";
26+
const result = rewriteCodeImports(fixture, fixturePath);
27+
expect(result).toEqual(`import foo from "../foo.js";`);
28+
});
29+
30+
it("ignores module export statement", () => {
31+
const fixture = "export {foo} from 'foo'";
32+
const result = rewriteCodeImports(fixture, fixturePath);
33+
expect(result).toEqual("export { foo } from 'foo';");
34+
});
35+
36+
it("rewrites relative export statement", () => {
37+
const fixture = "export {foo} from './bar'";
38+
const result = rewriteCodeImports(fixture, fixturePath);
39+
expect(result).toEqual(`export { foo } from "./bar.js";`);
40+
});
41+
42+
it("rewrites relative export statement for folder", () => {
43+
const fixture = "export {foo} from './foo'";
44+
const result = rewriteCodeImports(fixture, fixturePath);
45+
expect(result).toEqual(`export { foo } from "./foo/index.js";`);
46+
});

src/utils/rewrite-code-imports.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { parse } from "@babel/parser";
2+
import generate from "@babel/generator";
3+
import traverse from "@babel/traverse";
4+
import * as fse from "fs-extra";
5+
import * as path from "path";
6+
7+
function isFolderSync(path: string) {
8+
try {
9+
return fse.statSync(path).isDirectory();
10+
} catch (e) {
11+
return false;
12+
}
13+
}
14+
15+
function rewriteSourceValue(sourceValue: string, relativeDirname: string) {
16+
if (sourceValue.startsWith(".") && sourceValue.endsWith(".js") === false) {
17+
const targetPath = path.resolve(relativeDirname, sourceValue);
18+
// If the target path is a folder, we need to import from the index.js file
19+
if (isFolderSync(targetPath)) {
20+
sourceValue += "/index";
21+
}
22+
sourceValue += ".js";
23+
}
24+
return sourceValue;
25+
}
26+
27+
/**
28+
* Rewrite import and export statements to append the correct .js file extension when needed
29+
*/
30+
export function rewriteCodeImports(
31+
fileContents: string,
32+
absoluteFilePath: string
33+
): string {
34+
const ast = parse(fileContents, {
35+
sourceType: "module",
36+
});
37+
38+
const relativeDirname = path.dirname(absoluteFilePath);
39+
40+
traverse(ast, {
41+
ImportDeclaration(nodePath) {
42+
nodePath.node.source.value = rewriteSourceValue(
43+
nodePath.node.source.value,
44+
relativeDirname
45+
);
46+
},
47+
ExportDeclaration(nodePath) {
48+
if (
49+
nodePath.node.type !== "ExportDefaultDeclaration" &&
50+
nodePath.node.source
51+
) {
52+
nodePath.node.source.value = rewriteSourceValue(
53+
nodePath.node.source.value,
54+
relativeDirname
55+
);
56+
}
57+
},
58+
});
59+
60+
return generate(ast).code;
61+
}

yarn.lock

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.6.tgz#8b37d24e88e8e21c499d4328db80577d8882fa53"
3737
integrity sha512-tzulrgDT0QD6U7BJ4TKVk2SDDg7wlP39P9yAx1RfLy7vP/7rsDRlWVfbWxElslu56+r7QOhB2NSDsabYYruoZQ==
3838

39+
"@babel/compat-data@^7.18.8":
40+
version "7.18.8"
41+
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d"
42+
integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==
43+
3944
"@babel/core@^7.11.6", "@babel/core@^7.12.3":
4045
version "7.18.6"
4146
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.6.tgz#54a107a3c298aee3fe5e1947a6464b9b6faca03d"
@@ -57,6 +62,27 @@
5762
json5 "^2.2.1"
5863
semver "^6.3.0"
5964

65+
"@babel/core@^7.18.9":
66+
version "7.18.9"
67+
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.9.tgz#805461f967c77ff46c74ca0460ccf4fe933ddd59"
68+
integrity sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g==
69+
dependencies:
70+
"@ampproject/remapping" "^2.1.0"
71+
"@babel/code-frame" "^7.18.6"
72+
"@babel/generator" "^7.18.9"
73+
"@babel/helper-compilation-targets" "^7.18.9"
74+
"@babel/helper-module-transforms" "^7.18.9"
75+
"@babel/helpers" "^7.18.9"
76+
"@babel/parser" "^7.18.9"
77+
"@babel/template" "^7.18.6"
78+
"@babel/traverse" "^7.18.9"
79+
"@babel/types" "^7.18.9"
80+
convert-source-map "^1.7.0"
81+
debug "^4.1.0"
82+
gensync "^1.0.0-beta.2"
83+
json5 "^2.2.1"
84+
semver "^6.3.0"
85+
6086
"@babel/generator@^7.18.6", "@babel/generator@^7.7.2":
6187
version "7.18.6"
6288
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.6.tgz#9ab2d46d3cbf631f0e80f72e72874a04c3fc12a9"
@@ -66,6 +92,15 @@
6692
"@jridgewell/gen-mapping" "^0.3.0"
6793
jsesc "^2.5.1"
6894

95+
"@babel/generator@^7.18.9":
96+
version "7.18.9"
97+
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.9.tgz#68337e9ea8044d6ddc690fb29acae39359cca0a5"
98+
integrity sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug==
99+
dependencies:
100+
"@babel/types" "^7.18.9"
101+
"@jridgewell/gen-mapping" "^0.3.2"
102+
jsesc "^2.5.1"
103+
69104
"@babel/helper-compilation-targets@^7.18.6":
70105
version "7.18.6"
71106
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.6.tgz#18d35bfb9f83b1293c22c55b3d576c1315b6ed96"
@@ -76,11 +111,26 @@
76111
browserslist "^4.20.2"
77112
semver "^6.3.0"
78113

114+
"@babel/helper-compilation-targets@^7.18.9":
115+
version "7.18.9"
116+
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf"
117+
integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==
118+
dependencies:
119+
"@babel/compat-data" "^7.18.8"
120+
"@babel/helper-validator-option" "^7.18.6"
121+
browserslist "^4.20.2"
122+
semver "^6.3.0"
123+
79124
"@babel/helper-environment-visitor@^7.18.6":
80125
version "7.18.6"
81126
resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.6.tgz#b7eee2b5b9d70602e59d1a6cad7dd24de7ca6cd7"
82127
integrity sha512-8n6gSfn2baOY+qlp+VSzsosjCVGFqWKmDF0cCWOybh52Dw3SEyoWR1KrhMJASjLwIEkkAufZ0xvr+SxLHSpy2Q==
83128

129+
"@babel/helper-environment-visitor@^7.18.9":
130+
version "7.18.9"
131+
resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be"
132+
integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==
133+
84134
"@babel/helper-function-name@^7.18.6":
85135
version "7.18.6"
86136
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.6.tgz#8334fecb0afba66e6d87a7e8c6bb7fed79926b83"
@@ -89,6 +139,14 @@
89139
"@babel/template" "^7.18.6"
90140
"@babel/types" "^7.18.6"
91141

142+
"@babel/helper-function-name@^7.18.9":
143+
version "7.18.9"
144+
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0"
145+
integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==
146+
dependencies:
147+
"@babel/template" "^7.18.6"
148+
"@babel/types" "^7.18.9"
149+
92150
"@babel/helper-hoist-variables@^7.18.6":
93151
version "7.18.6"
94152
resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678"
@@ -117,6 +175,20 @@
117175
"@babel/traverse" "^7.18.6"
118176
"@babel/types" "^7.18.6"
119177

178+
"@babel/helper-module-transforms@^7.18.9":
179+
version "7.18.9"
180+
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712"
181+
integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==
182+
dependencies:
183+
"@babel/helper-environment-visitor" "^7.18.9"
184+
"@babel/helper-module-imports" "^7.18.6"
185+
"@babel/helper-simple-access" "^7.18.6"
186+
"@babel/helper-split-export-declaration" "^7.18.6"
187+
"@babel/helper-validator-identifier" "^7.18.6"
188+
"@babel/template" "^7.18.6"
189+
"@babel/traverse" "^7.18.9"
190+
"@babel/types" "^7.18.9"
191+
120192
"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0":
121193
version "7.14.5"
122194
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9"
@@ -155,6 +227,15 @@
155227
"@babel/traverse" "^7.18.6"
156228
"@babel/types" "^7.18.6"
157229

230+
"@babel/helpers@^7.18.9":
231+
version "7.18.9"
232+
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9"
233+
integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==
234+
dependencies:
235+
"@babel/template" "^7.18.6"
236+
"@babel/traverse" "^7.18.9"
237+
"@babel/types" "^7.18.9"
238+
158239
"@babel/highlight@^7.18.6":
159240
version "7.18.6"
160241
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf"
@@ -169,6 +250,11 @@
169250
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.6.tgz#845338edecad65ebffef058d3be851f1d28a63bc"
170251
integrity sha512-uQVSa9jJUe/G/304lXspfWVpKpK4euFLgGiMQFOCpM/bgcAdeoHwi/OQz23O9GK2osz26ZiXRRV9aV+Yl1O8tw==
171252

253+
"@babel/parser@^7.18.9":
254+
version "7.18.9"
255+
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.9.tgz#f2dde0c682ccc264a9a8595efd030a5cc8fd2539"
256+
integrity sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==
257+
172258
"@babel/plugin-syntax-async-generators@^7.8.4":
173259
version "7.8.4"
174260
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d"
@@ -292,6 +378,22 @@
292378
debug "^4.1.0"
293379
globals "^11.1.0"
294380

381+
"@babel/traverse@^7.18.9":
382+
version "7.18.9"
383+
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.9.tgz#deeff3e8f1bad9786874cb2feda7a2d77a904f98"
384+
integrity sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg==
385+
dependencies:
386+
"@babel/code-frame" "^7.18.6"
387+
"@babel/generator" "^7.18.9"
388+
"@babel/helper-environment-visitor" "^7.18.9"
389+
"@babel/helper-function-name" "^7.18.9"
390+
"@babel/helper-hoist-variables" "^7.18.6"
391+
"@babel/helper-split-export-declaration" "^7.18.6"
392+
"@babel/parser" "^7.18.9"
393+
"@babel/types" "^7.18.9"
394+
debug "^4.1.0"
395+
globals "^11.1.0"
396+
295397
"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.3.0", "@babel/types@^7.3.3":
296398
version "7.18.6"
297399
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.6.tgz#5d781dd10a3f0c9f1f931bd19de5eb26ec31acf0"
@@ -300,6 +402,14 @@
300402
"@babel/helper-validator-identifier" "^7.18.6"
301403
to-fast-properties "^2.0.0"
302404

405+
"@babel/types@^7.18.9":
406+
version "7.18.9"
407+
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.9.tgz#7148d64ba133d8d73a41b3172ac4b83a1452205f"
408+
integrity sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg==
409+
dependencies:
410+
"@babel/helper-validator-identifier" "^7.18.6"
411+
to-fast-properties "^2.0.0"
412+
303413
"@bcoe/v8-coverage@^0.2.3":
304414
version "0.2.3"
305415
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
@@ -730,6 +840,15 @@
730840
"@jridgewell/sourcemap-codec" "^1.4.10"
731841
"@jridgewell/trace-mapping" "^0.3.9"
732842

843+
"@jridgewell/gen-mapping@^0.3.2":
844+
version "0.3.2"
845+
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9"
846+
integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==
847+
dependencies:
848+
"@jridgewell/set-array" "^1.0.1"
849+
"@jridgewell/sourcemap-codec" "^1.4.10"
850+
"@jridgewell/trace-mapping" "^0.3.9"
851+
733852
"@jridgewell/resolve-uri@^3.0.3":
734853
version "3.0.7"
735854
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz#30cd49820a962aff48c8fffc5cd760151fca61fe"
@@ -740,6 +859,11 @@
740859
resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.1.tgz#36a6acc93987adcf0ba50c66908bd0b70de8afea"
741860
integrity sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==
742861

862+
"@jridgewell/set-array@^1.0.1":
863+
version "1.1.2"
864+
resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
865+
integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
866+
743867
"@jridgewell/sourcemap-codec@^1.4.10":
744868
version "1.4.13"
745869
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz#b6461fb0c2964356c469e115f504c95ad97ab88c"

0 commit comments

Comments
 (0)