Skip to content

Commit 894cdd3

Browse files
authored
import react locally (#320)
* import react locally * load react types from typecell * remove comment * fix css types * fix logs
1 parent a294d2f commit 894cdd3

File tree

2 files changed

+67
-35
lines changed

2 files changed

+67
-35
lines changed

packages/editor/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,11 @@
100100
},
101101
"scripts": {
102102
"copytypes:self": "rimraf public/types && tsc --declaration --stripInternal --emitDeclarationOnly --noEmit false --declarationDir public/types/@typecell-org/editor",
103+
"copytypes:externaldep": "mkdir -p public/types/$npm_config_pkgname && cp -rf ../../node_modules/$npm_config_pkgname/. public/types/$npm_config_pkgname",
104+
"copytypes:allexternaldeps": "npm run copytypes:externaldep --pkgname=@types/react && npm run copytypes:externaldep --pkgname=@types/scheduler && npm run copytypes:externaldep --pkgname=@types/prop-types",
103105
"copytypes:dep": "mkdir -p public/types/@typecell-org/$npm_config_pkgname && cp -rf ../$npm_config_pkgname/types/. public/types/@typecell-org/$npm_config_pkgname",
104106
"copytypes:alldeps": "npm run copytypes:dep --pkgname=common && npm run copytypes:dep --pkgname=engine",
105-
"copytypes": "npm run copytypes:self && npm run copytypes:alldeps",
107+
"copytypes": "npm run copytypes:self && npm run copytypes:alldeps && npm run copytypes:allexternaldeps",
106108
"start": "npm run copytypes && npm run vite:dev",
107109
"start:local": "npm run copytypes && cross-env VITE_REACT_APP_HOMESERVER_URI=http://localhost:8888 VITE_REACT_APP_HOMESERVER_NAME=test.typecell.org npm run vite:dev",
108110
"copy-docs": "rimraf public/_docs && mkdir public/_docs && node copy-docs.mjs > public/_docs/index.json && cp -rf ../../docs/. public/_docs",

packages/editor/src/runtime/editor/languages/typescript/typeAcquisition.ts

Lines changed: 64 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -165,24 +165,44 @@ const convertToModuleReferenceID = (
165165
}
166166
};
167167

168-
const addTypecellModuleToRuntime = async (
168+
const builtInModules = ["react", "scheduler", "prop-types", "csstype"];
169+
170+
const isBuiltInModule = (mod: string) => {
171+
const mainMod = mod.split("/")[0] || mod;
172+
return builtInModules.includes(mainMod);
173+
};
174+
175+
const addBuiltInTypesToRuntime = async (
169176
mod: string,
170177
path: string,
171178
config: ATAConfig
172179
) => {
173-
const typecellPath = mod === "typecell" ? "@typecell-org/editor" : mod;
180+
let typePath = mod;
174181

175-
let content: string;
182+
if (mod === "typecell") {
183+
typePath = "@typecell-org/editor";
184+
} else if (isBuiltInModule(mod)) {
185+
if (mod === "csstype") {
186+
typePath = "@types/react/node_modules/csstype"; // TODO: would be better to have 1 version of csstype, and in @types/csstype
187+
} else {
188+
typePath = "@types/" + mod;
189+
}
190+
} else if (mod.startsWith("@typecell-org")) {
191+
typePath = mod;
192+
} else {
193+
throw new Error("unknown local type module");
194+
}
195+
196+
let content: string | void;
176197
if (import.meta.env.NODE_ENV === "test") {
177198
// TODO: extract this case
178199
let fs = require("fs");
179-
content = fs.readFileSync(
180-
"public/types/" + typecellPath + "/" + path,
181-
"utf-8"
182-
);
200+
content = fs.readFileSync("public/types/" + typePath + "/" + path, "utf-8");
183201
} else {
184-
const url = new URL("/types/" + typecellPath + "/" + path, import.meta.url);
185-
content = await (await config.fetcher(url.toString())).text();
202+
const url = new URL("/types/" + typePath + "/" + path, import.meta.url);
203+
// console.log("RESOLVE", mod, url.toString(), path);
204+
content = await getCachedDTSString(config, url.toString());
205+
// content = await (await config.fetcher(url.toString())).text();
186206
}
187207
if (!content) {
188208
return errorMsg(
@@ -194,7 +214,10 @@ const addTypecellModuleToRuntime = async (
194214
// Now look and grab dependent modules where you need the
195215
await getDependenciesForModule(content, mod, path, config);
196216

197-
config.logger.log("adding typecell module", path);
217+
config.logger.log(
218+
"adding typecell module",
219+
`file:///node_modules/@types/${mod}/${path}`
220+
);
198221
config.addLibraryToRuntime(
199222
content,
200223
`file:///node_modules/@types/${mod}/${path}`
@@ -260,6 +283,7 @@ const getModuleAndRootDefTypePath = async (
260283
const url = moduleJSONURL(packageName);
261284

262285
const response = await config.fetcher(url);
286+
263287
if (!response.ok) {
264288
return errorMsg(
265289
`Could not get Algolia JSON for the module '${packageName}'`,
@@ -366,6 +390,7 @@ const getCachedDTSString = async (config: ATAConfig, url: string) => {
366390
}
367391

368392
const response = await config.fetcher(url);
393+
369394
if (!response.ok) {
370395
return errorMsg(
371396
`Could not get DTS response for the module at ${url}`,
@@ -374,6 +399,10 @@ const getCachedDTSString = async (config: ATAConfig, url: string) => {
374399
);
375400
}
376401

402+
if (response.headers.get("content-type") === "text/html") {
403+
// this happens when the file is not found, and the server is returning a dynamic route (html fallback) instead
404+
console.warn(`possibly wrong file for typescript types at ${url}`);
405+
}
377406
// TODO: handle checking for a resolve to index.d.ts whens someone imports the folder
378407
let content = await response.text();
379408
if (!content) {
@@ -407,6 +436,10 @@ const getReferenceDependencies = async (
407436
if (relativePath) {
408437
let newPath = mapRelativePath(relativePath, path);
409438
if (newPath) {
439+
if (isBuiltInModule(mod)) {
440+
await addBuiltInTypesToRuntime(mod, newPath, config);
441+
return;
442+
}
410443
const dtsRefURL = unpkgURL(mod, newPath);
411444

412445
const dtsReferenceResponseText = await getCachedDTSString(
@@ -519,18 +552,19 @@ const getDependenciesForModule = async (
519552
moduleToDownload.split("/").length === 1;
520553
const isPackageRootImport = modIsPackageOnly || modIsScopedPackageOnly;
521554
const isDenoModule = moduleToDownload.indexOf("https://") === 0;
522-
555+
const isPackageSpecificFileImport =
556+
!isPackageRootImport &&
557+
!moduleToDownload.startsWith(".") &&
558+
moduleToDownload.includes("/"); // absolute path
523559
if (moduleToDownload.startsWith("!@")) {
524560
// typecell imports are loaded in TypecellTypeResolver
525561
return;
526562
// config.addLibraryToRuntime(code.dtsCode, moduleToDownload+".d.ts");
527563
} else if (isPackageRootImport) {
528564
if (moduleToDownload.startsWith("@typecell-org/")) {
529-
await addTypecellModuleToRuntime(
530-
moduleToDownload,
531-
"index.d.ts",
532-
config
533-
);
565+
await addBuiltInTypesToRuntime(moduleToDownload, "index.d.ts", config);
566+
} else if (builtInModules.includes(moduleToDownload)) {
567+
await addBuiltInTypesToRuntime(moduleToDownload, "index.d.ts", config);
534568
} else {
535569
// So it doesn't run twice for a package
536570
acquiredTypeDefs[moduleID] = null;
@@ -549,22 +583,16 @@ const getDependenciesForModule = async (
549583
} else if (isDenoModule) {
550584
// E.g. import { serve } from "https://deno.land/[email protected]/http/server.ts";
551585
await addModuleToRuntime(moduleToDownload, moduleToDownload, config);
552-
// TODO: Possible fix for scheduler/tracing, but not critical / should file with original repo
553-
// } else if (
554-
// !moduleToDownload.startsWith(".") &&
555-
// moduleToDownload.includes("/")
556-
// ) {
557-
// const parts = moduleToDownload.split("/", 2);
558-
// const packageDef = await getModuleAndRootDefTypePath(parts[0], config);
559-
560-
// if (packageDef) {
561-
// acquiredTypeDefs[moduleID] = packageDef.packageJSON;
562-
// const absolutePathForModule = mapRelativePath(
563-
// parts[1] + ".d.ts",
564-
// packageDef.path
565-
// );
566-
// await addModuleToRuntime(packageDef.mod, absolutePathForModule, config);
567-
// }
586+
} else if (isPackageSpecificFileImport) {
587+
// fix for scheduler/tracing
588+
const parts = moduleToDownload.split("/", 2);
589+
const modname = parts[0];
590+
const pathName = parts[1] + ".d.ts";
591+
if (isBuiltInModule(moduleName!)) {
592+
await addBuiltInTypesToRuntime(modname, pathName, config);
593+
} else {
594+
await addModuleToRuntime(modname, pathName, config);
595+
}
568596
} else {
569597
// E.g. import {Component} from "./MyThing"
570598
if (!moduleToDownload || !path)
@@ -594,14 +622,16 @@ const getDependenciesForModule = async (
594622
moduleName?.startsWith("typecell") ||
595623
moduleName?.startsWith("@typecell-org/")
596624
) {
597-
await addTypecellModuleToRuntime(moduleName!, resolvedFilepath, config);
625+
await addBuiltInTypesToRuntime(moduleName!, resolvedFilepath, config);
626+
} else if (isBuiltInModule(moduleName!)) {
627+
await addBuiltInTypesToRuntime(moduleName!, resolvedFilepath, config);
598628
} else {
599629
await addModuleToRuntime(moduleName!, resolvedFilepath, config);
600630
}
601631
}
602632
});
603633

604-
// Also support the
634+
// Also support the <reference> comments
605635
promises.push(
606636
getReferenceDependencies(sourceCode, moduleName!, path!, config)
607637
);

0 commit comments

Comments
 (0)