Remove second snowpack instance (#368)

* Remove second snowpack instance

* Document import.meta.env.SSR

* Remove unnecessary Promise.all
This commit is contained in:
Matthew Phillips 2021-06-11 09:03:22 -04:00 committed by GitHub
parent ce9336115e
commit 1bab906539
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 45 additions and 67 deletions

View file

@ -0,0 +1,5 @@
---
'astro': minor
---
Removes a second instance of snowpack which degraded peformance

View file

@ -146,6 +146,24 @@ Astro will generate an RSS 2.0 feed at `/feed/[collection].xml` (for example, `/
<link rel="alternate" type="application/rss+xml" title="My RSS Feed" href="/feed/podcast.xml" />
```
### `import.meta`
All ESM modules include a `import.meta` property. Astro adds `import.meta.env` through [Snowpack](https://www.snowpack.dev/).
__import.meta.env.SSR__ can be used to know when rendering on the server. Some times you might want different logic, for example a component that should only be rendered in the client:
```jsx
import { h } from 'preact';
export default function() {
return (
import.meta.env.SSR ?
<div class="spinner"></div> :
<FancyComponent />
)
}
```
[canonical]: https://en.wikipedia.org/wiki/Canonical_link_element
[config]: ../README.md#%EF%B8%8F-configuration
[docs-collections]: ./collections.md

View file

@ -117,7 +117,7 @@ function PluginSearchPageLive() {
}
export default function PluginSearchPage(props) {
return import.meta.env.astro ? (
return import.meta.env.SSR ? (
<div>Loading...</div>
) : (
<PluginSearchPageLive {...props} />

View file

@ -58,7 +58,7 @@ export async function build(astroConfig: AstroConfig, logging: LogOptions = defa
const mode: RuntimeMode = 'production';
const runtime = await createRuntime(astroConfig, { mode, logging: runtimeLogging });
const { runtimeConfig } = runtime;
const { backendSnowpack: snowpack } = runtimeConfig;
const { snowpack } = runtimeConfig;
try {
// 0. erase build directory

View file

@ -20,12 +20,9 @@ interface RuntimeConfig {
astroConfig: AstroConfig;
logging: LogOptions;
mode: RuntimeMode;
backendSnowpack: SnowpackDevServer;
backendSnowpackRuntime: SnowpackServerRuntime;
backendSnowpackConfig: SnowpackConfig;
frontendSnowpack: SnowpackDevServer;
frontendSnowpackRuntime: SnowpackServerRuntime;
frontendSnowpackConfig: SnowpackConfig;
snowpack: SnowpackDevServer;
snowpackRuntime: SnowpackServerRuntime;
snowpackConfig: SnowpackConfig;
}
// info needed for collection generation
@ -50,7 +47,7 @@ configureSnowpackLogger(snowpackLogger);
/** Pass a URL to Astro to resolve and build */
async function load(config: RuntimeConfig, rawPathname: string | undefined): Promise<LoadResult> {
const { logging, backendSnowpackRuntime, frontendSnowpack } = config;
const { logging, snowpackRuntime, snowpack } = config;
const { pages: pagesRoot, buildOptions, devOptions } = config.astroConfig;
let origin = buildOptions.site ? new URL(buildOptions.site).origin : `http://localhost:${devOptions.port}`;
@ -62,7 +59,7 @@ async function load(config: RuntimeConfig, rawPathname: string | undefined): Pro
const searchResult = searchForPage(fullurl, pagesRoot);
if (searchResult.statusCode === 404) {
try {
const result = await frontendSnowpack.loadUrl(reqPath);
const result = await snowpack.loadUrl(reqPath);
if (!result) throw new Error(`Unable to load ${reqPath}`);
// success
return {
@ -88,7 +85,7 @@ async function load(config: RuntimeConfig, rawPathname: string | undefined): Pro
let rss: { data: any[] & CollectionRSS } = {} as any;
try {
const mod = await backendSnowpackRuntime.importModule(snowpackURL);
const mod = await snowpackRuntime.importModule(snowpackURL);
debug(logging, 'resolve', `${reqPath} -> ${snowpackURL}`);
// handle collection
@ -297,10 +294,8 @@ interface RuntimeOptions {
}
interface CreateSnowpackOptions {
env: Record<string, any>;
mode: RuntimeMode;
resolvePackageUrl?: (pkgName: string) => Promise<string>;
target: 'frontend' | 'backend';
}
const DEFAULT_HMR_PORT = 12321;
@ -309,11 +304,11 @@ const DEFAULT_RENDERERS = ['@astrojs/renderer-vue', '@astrojs/renderer-svelte',
/** Create a new Snowpack instance to power Astro */
async function createSnowpack(astroConfig: AstroConfig, options: CreateSnowpackOptions) {
const { projectRoot, pages: pagesRoot, renderers = DEFAULT_RENDERERS } = astroConfig;
const { env, mode, resolvePackageUrl, target } = options;
const { mode, resolvePackageUrl } = options;
const frontendPath = new URL('./frontend/', import.meta.url);
const resolveDependency = (dep: string) => resolve.sync(dep, { basedir: fileURLToPath(projectRoot) });
const isHmrEnabled = mode === 'development' && target === 'backend';
const isHmrEnabled = mode === 'development';
let snowpack: SnowpackDevServer;
let astroPluginOptions: {
@ -419,9 +414,6 @@ async function createSnowpack(astroConfig: AstroConfig, options: CreateSnowpackO
},
});
const envConfig = snowpackConfig.env || (snowpackConfig.env = {});
Object.assign(envConfig, env);
snowpack = await startSnowpackServer(
{
config: snowpackConfig,
@ -438,53 +430,34 @@ async function createSnowpack(astroConfig: AstroConfig, options: CreateSnowpackO
/** Core Astro runtime */
export async function createRuntime(astroConfig: AstroConfig, { mode, logging }: RuntimeOptions): Promise<AstroRuntime> {
let snowpack: SnowpackDevServer;
const timer: Record<string, number> = {};
const resolvePackageUrl = async (pkgName: string) => frontendSnowpack.getUrlForPackage(pkgName);
const resolvePackageUrl = async (pkgName: string) => snowpack.getUrlForPackage(pkgName);
timer.backend = performance.now();
const {
snowpack: backendSnowpack,
snowpackRuntime: backendSnowpackRuntime,
snowpackConfig: backendSnowpackConfig,
snowpack: snowpackInstance,
snowpackRuntime,
snowpackConfig,
} = await createSnowpack(astroConfig, {
target: 'backend',
env: {
astro: true,
},
mode,
resolvePackageUrl,
});
debug(logging, 'core', `backend snowpack created [${stopTimer(timer.backend)}]`);
timer.frontend = performance.now();
const {
snowpack: frontendSnowpack,
snowpackRuntime: frontendSnowpackRuntime,
snowpackConfig: frontendSnowpackConfig,
} = await createSnowpack(astroConfig, {
target: 'frontend',
env: {
astro: false,
},
mode,
});
debug(logging, 'core', `frontend snowpack created [${stopTimer(timer.frontend)}]`);
snowpack = snowpackInstance;
debug(logging, 'core', `snowpack created [${stopTimer(timer.backend)}]`);
const runtimeConfig: RuntimeConfig = {
astroConfig,
logging,
mode,
backendSnowpack,
backendSnowpackRuntime,
backendSnowpackConfig,
frontendSnowpack,
frontendSnowpackRuntime,
frontendSnowpackConfig,
snowpack,
snowpackRuntime,
snowpackConfig,
};
return {
runtimeConfig,
load: load.bind(null, runtimeConfig),
shutdown: () => Promise.all([backendSnowpack.shutdown(), frontendSnowpack.shutdown()]).then(() => void 0),
shutdown: () => snowpack.shutdown(),
};
}

View file

@ -1,8 +1,6 @@
import { logger as snowpackLogger } from 'snowpack';
import { defaultLogLevel } from './logger.js';
const onceMessages = ['Ready!', 'watching for file changes'].map((str) => new RegExp(`\\[snowpack\\](.*?)${str}`));
const neverWarn = new RegExp(
'(' +
/(run "snowpack init" to create a project config file.)|/.source +
@ -26,20 +24,4 @@ export function configureSnowpackLogger(logger: typeof snowpackLogger) {
}
console.error(message);
});
logger.on('info', (message) => {
// Cache messages that should only be shown once.
// This is due to having 2 snowpack instances. Once that is removed we can
// get rid of this workaround.
if (messageCache.has(message)) {
return;
}
const shouldBeCached = onceMessages.some((exp) => exp.test(message));
if (shouldBeCached) {
messageCache.add(message);
}
console.log(message);
});
}

View file

@ -1,5 +1,5 @@
import { h } from 'preact';
export default function (props) {
return <div id="fallback">{import.meta.env.astro ? 'static' : 'dynamic'}</div>;
return <div id="fallback">{import.meta.env.SSR ? 'static' : 'dynamic'}</div>;
}