Skip to content

Commit

Permalink
Migrate to Vite 3 ⚡️ (#3570)
Browse files Browse the repository at this point in the history
* Vite 3 test

* deps: bump to Vite beta.1

* refactor: move to use optimizeDeps.force option

* refactor: stub out new updateModuleInfo params

* nit: remove comment on deprecated Vite feature

* nit: remove comment on deprecated vite feature

* hail mary: destroy all ssr external / noexternal!

* fix: use new middlewareMode config settings

* fix: resolve npm package paths for rollup input

* wip: revert to unresolved. Issue reported!

* sad refactor: use legacy devDepsScanner for component HMR

* fix: add astro/components to noExternal for Code component

* refactor: use ALWAYS_NOEXTERNAL array

* refactor: add package.json to all test runners for noExternal error

* deps: bump to latest vite 3 beta

* wip: add package.json to smoke

* fix: remove accidental "force true" on create-vite

* refactor: write smoke package.json programmatically

* refactor: add fontsource to noExternal

* fix: only add to ssr.noExternal if present in project

* wip: what if we just... didn't have a memory test

* deps: bump to latest vite beta

* Revert "wip: what if we just... didn't have a memory test"

This reverts commit 173729d.

* fix: add type check for plugin.name

* feat: remove legacy.devDepsScanner. Vite 3 strat is now Vite 2.x strat!

* fix: add ssr.noExternal to components ex

* wip: ignore with-mdx starter

* fix: add serviceEntryPoint to ssr.noExternal

* temp: reset NODE_ENV on prod builds

* fix: missing async tag

* VITE 3 IS STABLE BABY

* deps: bump svelte to vite 3

* deps: bump vue to vite 3

* fix: resolve plugins for proper sorting

* sad fix: regex "export default" out of CSS ssr

* chore: add TODO to understand sad fix

* Revert "fix: resolve plugins for proper sorting"

This reverts commit e67c194.

* Revert "sad fix: regex "export default" out of CSS ssr"

This reverts commit 721d40b.

* fix: sort plugins WITHOUT resolveConfig

* Revert "wip: ignore with-mdx starter"

This reverts commit 7d4f733.

* chore: revert memory test changes

* chore: add nanostores/preact ot noexternal

* chore: changeset

* chore: changeset

* deps: use Vite ^3.0.0

* fix: add back third party astro pkg scanner

Co-authored-by: bholmesdev <hey@bholmes.dev>
  • Loading branch information
matthewp and bholmesdev committed Jul 19, 2022
1 parent 3753400 commit 04070c0
Show file tree
Hide file tree
Showing 30 changed files with 338 additions and 85 deletions.
8 changes: 8 additions & 0 deletions .changeset/thirty-beans-poke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'astro': minor
'@astrojs/image': minor
'@astrojs/svelte': minor
'@astrojs/vue': minor
---

Bump to Vite 3!
8 changes: 7 additions & 1 deletion examples/component/demo/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { defineConfig } from 'astro/config';

// https://astro.build/config
export default defineConfig({});
export default defineConfig({
vite: {
ssr: {
noExternal: ['@example/my-component']
},
},
});
2 changes: 1 addition & 1 deletion packages/astro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
"strip-ansi": "^7.0.1",
"supports-esm": "^1.0.0",
"tsconfig-resolver": "^3.0.1",
"vite": "^2.9.14",
"vite": "^3.0.0",
"yargs-parser": "^21.0.1",
"zod": "^3.17.3"
},
Expand Down
3 changes: 2 additions & 1 deletion packages/astro/src/core/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,9 @@ class AstroBuilder {
mode: this.mode,
server: {
hmr: false,
middlewareMode: 'ssr',
middlewareMode: true,
},
appType: 'custom',
},
{ astroConfig: this.config, logging, mode: 'build' }
);
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/build/page-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export async function collectPagesData(
'build',
`${colors.bold(
route.component
)} is taking a bit longer to import. This is common for larger "Astro.glob(...)" or "import.meta.globEager(...)" calls, for instance. Hang tight!`
)} is taking a bit longer to import. This is common for larger "Astro.glob(...)" or "import.meta.glob(...)" calls, for instance. Hang tight!`
);
clearInterval(routeCollectionLogTimeout);
}, 10000);
Expand Down
10 changes: 6 additions & 4 deletions packages/astro/src/core/build/static-build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { fileURLToPath } from 'url';
import * as vite from 'vite';
import { BuildInternals, createBuildInternals } from '../../core/build/internal.js';
import { prependForwardSlash } from '../../core/path.js';
import { emptyDir, removeDir } from '../../core/util.js';
import { emptyDir, removeDir, resolveDependency } from '../../core/util.js';
import { runHookBuildSetup } from '../../integrations/index.js';
import { rollupPluginAstroBuildCSS } from '../../vite-plugin-build-css/index.js';
import type { ViteConfigWithSSR } from '../create-vite';
Expand Down Expand Up @@ -67,10 +67,12 @@ export async function staticBuild(opts: StaticBuildOptions) {
const ssrResult = (await ssrBuild(opts, internals, pageInput)) as RollupOutput;
info(opts.logging, 'build', dim(`Completed in ${getTimeStat(timer.ssr, performance.now())}.`));

const clientInput = new Set<string>([
const rendererClientEntrypoints = opts.astroConfig._ctx.renderers.map((r) => r.clientEntrypoint).filter(a => typeof a === 'string') as string[]

const clientInput = new Set([
...internals.discoveredHydratedComponents,
...internals.discoveredClientOnlyComponents,
...(astroConfig._ctx.renderers.map((r) => r.clientEntrypoint).filter((a) => a) as string[]),
...rendererClientEntrypoints,
...internals.discoveredScripts,
]);

Expand Down Expand Up @@ -167,7 +169,7 @@ async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, inp
async function clientBuild(
opts: StaticBuildOptions,
internals: BuildInternals,
input: Set<string>
input: Set<string>,
) {
const { astroConfig, viteConfig } = opts;
const timer = performance.now();
Expand Down
91 changes: 49 additions & 42 deletions packages/astro/src/core/create-vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { AstroConfig } from '../@types/astro';
import type { LogOptions } from './logger/core';

import fs from 'fs';
import { builtinModules } from 'module';
import { fileURLToPath } from 'url';
import * as vite from 'vite';
import astroPostprocessVitePlugin from '../vite-plugin-astro-postprocess/index.js';
Expand All @@ -14,45 +13,47 @@ import astroIntegrationsContainerPlugin from '../vite-plugin-integrations-contai
import jsxVitePlugin from '../vite-plugin-jsx/index.js';
import markdownVitePlugin from '../vite-plugin-markdown/index.js';
import astroScriptsPlugin from '../vite-plugin-scripts/index.js';
import { resolveDependency } from './util.js';

// note: ssr is still an experimental API hence the type omission from `vite`
export type ViteConfigWithSSR = vite.InlineConfig & { ssr?: vite.SSROptions };

interface CreateViteOptions {
astroConfig: AstroConfig;
logging: LogOptions;
mode: 'dev' | 'build';
}

// Some packages are just external, and that’s the way it goes.
const ALWAYS_EXTERNAL = new Set([
...builtinModules.map((name) => `node:${name}`),
'@sveltejs/vite-plugin-svelte',
'micromark-util-events-to-acorn',
'@astrojs/markdown-remark',
// in-lined for markdown modules
'github-slugger',
'node-fetch',
'prismjs',
'shiki',
'unified',
'whatwg-url',
]);
const ALWAYS_NOEXTERNAL = new Set([
// This is only because Vite's native ESM doesn't resolve "exports" correctly.
'astro',
// Vite fails on nested `.astro` imports without bundling
'astro/components',
// Handle recommended nanostores. Only @nanostores/preact is required from our testing!
// Full explanation and related bug report: https://github.com/withastro/astro/pull/3667
'@nanostores/preact',
]);

// note: ssr is still an experimental API hence the type omission from `vite`
export type ViteConfigWithSSR = vite.InlineConfig & { ssr?: vite.SSROptions };

interface CreateViteOptions {
astroConfig: AstroConfig;
logging: LogOptions;
mode: 'dev' | 'build';
function getSsrNoExternalDeps(projectRoot: URL): string[] {
let noExternalDeps = []
for (const dep of ALWAYS_NOEXTERNAL) {
try {
resolveDependency(dep, projectRoot)
noExternalDeps.push(dep)
} catch {
// ignore dependency if *not* installed / present in your project
// prevents hard error from Vite!
}
}
return noExternalDeps
}

/** Return a common starting point for all Vite actions */
export async function createVite(
commandConfig: ViteConfigWithSSR,
{ astroConfig, logging, mode }: CreateViteOptions
): Promise<ViteConfigWithSSR> {
// Scan for any third-party Astro packages. Vite needs these to be passed to `ssr.noExternal`.
const astroPackages = await getAstroPackages(astroConfig);
const thirdPartyAstroPackages = await getAstroPackages(astroConfig);
// Start with the Vite configuration that Astro core needs
const commonConfig: ViteConfigWithSSR = {
cacheDir: fileURLToPath(new URL('./node_modules/.vite/', astroConfig.root)), // using local caches allows Astro to be used in monorepos, etc.
Expand Down Expand Up @@ -82,7 +83,6 @@ export async function createVite(
'import.meta.env.SITE': astroConfig.site ? `'${astroConfig.site}'` : 'undefined',
},
server: {
force: true, // force dependency rebuild (TODO: enabled only while next is unstable; eventually only call in "production" mode?)
hmr:
process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'production'
? false
Expand Down Expand Up @@ -115,11 +115,12 @@ export async function createVite(
],
conditions: ['astro'],
},
// Note: SSR API is in beta (https://vitejs.dev/guide/ssr.html)
ssr: {
external: [...ALWAYS_EXTERNAL],
noExternal: [...ALWAYS_NOEXTERNAL, ...astroPackages],
},
noExternal: [
...getSsrNoExternalDeps(astroConfig.root),
...thirdPartyAstroPackages,
],
}
};

// Merge configs: we merge vite configuration objects together in the following order,
Expand All @@ -131,27 +132,33 @@ export async function createVite(
let result = commonConfig;
result = vite.mergeConfig(result, astroConfig.vite || {});
result = vite.mergeConfig(result, commandConfig);
sortPlugins(result);
if (result.plugins) {
sortPlugins(result.plugins);
}

return result;
}

function getPluginName(plugin: vite.PluginOption) {
if (plugin && typeof plugin === 'object' && !Array.isArray(plugin)) {
return plugin.name;
}
function isVitePlugin(plugin: vite.PluginOption): plugin is vite.Plugin {
return Boolean(plugin?.hasOwnProperty('name'));
}

function findPluginIndexByName(pluginOptions: vite.PluginOption[], name: string): number {
return pluginOptions.findIndex(function (pluginOption) {
// Use isVitePlugin to ignore nulls, booleans, promises, and arrays
// CAUTION: could be a problem if a plugin we're searching for becomes async!
return isVitePlugin(pluginOption) && pluginOption.name === name
})
}

function sortPlugins(result: ViteConfigWithSSR) {
function sortPlugins(pluginOptions: vite.PluginOption[]) {
// HACK: move mdxPlugin to top because it needs to run before internal JSX plugin
const mdxPluginIndex =
result.plugins?.findIndex((plugin) => getPluginName(plugin) === '@mdx-js/rollup') ?? -1;
const mdxPluginIndex = findPluginIndexByName(pluginOptions, '@mdx-js/rollup');
if (mdxPluginIndex === -1) return;
const jsxPluginIndex =
result.plugins?.findIndex((plugin) => getPluginName(plugin) === 'astro:jsx') ?? -1;
const mdxPlugin = result.plugins?.[mdxPluginIndex];
result.plugins?.splice(mdxPluginIndex, 1);
result.plugins?.splice(jsxPluginIndex, 0, mdxPlugin);
const jsxPluginIndex = findPluginIndexByName(pluginOptions, 'astro:jsx');
const mdxPlugin = pluginOptions[mdxPluginIndex];
pluginOptions.splice(mdxPluginIndex, 1);
pluginOptions.splice(jsxPluginIndex, 0, mdxPlugin);
}

// Scans `projectRoot` for third-party Astro packages that could export an `.astro` file
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/src/core/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ export function codeFrame(src: string, loc: ErrorPayload['err']['loc']): string
return output;
}

export function resolveDependency(dep: string, astroConfig: AstroConfig) {
export function resolveDependency(dep: string, projectRoot: URL) {
const resolved = resolve.sync(dep, {
basedir: fileURLToPath(astroConfig.root),
basedir: fileURLToPath(projectRoot),
});
// For Windows compat, we need a fully resolved `file://` URL string
return pathToFileURL(resolved).toString();
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/vite-plugin-astro/hmr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export async function trackCSSDependencies(
}

// Update the module graph, telling it about our CSS deps.
moduleGraph.updateModuleInfo(mod, depModules, new Set(), true);
moduleGraph.updateModuleInfo(mod, depModules, new Map(), new Set(), new Set(), true);
for (const dep of cssDeps) {
this.addWatchFile(dep);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/vite-plugin-astro/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
configureServer(server) {
viteDevServer = server;
},
// note: don’t claim .astro files with resolveId() — it prevents Vite from transpiling the final JS (import.meta.globEager, etc.)
// note: don’t claim .astro files with resolveId() — it prevents Vite from transpiling the final JS (import.meta.glob, etc.)
async resolveId(id, from, opts) {
// If resolving from an astro subresource such as a hoisted script,
// we need to resolve relative paths ourselves.
Expand Down
8 changes: 8 additions & 0 deletions packages/astro/test/fixtures/api-routes/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@test/api-routes",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
8 changes: 8 additions & 0 deletions packages/astro/test/fixtures/astro-response/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@test/astro-response",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
8 changes: 8 additions & 0 deletions packages/astro/test/fixtures/config-vite/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@test/config-vite",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
13 changes: 13 additions & 0 deletions packages/astro/test/fixtures/fontsource-package/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { defineConfig } from 'astro/config';

// https://astro.build/config
export default defineConfig({
vite: {
ssr: {
noExternal: [
'@fontsource/montserrat',
'@fontsource/monofett',
]
}
}
});
8 changes: 8 additions & 0 deletions packages/astro/test/fixtures/hmr-css/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@test/hmr-css",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
8 changes: 8 additions & 0 deletions packages/astro/test/fixtures/import-ts-with-js/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@test/import-ts-with-js",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
8 changes: 8 additions & 0 deletions packages/astro/test/fixtures/page-level-styles/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@test/page-level-styles",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
8 changes: 8 additions & 0 deletions packages/astro/test/fixtures/ssr-api-route/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@test/ssr-api-route",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
8 changes: 8 additions & 0 deletions packages/astro/test/fixtures/ssr-assets/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@test/ssr-assets",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
8 changes: 8 additions & 0 deletions packages/astro/test/fixtures/ssr-dynamic/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@test/ssr-dynamic",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
8 changes: 8 additions & 0 deletions packages/astro/test/fixtures/ssr-hoisted-script/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@test/ssr-hoisted-script",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
8 changes: 8 additions & 0 deletions packages/astro/test/fixtures/ssr-request/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@test/ssr-request",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
8 changes: 8 additions & 0 deletions packages/astro/test/fixtures/ssr-response/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@test/ssr-response",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
8 changes: 8 additions & 0 deletions packages/astro/test/fixtures/status-code/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@test/status-code",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
Loading

0 comments on commit 04070c0

Please sign in to comment.