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:
parent
b22ba1c03a
commit
1ab505855f
5 changed files with 80 additions and 19 deletions
5
.changeset/purple-tips-flash.md
Normal file
5
.changeset/purple-tips-flash.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fix regression with loading .ts in .mjs config
|
|
@ -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 ?? {},
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
41
packages/astro/test/units/config/format.test.js
Normal file
41
packages/astro/test/units/config/format.test.js
Normal 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.');
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue