Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions packages/cli/src/update.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import { spawn } from 'node:child_process';
import fs from 'node:fs/promises';
import path from 'node:path';
import fse from '@rspress/shared/fs-extra';
import { logger } from '@rspress/shared/logger';

async function pathExists(path: string): Promise<boolean> {
try {
await fs.access(path);
return true;
} catch {
return false;
}
}

type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun';

const lockfileMap: Record<string, PackageManager> = {
Expand All @@ -16,7 +24,7 @@ const lockfileMap: Record<string, PackageManager> = {
async function getPackageManager(rootPath: string) {
let packageManager: PackageManager = 'npm';
for (const file of Object.keys(lockfileMap)) {
if (await fse.pathExists(path.join(rootPath, file))) {
if (await pathExists(path.join(rootPath, file))) {
packageManager = lockfileMap[file];
break;
}
Expand Down
20 changes: 14 additions & 6 deletions packages/core/src/node/build.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import fs from 'node:fs/promises';
import { dirname, join } from 'node:path';
import { pathToFileURL } from 'node:url';
import type { Route } from '@/node/route/RouteService';
Expand All @@ -11,7 +12,6 @@ import {
withBase,
} from '@rspress/shared';
import chalk from '@rspress/shared/chalk';
import fs from '@rspress/shared/fs-extra';
import { logger } from '@rspress/shared/logger';
import type { HelmetData } from 'react-helmet-async';
import { PluginDriver } from './PluginDriver';
Expand Down Expand Up @@ -50,13 +50,18 @@ export async function bundle(
pluginDriver,
enableSSG,
);

await rsbuild.build();
} finally {
await writeSearchIndex(config);
await checkLanguageParity(config);
}
}

function emptyDir(path: string): Promise<void> {
return fs.rm(path, { force: true, recursive: true });
}

export interface SSRBundleExports {
render: (
url: string,
Expand All @@ -77,7 +82,6 @@ export async function renderPages(
const ssrBundlePath = join(outputPath, 'ssr', 'main.cjs');

try {
const { default: fs } = await import('@rspress/shared/fs-extra');
const { version } = await import('../../package.json');
// There are two cases where we will fallback to CSR:
// 1. ssr bundle load failed
Expand Down Expand Up @@ -204,15 +208,17 @@ export async function renderPages(
return `${path}.html`.replace(normalizedBase, '');
};
const fileName = normalizeHtmlFilePath(routePath);
await fs.ensureDir(join(outputPath, dirname(fileName)));
await fs.mkdir(join(outputPath, dirname(fileName)), {
recursive: true,
});
await fs.writeFile(join(outputPath, fileName), html);
}),
);
// Remove ssr bundle
if (!isDebugMode()) {
await fs.remove(join(outputPath, 'ssr'));
await emptyDir(join(outputPath, 'ssr'));
}
await fs.remove(join(outputPath, 'html'));
await emptyDir(join(outputPath, 'html'));

const totalTime = Date.now() - startTime;
logger.success(`Pages rendered in ${chalk.yellow(totalTime)} ms.`);
Expand All @@ -227,13 +233,15 @@ export async function build(options: BuildOptions) {
const pluginDriver = new PluginDriver(config, true);
await pluginDriver.init();
const modifiedConfig = await pluginDriver.modifyConfig();

await pluginDriver.beforeBuild();
const ssgConfig = modifiedConfig.ssg ?? true;

// empty temp dir before build
await fs.emptyDir(TEMP_DIR);
await emptyDir(TEMP_DIR);

await bundle(docDirectory, modifiedConfig, pluginDriver, Boolean(ssgConfig));

await renderPages(appDirectory, modifiedConfig, pluginDriver, ssgConfig);
await pluginDriver.afterBuild();
}
1 change: 0 additions & 1 deletion packages/core/src/node/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export async function dev(options: DevOptions): Promise<ServerInstance> {
await pluginDriver.beforeBuild();

// empty temp dir before build
// await fs.emptyDir( TEMP_DIR);
const builder = await initRsbuild(
docDirectory,
modifiedConfig,
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/node/initRsbuild.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import type {
RsbuildConfig,
Expand All @@ -15,7 +16,6 @@ import {
removeLeadingSlash,
removeTrailingSlash,
} from '@rspress/shared';
import fs from '@rspress/shared/fs-extra';
import type { PluginDriver } from './PluginDriver';
import {
CLIENT_ENTRY,
Expand Down Expand Up @@ -321,7 +321,7 @@ export async function initRsbuild(
// and we should empty temp dir before build
const runtimeTempDir = path.join(RSPRESS_TEMP_DIR, 'runtime');
const runtimeAbsTempDir = path.join(cwd, 'node_modules', runtimeTempDir);
await fs.ensureDir(runtimeAbsTempDir);
await fs.mkdir(runtimeAbsTempDir, { recursive: true });

const routeService = await initRouteService({
config,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/node/mdx/loader.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import { pathToFileURL } from 'node:url';
import { createProcessor } from '@mdx-js/mdx';
import { isProduction } from '@rspress/shared';
import fs from '@rspress/shared/fs-extra';
import { logger } from '@rspress/shared/logger';
import { loadFrontMatter } from '@rspress/shared/node-utils';
import type { PluginDriver } from '../PluginDriver';
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/node/route/RouteService.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import {
type PageModule,
Expand All @@ -7,7 +8,6 @@ import {
addTrailingSlash,
withBase,
} from '@rspress/shared';
import fs from '@rspress/shared/fs-extra';
import type { ComponentType } from 'react';
import { glob } from 'tinyglobby';
import type { PluginDriver } from '../PluginDriver';
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/node/runtimeModule/globalStyles.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fs from '@rspress/shared/fs-extra';
import fs from 'node:fs/promises';
import { type FactoryContext, RuntimeModuleID } from '.';

export async function globalStylesVMPlugin(context: FactoryContext) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import { importStatementRegex } from '@/node/constants';
import type { RouteService } from '@/node/route/RouteService';
Expand All @@ -10,7 +11,6 @@ import {
type PageIndexInfo,
type ReplaceRule,
} from '@rspress/shared';
import fs from '@rspress/shared/fs-extra';
import { loadFrontMatter } from '@rspress/shared/node-utils';
import { htmlToText } from 'html-to-text';

Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/node/runtimeModule/siteData/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import { TEMP_DIR, isProduction } from '@/node/constants';
import { createHash } from '@/node/utils';
import { SEARCH_INDEX_NAME, type SiteData } from '@rspress/shared';
import fs from '@rspress/shared/fs-extra';
import { groupBy } from 'lodash-es';
import { type FactoryContext, RuntimeModuleID } from '..';
import { extractPageData } from './extractPageData';
Expand Down Expand Up @@ -97,7 +97,7 @@ export async function siteDataVMPlugin(context: FactoryContext) {
const indexVersion = version ? `.${version.replace('.', '_')}` : '';
const indexLang = lang ? `.${lang}` : '';

await fs.ensureDir(TEMP_DIR);
await fs.mkdir(TEMP_DIR, { recursive: true });
await fs.writeFile(
path.join(
TEMP_DIR,
Expand Down
14 changes: 10 additions & 4 deletions packages/core/src/node/searchIndex.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { createReadStream } from 'node:fs';
import fs from 'node:fs/promises';
import type { IncomingMessage, ServerResponse } from 'node:http';
import path, { join } from 'node:path';
import { SEARCH_INDEX_NAME, type UserConfig, isSCM } from '@rspress/shared';
import chalk from '@rspress/shared/chalk';
import fs from '@rspress/shared/fs-extra';
import { logger } from '@rspress/shared/logger';
import { OUTPUT_DIR, TEMP_DIR, isProduction } from './constants';

Expand All @@ -15,9 +16,14 @@ export async function writeSearchIndex(config: UserConfig) {
const searchIndexFiles = await fs.readdir(TEMP_DIR);
const outDir = config?.outDir ?? join(cwd, OUTPUT_DIR);

// Make sure the targetDir exists
const targetDir = join(outDir, 'static');
await fs.mkdir(targetDir, { recursive: true });

// For performance, we only stitch the string of search index data instead of big JavaScript object in memory
let searchIndexData = '[]';
let scanning = false;
// TODO: use Promise for perf
for (const searchIndexFile of searchIndexFiles) {
if (
!searchIndexFile.includes(SEARCH_INDEX_NAME) ||
Expand All @@ -26,15 +32,15 @@ export async function writeSearchIndex(config: UserConfig) {
continue;
}
const source = join(TEMP_DIR, searchIndexFile);
const target = join(outDir, 'static', searchIndexFile);
const target = join(targetDir, searchIndexFile);
const searchIndex = await fs.readFile(
join(TEMP_DIR, searchIndexFile),
'utf-8',
);
searchIndexData = `${searchIndexData.slice(0, -1)}${
scanning ? ',' : ''
}${searchIndex.slice(1)}`;
await fs.move(source, target, { overwrite: true });
await fs.rename(source, target);
scanning = true;
}

Expand Down Expand Up @@ -75,7 +81,7 @@ export function serveSearchIndexMiddleware(config: UserConfig): RequestHandler {
res.setHeader('Content-Type', 'application/json');
// Get search index name from request url
const searchIndexFile = req.url?.split('/').pop();
fs.createReadStream(
createReadStream(
path.join(
process.cwd(),
config?.outDir || OUTPUT_DIR,
Expand Down
12 changes: 8 additions & 4 deletions packages/core/src/node/utils/detectReactVersion.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import fs from 'node:fs';
import path from 'node:path';
import fs from '@rspress/shared/fs-extra';
import { logger } from '@rspress/shared/logger';
import enhancedResolve from 'enhanced-resolve';
import { PACKAGE_ROOT } from '../constants';
import { pathExists, readJson } from './fs';

// TODO: replace enhanced-resolve with this.getResolver
const { CachedInputFileSystem, ResolverFactory } = enhancedResolve;

const DEFAULT_REACT_VERSION = 18;
Expand All @@ -14,9 +16,11 @@ export async function detectReactVersion(): Promise<number> {
// if not found, return 18
const cwd = process.cwd();
const reactPath = path.join(cwd, 'node_modules', 'react');
if (await fs.pathExists(reactPath)) {
const reactPkg = await fs.readJson(path.join(reactPath, 'package.json'));
const version = Number(reactPkg.version.split('.')[0]);
if (await pathExists(reactPath)) {
const reactPkg: { version?: string } = await readJson(
path.join(reactPath, 'package.json'),
);
const version = Number(reactPkg.version?.split('.')[0]);
return version;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/node/utils/flattenMdxContent.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fs from 'node:fs';
import path from 'node:path';
import { createProcessor } from '@mdx-js/mdx';
import { MDX_REGEXP } from '@rspress/shared';
import fs from '@rspress/shared/fs-extra';
import enhancedResolve from 'enhanced-resolve';
import { importStatementRegex } from '../constants';

Expand Down
15 changes: 15 additions & 0 deletions packages/core/src/node/utils/fs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import fs from 'node:fs/promises';

export async function pathExists(path: string): Promise<boolean> {
try {
await fs.access(path);
return true;
} catch {
return false;
}
}

export async function readJson(path: string): Promise<any> {
const raw = await fs.readFile(path, 'utf8');
return JSON.parse(raw);
}
1 change: 1 addition & 0 deletions packages/core/src/node/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export * from './flattenMdxContent';
export * from './applyReplaceRules';
export * from './extractTextAndId';
export * from './escapeHeadingIds';
export * from './fs';
4 changes: 2 additions & 2 deletions packages/core/src/node/utils/renderHead.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import fs from 'node:fs/promises';
import type { FrontMatterMeta, RouteMeta, UserConfig } from '@rspress/shared';
import fsExtra from '@rspress/shared/fs-extra';
import { loadFrontMatter } from '@rspress/shared/node-utils';

export async function renderFrontmatterHead(route: any): Promise<string> {
if (!isRouteMeta(route)) return '';
const content = await fsExtra.readFile(route.absolutePath, {
const content = await fs.readFile(route.absolutePath, {
encoding: 'utf-8',
});
const {
Expand Down
4 changes: 2 additions & 2 deletions packages/modern-plugin-rspress/src/launchDoc.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fs from 'node:fs';
import fs from 'node:fs/promises';
import { join, relative, resolve } from 'node:path';
import type { Sidebar, SidebarGroup, UserConfig } from '@rspress/core';
import { pluginApiDocgen } from '@rspress/plugin-api-docgen';
Expand Down Expand Up @@ -34,7 +34,7 @@ export async function launchDoc({
previewMode = 'iframe';
}
const json = JSON.parse(
fs.readFileSync(resolve(appDir, './package.json'), 'utf8'),
await fs.readFile(resolve(appDir, './package.json'), 'utf8'),
);
const root = resolve(appDir, doc.root ?? 'docs');
const { dev, build } = await import('@rspress/core');
Expand Down
18 changes: 16 additions & 2 deletions packages/plugin-auto-nav-sidebar/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import type { NavItem, Sidebar } from '@rspress/shared';
import fs from '@rspress/shared/fs-extra';
import { logger } from '@rspress/shared/logger';
import { loadFrontMatter } from '@rspress/shared/node-utils';

export async function pathExists(path: string): Promise<boolean> {
try {
await fs.access(path);
return true;
} catch {
return false;
}
}

export async function readJson(path: string): Promise<any> {
const raw = await fs.readFile(path, 'utf8');
return JSON.parse(raw);
}

/**
* @param rawPathWithExtension /usr/rspress-demo/docs/api.md
* @returns /usr/rspress-demo/docs/api.md or undefined
*/
export async function detectFilePathWithExtension(
rawPathWithExtension: string,
): Promise<string | undefined> {
const exist = await fs.pathExists(rawPathWithExtension);
const exist = await pathExists(rawPathWithExtension);
if (!exist) {
return undefined;
}
Expand Down
Loading