diff options
author | 2021-04-19 14:41:06 -0400 | |
---|---|---|
committer | 2021-04-19 14:41:06 -0400 | |
commit | eb984559a89b4f0b09c42604a18f1198c8d7ecca (patch) | |
tree | 5bcf0ea7c136733aa39c6dffc3d9b31d77dde719 /src | |
parent | 188541260acad5ccd6699f0a21d6da600860e74c (diff) | |
download | astro-eb984559a89b4f0b09c42604a18f1198c8d7ecca.tar.gz astro-eb984559a89b4f0b09c42604a18f1198c8d7ecca.tar.zst astro-eb984559a89b4f0b09c42604a18f1198c8d7ecca.zip |
Fix dynamic React components (#111)
Another change in snowpack@3 caused this bug. It's not actually a bug in snowpack. Previously snowpack was keeping its list of installed packages in a global cache. In 3.3 it stopped doing so. We were accidentally relying on that global cache to be able to resolve dynamic components.
This fixes it so that we use the frontend snowpack instance to resolve dynamic components. Doing so means they are available when we try to load them.
Diffstat (limited to 'src')
-rw-r--r-- | src/@types/compiler.ts | 2 | ||||
-rw-r--r-- | src/build.ts | 4 | ||||
-rw-r--r-- | src/build/bundle.ts | 18 | ||||
-rw-r--r-- | src/compiler/codegen/index.ts | 12 | ||||
-rw-r--r-- | src/runtime.ts | 34 |
5 files changed, 42 insertions, 28 deletions
diff --git a/src/@types/compiler.ts b/src/@types/compiler.ts index 2f104b5c5..7da0afaf2 100644 --- a/src/@types/compiler.ts +++ b/src/@types/compiler.ts @@ -3,7 +3,7 @@ import type { AstroConfig, RuntimeMode, ValidExtensionPlugins } from './astro'; export interface CompileOptions { logging: LogOptions; - resolve: (p: string) => Promise<string>; + resolvePackageUrl: (p: string) => Promise<string>; astroConfig: AstroConfig; extensions?: Record<string, ValidExtensionPlugins>; mode: RuntimeMode; diff --git a/src/build.ts b/src/build.ts index a66d49ffa..93314da7a 100644 --- a/src/build.ts +++ b/src/build.ts @@ -155,11 +155,11 @@ export async function build(astroConfig: AstroConfig): Promise<0 | 1> { const runtime = await createRuntime(astroConfig, { mode, logging: runtimeLogging }); const { runtimeConfig } = runtime; const { backendSnowpack: snowpack } = runtimeConfig; - const resolve = (pkgName: string) => snowpack.getUrlForPackage(pkgName); + const resolvePackageUrl = (pkgName: string) => snowpack.getUrlForPackage(pkgName); const imports = new Set<string>(); const statics = new Set<string>(); - const collectImportsOptions = { astroConfig, logging, resolve, mode }; + const collectImportsOptions = { astroConfig, logging, resolvePackageUrl, mode }; const pages = await allPages(pageRoot); diff --git a/src/build/bundle.ts b/src/build/bundle.ts index 0a5961986..681bea3b2 100644 --- a/src/build/bundle.ts +++ b/src/build/bundle.ts @@ -23,21 +23,21 @@ const { readFile } = fsPromises; type DynamicImportMap = Map<'vue' | 'react' | 'react-dom' | 'preact', string>; /** Add framework runtimes when needed */ -async function acquireDynamicComponentImports(plugins: Set<ValidExtensionPlugins>, resolve: (s: string) => Promise<string>): Promise<DynamicImportMap> { +async function acquireDynamicComponentImports(plugins: Set<ValidExtensionPlugins>, resolvePackageUrl: (s: string) => Promise<string>): Promise<DynamicImportMap> { const importMap: DynamicImportMap = new Map(); for (let plugin of plugins) { switch (plugin) { case 'vue': { - importMap.set('vue', await resolve('vue')); + importMap.set('vue', await resolvePackageUrl('vue')); break; } case 'react': { - importMap.set('react', await resolve('react')); - importMap.set('react-dom', await resolve('react-dom')); + importMap.set('react', await resolvePackageUrl('react')); + importMap.set('react-dom', await resolvePackageUrl('react-dom')); break; } case 'preact': { - importMap.set('preact', await resolve('preact')); + importMap.set('preact', await resolvePackageUrl('preact')); break; } } @@ -64,13 +64,13 @@ const defaultExtensions: Readonly<Record<string, ValidExtensionPlugins>> = { interface CollectDynamic { astroConfig: AstroConfig; - resolve: (s: string) => Promise<string>; + resolvePackageUrl: (s: string) => Promise<string>; logging: LogOptions; mode: RuntimeMode; } /** Gather necessary framework runtimes for dynamic components */ -export async function collectDynamicImports(filename: URL, { astroConfig, logging, resolve, mode }: CollectDynamic) { +export async function collectDynamicImports(filename: URL, { astroConfig, logging, resolvePackageUrl, mode }: CollectDynamic) { const imports = new Set<string>(); // Only astro files @@ -98,7 +98,7 @@ export async function collectDynamicImports(filename: URL, { astroConfig, loggin fileID: '', compileOptions: { astroConfig, - resolve, + resolvePackageUrl, logging, mode, }, @@ -135,7 +135,7 @@ export async function collectDynamicImports(filename: URL, { astroConfig, loggin }; } - const dynamic = await acquireDynamicComponentImports(plugins, resolve); + const dynamic = await acquireDynamicComponentImports(plugins, resolvePackageUrl); /** Add dynamic component runtimes to imports */ function appendImports(rawName: string, importUrl: URL) { diff --git a/src/compiler/codegen/index.ts b/src/compiler/codegen/index.ts index d3e8a45dd..8d968e1ea 100644 --- a/src/compiler/codegen/index.ts +++ b/src/compiler/codegen/index.ts @@ -258,21 +258,21 @@ function compileExpressionSafe(raw: string): string { } /** Build dependency map of dynamic component runtime frameworks */ -async function acquireDynamicComponentImports(plugins: Set<ValidExtensionPlugins>, resolve: (s: string) => Promise<string>): Promise<DynamicImportMap> { +async function acquireDynamicComponentImports(plugins: Set<ValidExtensionPlugins>, resolvePackageUrl: (s: string) => Promise<string>): Promise<DynamicImportMap> { const importMap: DynamicImportMap = new Map(); for (let plugin of plugins) { switch (plugin) { case 'vue': { - importMap.set('vue', await resolve('vue')); + importMap.set('vue', await resolvePackageUrl('vue')); break; } case 'react': { - importMap.set('react', await resolve('react')); - importMap.set('react-dom', await resolve('react-dom')); + importMap.set('react', await resolvePackageUrl('react')); + importMap.set('react-dom', await resolvePackageUrl('react-dom')); break; } case 'preact': { - importMap.set('preact', await resolve('preact')); + importMap.set('preact', await resolvePackageUrl('preact')); break; } } @@ -643,7 +643,7 @@ export async function codegen(ast: Ast, { compileOptions, filename }: CodeGenOpt }; const { script, componentPlugins, createCollection } = compileModule(ast.module, state, compileOptions); - state.dynamicImports = await acquireDynamicComponentImports(componentPlugins, compileOptions.resolve); + state.dynamicImports = await acquireDynamicComponentImports(componentPlugins, compileOptions.resolvePackageUrl); compileCss(ast.css, state); diff --git a/src/runtime.ts b/src/runtime.ts index 99f4d9682..40fa1dce2 100644 --- a/src/runtime.ts +++ b/src/runtime.ts @@ -230,20 +230,27 @@ interface RuntimeOptions { } /** Create a new Snowpack instance to power Astro */ -async function createSnowpack(astroConfig: AstroConfig, env: Record<string, any>, mode: RuntimeMode) { +interface CreateSnowpackOptions { + env: Record<string, any>; + mode: RuntimeMode; + resolvePackageUrl?: (pkgName: string) => Promise<string>; +} + +async function createSnowpack(astroConfig: AstroConfig, options: CreateSnowpackOptions) { const { projectRoot, astroRoot, extensions } = astroConfig; + const { env, mode, resolvePackageUrl } = options; const internalPath = new URL('./frontend/', import.meta.url); let snowpack: SnowpackDevServer; const astroPlugOptions: { - resolve?: (s: string) => Promise<string>; + resolvePackageUrl?: (s: string) => Promise<string>; extensions?: Record<string, string>; astroConfig: AstroConfig; } = { astroConfig, extensions, - resolve: async (pkgName: string) => snowpack.getUrlForPackage(pkgName), + resolvePackageUrl, }; const mountOptions = { @@ -258,7 +265,7 @@ async function createSnowpack(astroConfig: AstroConfig, env: Record<string, any> const snowpackConfig = await loadConfiguration({ root: fileURLToPath(projectRoot), mount: mountOptions, - mode: mode, + mode, plugins: [ [fileURLToPath(new URL('../snowpack-plugin.cjs', import.meta.url)), astroPlugOptions], require.resolve('@snowpack/plugin-sass'), @@ -293,20 +300,27 @@ async function createSnowpack(astroConfig: AstroConfig, env: Record<string, any> /** Core Astro runtime */ export async function createRuntime(astroConfig: AstroConfig, { mode, logging }: RuntimeOptions): Promise<AstroRuntime> { + const resolvePackageUrl = async (pkgName: string) => frontendSnowpack.getUrlForPackage(pkgName); + const { snowpack: backendSnowpack, snowpackRuntime: backendSnowpackRuntime, snowpackConfig: backendSnowpackConfig } = await createSnowpack( astroConfig, { - astro: true, - }, - mode + env: { + astro: true + }, + mode, + resolvePackageUrl + } ); const { snowpack: frontendSnowpack, snowpackRuntime: frontendSnowpackRuntime, snowpackConfig: frontendSnowpackConfig } = await createSnowpack( astroConfig, { - astro: false, - }, - mode + env: { + astro: false + }, + mode + } ); const runtimeConfig: RuntimeConfig = { |