Skip to content

Commit

Permalink
Fix regression with loading .ts in .mjs config (#5431)
Browse files Browse the repository at this point in the history
* Fix regression with loading .ts in .mjs config

* Account for directories
  • Loading branch information
matthewp authored Nov 17, 2022
1 parent b22ba1c commit 1ab5058
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changeset/purple-tips-flash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fix regression with loading .ts in .mjs config
21 changes: 14 additions & 7 deletions packages/astro/src/core/config/vite-load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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: [] },
Expand All @@ -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 {
Expand Down Expand Up @@ -103,17 +105,22 @@ export async function loadConfigWithVite({

// Try loading with Node import()
if (/\.[cm]?js$/.test(file)) {
const config = await import(pathToFileURL(file).toString());
return {
value: config.default ?? {},
filePath: 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 ?? {},
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/create-vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
30 changes: 19 additions & 11 deletions packages/astro/src/vite-plugin-load-fallback/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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
Expand All @@ -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 {
let resolved = await this.resolve(id, parent, { skipSelf: true });
if (resolved) {
return resolved.id;
}
return slashify(id);
// 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);
Expand Down
41 changes: 41 additions & 0 deletions packages/astro/test/units/config/format.test.js
Original file line number Diff line number Diff line change
@@ -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.');
});
});
});

0 comments on commit 1ab5058

Please sign in to comment.