From af2db63a1f2a71682932aa8e3566e70b88477bcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Israel=20Rold=C3=A1n?= Date: Wed, 22 Apr 2020 19:09:13 +0200 Subject: [PATCH] Check if `web_modules/import-map.json` exists and check it before resolving from `node_modules` --- src/server/plugins/modules.ts | 38 ++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/server/plugins/modules.ts b/src/server/plugins/modules.ts index 21837e5aea517a..a938c18ffbff1a 100644 --- a/src/server/plugins/modules.ts +++ b/src/server/plugins/modules.ts @@ -6,9 +6,11 @@ import { Readable } from 'stream' import { init as initLexer, parse } from 'es-module-lexer' import MagicString from 'magic-string' import { cachedRead } from '../utils' +import { promises as fs } from 'fs' const idToFileMap = new Map() const fileToIdMap = new Map() +const webModulesMap = new Map() export const modulesPlugin: Plugin = ({ root, app }) => { // rewrite named module imports to `/__modules/:id` requests @@ -99,7 +101,18 @@ export const modulesPlugin: Plugin = ({ root, app }) => { } } - // TODO support resolving from Snowpack's web_modules + try { + const webModulePath = await resolveWebModule(root, id) + if (webModulePath) { + idToFileMap.set(id, webModulePath) + fileToIdMap.set(path.basename(webModulePath), id) + ctx.body = await cachedRead(webModulePath) + return + } + } catch (e) { + console.error(e) + ctx.status = 404 + } // resolve from node_modules try { @@ -135,6 +148,29 @@ async function readBody(stream: Readable | string): Promise { } } +async function resolveWebModule( + root: string, + id: string +): Promise { + const webModulePath = webModulesMap.get(id) + if (webModulePath) { + return webModulePath + } + const importMapPath = path.join(root, 'web_modules', 'import-map.json') + if (await fs.stat(importMapPath).catch((e) => false)) { + const importMap = require(importMapPath) + if (importMap.imports) { + const webModulesDir = path.dirname(importMapPath) + Object.entries( + importMap.imports + ).forEach(([key, val]: [string, string]) => + webModulesMap.set(key, path.join(webModulesDir, val)) + ) + return webModulesMap.get(id) + } + } +} + // while we lex the files for imports we also build a import graph // so that we can determine what files to hot reload export const importerMap = new Map>()