0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-23 21:53:55 -05:00

Fix regression with loading .ts in .mjs config (#5431)

* Fix regression with loading .ts in .mjs config

* Account for directories
This commit is contained in:
Matthew Phillips 2022-11-17 10:32:59 -05:00 committed by GitHub
parent b22ba1c03a
commit 1ab505855f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 80 additions and 19 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fix regression with loading .ts in .mjs config

View file

@ -3,6 +3,7 @@ import npath from 'path';
import { pathToFileURL } from 'url'; import { pathToFileURL } from 'url';
import * as vite from 'vite'; import * as vite from 'vite';
import { AstroError, AstroErrorData } from '../errors/index.js'; import { AstroError, AstroErrorData } from '../errors/index.js';
import loadFallbackPlugin from '../../vite-plugin-load-fallback/index.js';
// Fallback for legacy // Fallback for legacy
import load from '@proload/core'; import load from '@proload/core';
@ -15,7 +16,7 @@ export interface ViteLoader {
viteServer: vite.ViteDevServer; viteServer: vite.ViteDevServer;
} }
async function createViteLoader(root: string): Promise<ViteLoader> { async function createViteLoader(root: string, fs: typeof fsType): Promise<ViteLoader> {
const viteServer = await vite.createServer({ const viteServer = await vite.createServer({
server: { middlewareMode: true, hmr: false }, server: { middlewareMode: true, hmr: false },
optimizeDeps: { entries: [] }, optimizeDeps: { entries: [] },
@ -27,6 +28,7 @@ async function createViteLoader(root: string): Promise<ViteLoader> {
// avoid `vite.createServer` and use `loadConfigFromFile` instead. // avoid `vite.createServer` and use `loadConfigFromFile` instead.
external: ['@astrojs/tailwind', '@astrojs/mdx', '@astrojs/react'], external: ['@astrojs/tailwind', '@astrojs/mdx', '@astrojs/react'],
}, },
plugins: [ loadFallbackPlugin({ fs, root: pathToFileURL(root) })]
}); });
return { return {
@ -103,17 +105,22 @@ export async function loadConfigWithVite({
// Try loading with Node import() // Try loading with Node import()
if (/\.[cm]?js$/.test(file)) { if (/\.[cm]?js$/.test(file)) {
try {
const config = await import(pathToFileURL(file).toString()); const config = await import(pathToFileURL(file).toString());
return { return {
value: config.default ?? {}, value: config.default ?? {},
filePath: file, filePath: file,
}; };
} catch {
// We do not need to keep the error here because with fallback the error will be rethrown
// when/if it fails in Proload.
}
} }
// Try Loading with Vite // Try Loading with Vite
let loader: ViteLoader | undefined; let loader: ViteLoader | undefined;
try { try {
loader = await createViteLoader(root); loader = await createViteLoader(root, fs);
const mod = await loader.viteServer.ssrLoadModule(file); const mod = await loader.viteServer.ssrLoadModule(file);
return { return {
value: mod.default ?? {}, value: mod.default ?? {},

View file

@ -97,7 +97,7 @@ export async function createVite(
}, },
plugins: [ plugins: [
configAliasVitePlugin({ settings }), configAliasVitePlugin({ settings }),
astroLoadFallbackPlugin({ fs, settings }), astroLoadFallbackPlugin({ fs, root: settings.config.root }),
astroVitePlugin({ settings, logging }), astroVitePlugin({ settings, logging }),
astroScriptsPlugin({ settings }), astroScriptsPlugin({ settings }),
// The server plugin is for dev only and having it run during the build causes // The server plugin is for dev only and having it run during the build causes

View file

@ -8,12 +8,12 @@ type NodeFileSystemModule = typeof nodeFs;
export interface LoadFallbackPluginParams { export interface LoadFallbackPluginParams {
fs?: NodeFileSystemModule; fs?: NodeFileSystemModule;
settings: AstroSettings; root: URL;
} }
export default function loadFallbackPlugin({ export default function loadFallbackPlugin({
fs, fs,
settings, root,
}: LoadFallbackPluginParams): vite.Plugin[] | false { }: LoadFallbackPluginParams): vite.Plugin[] | false {
// Only add this plugin if a custom fs implementation is provided. // Only add this plugin if a custom fs implementation is provided.
if (!fs || fs === nodeFs) { if (!fs || fs === nodeFs) {
@ -29,7 +29,7 @@ export default function loadFallbackPlugin({
return await fs.promises.readFile(id, 'utf-8'); return await fs.promises.readFile(id, 'utf-8');
} catch (e2) { } catch (e2) {
try { try {
const fullpath = new URL('.' + id, settings.config.root); const fullpath = new URL('.' + id, root);
return await fs.promises.readFile(fullpath, 'utf-8'); return await fs.promises.readFile(fullpath, 'utf-8');
} catch (e3) { } catch (e3) {
// Let fall through to the next // Let fall through to the next
@ -43,15 +43,23 @@ export default function loadFallbackPlugin({
name: 'astro:load-fallback', name: 'astro:load-fallback',
enforce: 'post', enforce: 'post',
async resolveId(id, parent) { async resolveId(id, parent) {
if (id.startsWith('.') && parent && fs.existsSync(parent)) { // See if this can be loaded from our fs
return npath.posix.join(npath.posix.dirname(parent), id); if (parent) {
} else { const candidateId = npath.posix.join(npath.posix.dirname(parent), id);
try {
// Check to see if this file exists and is not a directory.
const stats = await fs.promises.stat(candidateId);
if(!stats.isDirectory()) {
return candidateId;
}
} catch {}
}
let resolved = await this.resolve(id, parent, { skipSelf: true }); let resolved = await this.resolve(id, parent, { skipSelf: true });
if (resolved) { if (resolved) {
return resolved.id; return resolved.id;
} }
return slashify(id); return slashify(id);
}
}, },
async load(id) { async load(id) {
const source = await tryLoadModule(id); const source = await tryLoadModule(id);

View file

@ -0,0 +1,41 @@
import { expect } from 'chai';
import * as cheerio from 'cheerio';
import { fileURLToPath } from 'url';
import {
runInContainer,
} from '../../../dist/core/dev/index.js';
import { openConfig, createSettings } from '../../../dist/core/config/index.js';
import { createFs } from '../test-utils.js';
import { defaultLogging } from '../../test-utils.js';
const root = new URL('../../fixtures/tailwindcss-ts/', import.meta.url);
describe('Astro config formats', () => {
it('An mjs config can import TypeScript modules', async () => {
const fs = createFs(
{
'/src/pages/index.astro': ``,
'/src/stuff.ts': `export default 'works';`,
'/astro.config.mjs': `
import stuff from './src/stuff.ts';
export default {}
`,
},
root
);
const { astroConfig } = await openConfig({
cwd: root,
flags: {},
cmd: 'dev',
logging: defaultLogging,
fsMod: fs
});
const settings = createSettings(astroConfig);
await runInContainer({ fs, root, settings }, () => {
expect(true).to.equal(true, 'We were able to get into the container which means the config loaded.');
});
});
});