diff options
author | 2021-03-30 15:06:43 -0400 | |
---|---|---|
committer | 2021-03-30 15:06:43 -0400 | |
commit | 4a732837cdd1ad5493a25ae58612e9b6a302c651 (patch) | |
tree | 724af4f76202d6615a6969cd2d2bd7e3723c3d4f /src | |
parent | 7334a550d8e042ae0dc59519149df2b3ad04f058 (diff) | |
download | astro-4a732837cdd1ad5493a25ae58612e9b6a302c651.tar.gz astro-4a732837cdd1ad5493a25ae58612e9b6a302c651.tar.zst astro-4a732837cdd1ad5493a25ae58612e9b6a302c651.zip |
Resolve component URLs during compilation (#40)
Previously dynamic component URLs were being resolved client-side in a weird way that only worked during dev. This change makes them handle during compilation, so it works in both (and improves readability of the dynamic import output).
Diffstat (limited to '')
-rw-r--r-- | src/@types/compiler.ts | 3 | ||||
-rw-r--r-- | src/compiler/codegen.ts | 25 | ||||
-rw-r--r-- | src/compiler/index.ts | 9 | ||||
-rw-r--r-- | src/frontend/render/renderer.ts | 2 | ||||
-rw-r--r-- | src/runtime.ts | 2 |
5 files changed, 26 insertions, 15 deletions
diff --git a/src/@types/compiler.ts b/src/@types/compiler.ts index 916be22cb..916242c51 100644 --- a/src/@types/compiler.ts +++ b/src/@types/compiler.ts @@ -1,8 +1,9 @@ import type { LogOptions } from '../logger'; -import type { ValidExtensionPlugins } from './astro'; +import type { AstroConfig, ValidExtensionPlugins } from './astro'; export interface CompileOptions { logging: LogOptions; resolve: (p: string) => Promise<string>; + astroConfig: AstroConfig; extensions?: Record<string, ValidExtensionPlugins>; } diff --git a/src/compiler/codegen.ts b/src/compiler/codegen.ts index febb0a514..add38baad 100644 --- a/src/compiler/codegen.ts +++ b/src/compiler/codegen.ts @@ -1,5 +1,5 @@ import type { CompileOptions } from '../@types/compiler'; -import type { ValidExtensionPlugins } from '../@types/astro'; +import type { AstroConfig, ValidExtensionPlugins } from '../@types/astro'; import type { Ast, TemplateNode } from '../parser/interfaces'; import type { JsxItem, TransformResult } from '../@types/astro'; @@ -111,14 +111,25 @@ const defaultExtensions: Readonly<Record<string, ValidExtensionPlugins>> = { type DynamicImportMap = Map<'vue' | 'react' | 'react-dom' | 'preact', string>; -function getComponentWrapper(_name: string, { type, plugin, url }: ComponentInfo, dynamicImports: DynamicImportMap) { +interface GetComponentWrapperOptions { + filename: string; + astroConfig: AstroConfig; + dynamicImports: DynamicImportMap; +} +function getComponentWrapper(_name: string, { type, plugin, url }: ComponentInfo, opts: GetComponentWrapperOptions) { + const { astroConfig, dynamicImports, filename } = opts; + const { astroRoot } = astroConfig; const [name, kind] = _name.split(':'); + const currFileUrl = new URL(`file://${filename}`); if (!plugin) { throw new Error(`No supported plugin found for extension ${type}`); } - const getComponentUrl = (ext = '.js') => `new URL(${JSON.stringify(url.replace(/\.[^.]+$/, ext))}, \`http://TEST\${import.meta.url\}\`).pathname.replace(/^\\/\\//, '/_astro/')`; + const getComponentUrl = (ext = '.js') => { + const outUrl = new URL(url, currFileUrl); + return '/_astro/' + path.posix.relative(astroRoot.pathname, outUrl.pathname).replace(/\.[^.]+$/, ext); + }; switch (plugin) { case 'astro': { @@ -242,8 +253,8 @@ async function acquireDynamicComponentImports(plugins: Set<ValidExtensionPlugins return importMap; } -export async function codegen(ast: Ast, { compileOptions }: CodeGenOptions): Promise<TransformResult> { - const { extensions = defaultExtensions } = compileOptions; +export async function codegen(ast: Ast, { compileOptions, filename }: CodeGenOptions): Promise<TransformResult> { + const { extensions = defaultExtensions, astroConfig } = compileOptions; await eslexer.init; const componentImports: ImportDeclaration[] = []; @@ -343,7 +354,7 @@ export async function codegen(ast: Ast, { compileOptions }: CodeGenOptions): Pro if (!components[componentName]) { throw new Error(`Unknown Component: ${componentName}`); } - const { wrapper, wrapperImport } = getComponentWrapper(name, components[componentName], dynamicImports); + const { wrapper, wrapperImport } = getComponentWrapper(name, components[componentName], {astroConfig, dynamicImports, filename}); if (wrapperImport) { importExportStatements.add(wrapperImport); } @@ -395,7 +406,7 @@ export async function codegen(ast: Ast, { compileOptions }: CodeGenOptions): Pro if (!componentImportData) { throw new Error(`Unknown Component: ${componentName}`); } - const { wrapper, wrapperImport } = getComponentWrapper(name, components[componentName], dynamicImports); + const { wrapper, wrapperImport } = getComponentWrapper(name, components[componentName], {astroConfig, dynamicImports, filename}); if (wrapperImport) { importExportStatements.add(wrapperImport); } diff --git a/src/compiler/index.ts b/src/compiler/index.ts index 945d9bfc5..8104ef4b4 100644 --- a/src/compiler/index.ts +++ b/src/compiler/index.ts @@ -1,4 +1,5 @@ import type { LogOptions } from '../logger.js'; +import type { AstroConfig } from '../@types/astro'; import path from 'path'; import micromark from 'micromark'; @@ -14,15 +15,11 @@ import { optimize } from './optimize/index.js'; import { codegen } from './codegen.js'; interface CompileOptions { + astroConfig: AstroConfig; logging: LogOptions; resolve: (p: string) => Promise<string>; } -const defaultCompileOptions: CompileOptions = { - logging: defaultLogOptions, - resolve: (p: string) => Promise.resolve(p), -}; - function internalImport(internalPath: string) { return `/_astro_internal/${internalPath}`; } @@ -107,7 +104,7 @@ async function transformFromSource( export async function compileComponent( source: string, - { compileOptions = defaultCompileOptions, filename, projectRoot }: { compileOptions: CompileOptions; filename: string; projectRoot: string } + { compileOptions, filename, projectRoot }: { compileOptions: CompileOptions; filename: string; projectRoot: string } ): Promise<CompileResult> { const sourceJsx = await transformFromSource(source, { compileOptions, filename, projectRoot }); const isPage = path.extname(filename) === '.md' || sourceJsx.items.some((item) => item.name === 'html'); diff --git a/src/frontend/render/renderer.ts b/src/frontend/render/renderer.ts index ceb460e40..d7afc0558 100644 --- a/src/frontend/render/renderer.ts +++ b/src/frontend/render/renderer.ts @@ -23,7 +23,7 @@ export function createRenderer(renderer: Renderer) { return [...acc, `import("${context.frameworkUrls[lib as any]}")`]; }, []) .join(','); - return `const [{${context.componentExport}: Component}, ${values}] = await Promise.all([import(${context.componentUrl})${renderer.imports ? ', ' + libs : ''}]);`; + return `const [{${context.componentExport}: Component}, ${values}] = await Promise.all([import("${context.componentUrl}")${renderer.imports ? ', ' + libs : ''}]);`; }; const serializeProps = (props: Record<string, any>) => JSON.stringify(props); const createContext = () => { diff --git a/src/runtime.ts b/src/runtime.ts index 3b2cffefc..42024eff4 100644 --- a/src/runtime.ts +++ b/src/runtime.ts @@ -126,7 +126,9 @@ export async function createRuntime(astroConfig: AstroConfig, { logging }: Runti const astroPlugOptions: { resolve?: (s: string) => Promise<string>; extensions?: Record<string, string>; + astroConfig: AstroConfig; } = { + astroConfig, extensions, resolve: async (pkgName: string) => snowpack.getUrlForPackage(pkgName), }; |