mirror of
https://github.com/lobehub/lobe-chat.git
synced 2026-06-14 03:30:19 +00:00
🔨 chore(vite): support direct markdown imports (#13216)
✨ feat(vite): support markdown imports
This commit is contained in:
@@ -0,0 +1,51 @@
|
|||||||
|
import { mkdtemp, rm, writeFile } from 'node:fs/promises';
|
||||||
|
import { tmpdir } from 'node:os';
|
||||||
|
import { join } from 'node:path';
|
||||||
|
|
||||||
|
import { describe, expect, it, vi } from 'vitest';
|
||||||
|
|
||||||
|
import { viteMarkdownImport } from './markdownImport';
|
||||||
|
|
||||||
|
describe('viteMarkdownImport', () => {
|
||||||
|
it('rewrites bare markdown imports into raw string modules', async () => {
|
||||||
|
const tempDir = await mkdtemp(join(tmpdir(), 'vite-markdown-import-'));
|
||||||
|
const markdownPath = join(tempDir, 'sample.md');
|
||||||
|
const markdownContent = '# hello\n\nThis is markdown.\n';
|
||||||
|
|
||||||
|
await writeFile(markdownPath, markdownContent);
|
||||||
|
|
||||||
|
const plugin = viteMarkdownImport();
|
||||||
|
const resolve = vi.fn().mockResolvedValue({ id: markdownPath });
|
||||||
|
|
||||||
|
const resolved = await plugin.resolveId?.call(
|
||||||
|
{ resolve } as never,
|
||||||
|
'./sample.md',
|
||||||
|
join(tempDir, 'entry.ts'),
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(resolved).toEqual({
|
||||||
|
id: `${markdownPath}?lobe-md-import`,
|
||||||
|
moduleSideEffects: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const loaded = await plugin.load?.call({} as never, `${markdownPath}?lobe-md-import`);
|
||||||
|
|
||||||
|
expect(loaded).toBe(`export default ${JSON.stringify(markdownContent)};`);
|
||||||
|
|
||||||
|
await rm(tempDir, { force: true, recursive: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('leaves explicit markdown queries untouched', async () => {
|
||||||
|
const plugin = viteMarkdownImport();
|
||||||
|
|
||||||
|
const resolved = await plugin.resolveId?.call(
|
||||||
|
{ resolve: vi.fn() } as never,
|
||||||
|
'./sample.md?raw',
|
||||||
|
'/tmp/entry.ts',
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(resolved).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { readFile } from 'node:fs/promises';
|
||||||
|
|
||||||
|
import type { Plugin } from 'vite';
|
||||||
|
|
||||||
|
const MARKDOWN_IMPORT_QUERY = 'lobe-md-import';
|
||||||
|
|
||||||
|
function hasQuery(id: string) {
|
||||||
|
return id.includes('?');
|
||||||
|
}
|
||||||
|
|
||||||
|
function isMarkdownFile(id: string) {
|
||||||
|
return id.replace(/[?#].*$/, '').endsWith('.md');
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchesMarkdownImportQuery(id: string) {
|
||||||
|
const query = id.split('?')[1];
|
||||||
|
if (!query) return false;
|
||||||
|
|
||||||
|
const params = new URLSearchParams(query);
|
||||||
|
|
||||||
|
return params.has(MARKDOWN_IMPORT_QUERY);
|
||||||
|
}
|
||||||
|
|
||||||
|
function withMarkdownImportQuery(id: string) {
|
||||||
|
return `${id}${hasQuery(id) ? '&' : '?'}${MARKDOWN_IMPORT_QUERY}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function viteMarkdownImport(): Plugin {
|
||||||
|
return {
|
||||||
|
enforce: 'pre',
|
||||||
|
async load(id) {
|
||||||
|
if (!matchesMarkdownImportQuery(id)) return null;
|
||||||
|
|
||||||
|
const filePath = id.replace(/[?#].*$/, '');
|
||||||
|
const content = await readFile(filePath, 'utf8');
|
||||||
|
|
||||||
|
return `export default ${JSON.stringify(content)};`;
|
||||||
|
},
|
||||||
|
name: 'vite-markdown-import',
|
||||||
|
async resolveId(source, importer, options) {
|
||||||
|
if (!importer || hasQuery(source) || !isMarkdownFile(source)) return null;
|
||||||
|
|
||||||
|
const resolved = await this.resolve(source, importer, { ...options, skipSelf: true });
|
||||||
|
if (!resolved) return null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: withMarkdownImportQuery(resolved.id),
|
||||||
|
moduleSideEffects: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import { nodePolyfills } from 'vite-plugin-node-polyfills';
|
|||||||
import tsconfigPaths from 'vite-tsconfig-paths';
|
import tsconfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|
||||||
import { viteEmotionSpeedy } from './emotionSpeedy';
|
import { viteEmotionSpeedy } from './emotionSpeedy';
|
||||||
|
import { viteMarkdownImport } from './markdownImport';
|
||||||
import { viteNodeModuleStub } from './nodeModuleStub';
|
import { viteNodeModuleStub } from './nodeModuleStub';
|
||||||
import { vitePlatformResolve } from './platformResolve';
|
import { vitePlatformResolve } from './platformResolve';
|
||||||
|
|
||||||
@@ -123,6 +124,7 @@ export function sharedRendererPlugins(options: SharedRendererOptions) {
|
|||||||
const defaultTsconfigPaths = options.tsconfigPaths ?? true;
|
const defaultTsconfigPaths = options.tsconfigPaths ?? true;
|
||||||
return [
|
return [
|
||||||
viteEmotionSpeedy(),
|
viteEmotionSpeedy(),
|
||||||
|
viteMarkdownImport(),
|
||||||
nodePolyfills({ include: ['buffer'] }),
|
nodePolyfills({ include: ['buffer'] }),
|
||||||
viteNodeModuleStub(),
|
viteNodeModuleStub(),
|
||||||
vitePlatformResolve(options.platform),
|
vitePlatformResolve(options.platform),
|
||||||
|
|||||||
Vendored
+5
@@ -1,5 +1,10 @@
|
|||||||
import 'vite/client';
|
import 'vite/client';
|
||||||
|
|
||||||
|
declare module '*.md' {
|
||||||
|
const content: string;
|
||||||
|
export default content;
|
||||||
|
}
|
||||||
|
|
||||||
declare module 'pdfjs-dist/build/pdf.worker.min.mjs?url' {
|
declare module 'pdfjs-dist/build/pdf.worker.min.mjs?url' {
|
||||||
const url: string;
|
const url: string;
|
||||||
export default url;
|
export default url;
|
||||||
|
|||||||
Reference in New Issue
Block a user