Skip to content

Commit 206a6ac

Browse files
authored
Import Npm Package from CDN Refactor (#1623)
* importName eval * Update lib/eval/import-eval-path.ts
1 parent c62a673 commit 206a6ac

File tree

3 files changed

+34
-60
lines changed

3 files changed

+34
-60
lines changed

lib/eval/import-eval-path.ts

Lines changed: 29 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { importSnippet } from "./import-snippet"
44
import { resolveFilePath } from "lib/runner/resolveFilePath"
55
import { resolveNodeModule } from "lib/utils/resolve-node-module"
66
import { importNodeModule } from "./import-node-module"
7-
import { importNpmPackage } from "./import-npm-package"
7+
import { importNpmPackageFromCdn } from "./import-npm-package-from-cdn"
88
import {
99
getTsConfig,
1010
matchesTsconfigPathPattern,
@@ -24,7 +24,6 @@ export async function importEvalPath(
2424
depth = 0,
2525
opts: {
2626
cwd?: string
27-
fromJsDelivr?: boolean
2827
} = {},
2928
) {
3029
debug("importEvalPath called with:", {
@@ -97,12 +96,8 @@ export async function importEvalPath(
9796
`Cannot find module "${pkgName}". The package is not available in the local environment.\n\n${ctx.logger.stringifyLogs()}`,
9897
)
9998
}
100-
ctx.logger.info(`importNpmPackage("${pkgName}")`)
101-
// /npm/ paths are always transitive dependencies from jsDelivr
102-
await importNpmPackage(
103-
{ importName: pkgName, depth, fromJsDelivr: true },
104-
ctx,
105-
)
99+
ctx.logger.info(`importNpmPackageFromCdn("${pkgName}")`)
100+
await importNpmPackageFromCdn({ importName: pkgName, depth }, ctx)
106101
const pkg = preSuppliedImports[pkgName]
107102
if (pkg) {
108103
preSuppliedImports[importName] = pkg
@@ -198,41 +193,38 @@ export async function importEvalPath(
198193
}
199194

200195
if (!importName.startsWith(".") && !importName.startsWith("/")) {
201-
// Validation steps for node modules (before jsDelivr fallback)
202-
if (!opts.fromJsDelivr) {
203-
// Step 1: Check if package is declared in package.json
204-
if (!isPackageDeclaredInPackageJson(importName, ctx.fsMap)) {
205-
throw new Error(
206-
`Node module imported but not in package.json "${importName}"\n\n${ctx.logger.stringifyLogs()}`,
207-
)
208-
}
196+
// Step 1: Check if package is declared in package.json
197+
if (!isPackageDeclaredInPackageJson(importName, ctx.fsMap)) {
198+
throw new Error(
199+
`Node module imported but not in package.json "${importName}"\n\n${ctx.logger.stringifyLogs()}`,
200+
)
201+
}
209202

210-
// Step 2: Check if node_modules directory exists (only if not found locally yet)
211-
// Only validate if CDN loading is disabled (i.e., no fallback to jsDelivr available)
212-
const nodeModuleDir = getNodeModuleDirectory(importName, ctx.fsMap)
213-
if (!nodeModuleDir && disableCdnLoading) {
203+
// Step 2: Check if node_modules directory exists (only if not found locally yet)
204+
// Only validate if CDN loading is disabled (i.e., no fallback to jsDelivr available)
205+
const nodeModuleDir = getNodeModuleDirectory(importName, ctx.fsMap)
206+
if (!nodeModuleDir && disableCdnLoading) {
207+
throw new Error(
208+
`Node module "${importName}" has no files in the node_modules directory\n\n${ctx.logger.stringifyLogs()}`,
209+
)
210+
}
211+
212+
// Step 3: Check if main entrypoint is a TypeScript file (only if dir exists)
213+
if (nodeModuleDir) {
214+
const entrypoint = getPackageJsonEntrypoint(importName, ctx.fsMap)
215+
if (isTypeScriptEntrypoint(entrypoint)) {
214216
throw new Error(
215-
`Node module "${importName}" has no files in the node_modules directory\n\n${ctx.logger.stringifyLogs()}`,
217+
`Node module "${importName}" has a typescript entrypoint that is unsupported\n\n${ctx.logger.stringifyLogs()}`,
216218
)
217219
}
218220

219-
// Step 3: Check if main entrypoint is a TypeScript file (only if dir exists)
220-
if (nodeModuleDir) {
221-
const entrypoint = getPackageJsonEntrypoint(importName, ctx.fsMap)
222-
if (isTypeScriptEntrypoint(entrypoint)) {
221+
// Step 4: Check if dist directory is empty when main points to dist
222+
if (entrypoint?.startsWith("dist/")) {
223+
if (isDistDirEmpty(importName, ctx.fsMap)) {
223224
throw new Error(
224-
`Node module "${importName}" has a typescript entrypoint that is unsupported\n\n${ctx.logger.stringifyLogs()}`,
225+
`Node module "${importName}" has no files in dist, did you forget to transpile?\n\n${ctx.logger.stringifyLogs()}`,
225226
)
226227
}
227-
228-
// Step 4: Check if dist directory is empty when main points to dist
229-
if (entrypoint && entrypoint.startsWith("dist/")) {
230-
if (isDistDirEmpty(importName, ctx.fsMap)) {
231-
throw new Error(
232-
`Node module "${importName}" has no files in dist, did you forget to transpile?\n\n${ctx.logger.stringifyLogs()}`,
233-
)
234-
}
235-
}
236228
}
237229
}
238230

@@ -241,11 +233,8 @@ export async function importEvalPath(
241233
`Cannot find module "${importName}". The package is not available in the local environment.\n\n${ctx.logger.stringifyLogs()}`,
242234
)
243235
}
244-
ctx.logger.info(`importNpmPackage("${importName}")`)
245-
return importNpmPackage(
246-
{ importName, depth, fromJsDelivr: opts.fromJsDelivr },
247-
ctx,
248-
)
236+
ctx.logger.info(`importNpmPackageFromCdn("${importName}")`)
237+
return importNpmPackageFromCdn({ importName, depth }, ctx)
249238
}
250239

251240
throw new Error(

lib/eval/import-npm-package.ts renamed to lib/eval/import-npm-package-from-cdn.ts

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import Debug from "debug"
55
import { getImportsFromCode } from "lib/utils/get-imports-from-code"
66
import { importEvalPath } from "./import-eval-path"
77
import { transformWithSucrase } from "lib/transpile/transform-with-sucrase"
8-
import { isPackageDeclaredInPackageJson } from "./isPackageDeclaredInPackageJson"
98

109
const debug = Debug("tsci:eval:import-npm-package")
1110

@@ -17,28 +16,15 @@ function extractPackagePathFromJSDelivr(url: string) {
1716
return url
1817
}
1918

20-
export async function importNpmPackage(
21-
{
22-
importName,
23-
depth = 0,
24-
fromJsDelivr = false,
25-
}: { importName: string; depth?: number; fromJsDelivr?: boolean },
19+
export async function importNpmPackageFromCdn(
20+
{ importName, depth = 0 }: { importName: string; depth?: number },
2621
ctx: ExecutionContext,
2722
) {
28-
debug(`importing npm package: ${importName}`)
29-
const { preSuppliedImports, fsMap } = ctx
23+
debug(`importing npm package from CDN: ${importName}`)
24+
const { preSuppliedImports } = ctx
3025

3126
if (preSuppliedImports[importName]) return
3227

33-
// Check if the package is declared in package.json before fetching from jsDelivr
34-
// Skip this check for transitive dependencies (sub-imports from jsDelivr packages)
35-
if (!fromJsDelivr && !isPackageDeclaredInPackageJson(importName, fsMap)) {
36-
throw new Error(
37-
`Package "${importName}" is not declared in package.json. ` +
38-
`Add it to dependencies or devDependencies before importing.\n\n${ctx.logger.stringifyLogs()}`,
39-
)
40-
}
41-
4228
const npmCdnUrl = `https://cdn.jsdelivr.net/npm/${importName}/+esm`
4329

4430
let finalUrl: string | undefined
@@ -67,7 +53,6 @@ export async function importNpmPackage(
6753
if (!preSuppliedImports[subImportName]) {
6854
await importEvalPath(subImportName, ctx, depth + 1, {
6955
cwd,
70-
fromJsDelivr: true,
7156
})
7257
}
7358
}

lib/eval/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export { importEvalPath } from "./import-eval-path"
1010
export { importLocalFile } from "./import-local-file"
1111
export { importSnippet } from "./import-snippet"
1212
export { importNodeModule } from "./import-node-module"
13-
export { importNpmPackage } from "./import-npm-package"
13+
export { importNpmPackageFromCdn as importNpmPackage } from "./import-npm-package-from-cdn"
1414
export { evalCompiledJs } from "./eval-compiled-js"
1515
export { transformWithSucrase } from "lib/transpile/transform-with-sucrase"
1616
export { extractBasePackageName } from "./extractBasePackageName"

0 commit comments

Comments
 (0)