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 * as vite from 'vite';
import { AstroError, AstroErrorData } from '../errors/index.js';
import loadFallbackPlugin from '../../vite-plugin-load-fallback/index.js';
// Fallback for legacy
import load from '@proload/core';
@ -15,7 +16,7 @@ export interface ViteLoader {
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({
server: { middlewareMode: true, hmr: false },
optimizeDeps: { entries: [] },
@ -27,6 +28,7 @@ async function createViteLoader(root: string): Promise<ViteLoader> {
// avoid `vite.createServer` and use `loadConfigFromFile` instead.
external: ['@astrojs/tailwind', '@astrojs/mdx', '@astrojs/react'],
},
plugins: [ loadFallbackPlugin({ fs, root: pathToFileURL(root) })]
});
return {
@ -103,17 +105,22 @@ export async function loadConfigWithVite({
// Try loading with Node import()
if (/\.[cm]?js$/.test(file)) {
try {
const config = await import(pathToFileURL(file).toString());
return {
value: config.default ?? {},
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
let loader: ViteLoader | undefined;
try {
loader = await createViteLoader(root);
loader = await createViteLoader(root, fs);
const mod = await loader.viteServer.ssrLoadModule(file);
return {
value: mod.default ?? {},

View file

@ -97,7 +97,7 @@ export async function createVite(
},
plugins: [
configAliasVitePlugin({ settings }),
astroLoadFallbackPlugin({ fs, settings }),
astroLoadFallbackPlugin({ fs, root: settings.config.root }),
astroVitePlugin({ settings, logging }),
astroScriptsPlugin({ settings }),
// 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 {
fs?: NodeFileSystemModule;
settings: AstroSettings;
root: URL;
}
export default function loadFallbackPlugin({
fs,
settings,
root,
}: LoadFallbackPluginParams): vite.Plugin[] | false {
// Only add this plugin if a custom fs implementation is provided.
if (!fs || fs === nodeFs) {
@ -29,7 +29,7 @@ export default function loadFallbackPlugin({
return await fs.promises.readFile(id, 'utf-8');
} catch (e2) {
try {
const fullpath = new URL('.' + id, settings.config.root);
const fullpath = new URL('.' + id, root);
return await fs.promises.readFile(fullpath, 'utf-8');
} catch (e3) {
// Let fall through to the next
@ -43,15 +43,23 @@ export default function loadFallbackPlugin({
name: 'astro:load-fallback',
enforce: 'post',
async resolveId(id, parent) {
if (id.startsWith('.') && parent && fs.existsSync(parent)) {
return npath.posix.join(npath.posix.dirname(parent), id);
} else {
// See if this can be loaded from our fs
if (parent) {
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 });
if (resolved) {
return resolved.id;
}
return slashify(id);
}
},
async load(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.');
});
});
});