@rspress/plugin-preview 2.0.0-beta.2 → 2.0.0-beta.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.js +39 -56
- package/index.d.ts +0 -1
- package/package.json +14 -14
- package/static/global-styles/entry.css +22 -5
package/README.md
CHANGED
package/dist/index.js
CHANGED
@@ -1,16 +1,15 @@
|
|
1
|
-
import
|
2
|
-
import
|
3
|
-
import
|
4
|
-
import
|
5
|
-
import
|
6
|
-
import
|
7
|
-
import
|
8
|
-
import
|
9
|
-
import
|
10
|
-
|
11
|
-
const
|
12
|
-
const
|
13
|
-
const virtualDir = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(process.cwd(), 'node_modules', __WEBPACK_EXTERNAL_MODULE__rspress_shared_baa012d0__.RSPRESS_TEMP_DIR, 'virtual-demo');
|
1
|
+
import node_net from "node:net";
|
2
|
+
import node_path, { dirname, join, resolve as external_node_path_resolve } from "node:path";
|
3
|
+
import { createRsbuild, mergeRsbuildConfig } from "@rsbuild/core";
|
4
|
+
import { pluginBabel } from "@rsbuild/plugin-babel";
|
5
|
+
import { pluginReact } from "@rsbuild/plugin-react";
|
6
|
+
import { pluginSolid } from "@rsbuild/plugin-solid";
|
7
|
+
import { RSPRESS_TEMP_DIR, normalizePosixPath, removeTrailingSlash } from "@rspress/shared";
|
8
|
+
import { cloneDeep, isEqual } from "lodash";
|
9
|
+
import node_fs, { writeFileSync } from "node:fs";
|
10
|
+
const staticPath = node_path.join(__dirname, '..', 'static');
|
11
|
+
const demoBlockComponentPath = node_path.join(staticPath, 'global-components', 'DemoBlock.tsx');
|
12
|
+
const virtualDir = node_path.join(process.cwd(), 'node_modules', RSPRESS_TEMP_DIR, 'virtual-demo');
|
14
13
|
const toValidVarName = (str)=>{
|
15
14
|
if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(str)) return str;
|
16
15
|
return str.replace(/[^0-9a-zA-Z_$]/g, '_').replace(/^([0-9])/, '_$1');
|
@@ -33,11 +32,11 @@ const getLangFileExt = (lang)=>{
|
|
33
32
|
};
|
34
33
|
function generateEntry(demos, framework, position, customEntry) {
|
35
34
|
const sourceEntry = {};
|
36
|
-
const entryCssPath =
|
35
|
+
const entryCssPath = join(staticPath, 'global-styles', 'entry.css');
|
37
36
|
if ('follow' === position) Object.values(demos).forEach((routes)=>{
|
38
37
|
routes.forEach((route)=>{
|
39
38
|
const { id, path: demoPath } = route;
|
40
|
-
const entry =
|
39
|
+
const entry = join(virtualDir, `${id}.entry.tsx`);
|
41
40
|
const solidEntry = `
|
42
41
|
import { render } from 'solid-js/web';
|
43
42
|
import ${JSON.stringify(entryCssPath)};
|
@@ -55,7 +54,7 @@ function generateEntry(demos, framework, position, customEntry) {
|
|
55
54
|
entryCssPath,
|
56
55
|
demoPath
|
57
56
|
}) : 'react' === framework ? reactEntry : solidEntry;
|
58
|
-
|
57
|
+
writeFileSync(entry, entryContent);
|
59
58
|
sourceEntry[id] = entry;
|
60
59
|
});
|
61
60
|
});
|
@@ -92,8 +91,8 @@ function generateEntry(demos, framework, position, customEntry) {
|
|
92
91
|
`;
|
93
92
|
const renderContent = 'solid' === framework ? solidContent : reactContent;
|
94
93
|
const id = `_${toValidVarName(key)}`;
|
95
|
-
const entry =
|
96
|
-
|
94
|
+
const entry = join(virtualDir, `${id}.entry.tsx`);
|
95
|
+
writeFileSync(entry, renderContent);
|
97
96
|
sourceEntry[id] = entry;
|
98
97
|
});
|
99
98
|
return sourceEntry;
|
@@ -304,26 +303,25 @@ const getExternalDemoContent = (tempVar)=>({
|
|
304
303
|
const remarkPlugin_demos = {};
|
305
304
|
const remarkCodeToDemo = function({ getRouteMeta, previewMode, defaultRenderMode, position, previewLanguages, previewCodeTransform }) {
|
306
305
|
const routeMeta = getRouteMeta();
|
307
|
-
|
306
|
+
node_fs.mkdirSync(virtualDir, {
|
308
307
|
recursive: true
|
309
308
|
});
|
310
309
|
const data = this.data();
|
311
310
|
return (tree, vfile)=>{
|
312
311
|
const demoMdx = [];
|
313
|
-
const route = routeMeta.find((meta)=>
|
312
|
+
const route = routeMeta.find((meta)=>normalizePosixPath(meta.absolutePath) === normalizePosixPath(vfile.path || vfile.history[0]));
|
314
313
|
if (!route) return;
|
315
314
|
const { pageName } = route;
|
316
315
|
remarkPlugin_demos[pageName] = [];
|
317
316
|
let title = pageName;
|
318
317
|
let index = 1;
|
319
|
-
let externalDemoIndex = 0;
|
320
318
|
function constructDemoNode(demoId, demoPath, currentNode, isMobileMode, externalDemoIndex) {
|
321
319
|
if (isMobileMode) {
|
322
320
|
const relativePathReg = new RegExp(/^\.\.?\/.*$/);
|
323
321
|
remarkPlugin_demos[pageName].push({
|
324
322
|
title,
|
325
323
|
id: demoId,
|
326
|
-
path: relativePathReg.test(demoPath) ? (
|
324
|
+
path: relativePathReg.test(demoPath) ? external_node_path_resolve(vfile.dirname || dirname(vfile.path), demoPath) : demoPath
|
327
325
|
});
|
328
326
|
} else demoMdx.push(getASTNodeImport(`Demo${demoId}`, demoPath));
|
329
327
|
const tempVar = `externalDemoContent${externalDemoIndex}`;
|
@@ -365,18 +363,6 @@ const remarkCodeToDemo = function({ getRouteMeta, previewMode, defaultRenderMode
|
|
365
363
|
title = firstChild && 'value' in firstChild && firstChild.value || title;
|
366
364
|
}
|
367
365
|
});
|
368
|
-
lib_visit(tree, 'mdxJsxFlowElement', (node)=>{
|
369
|
-
if ('code' === node.name) {
|
370
|
-
const src = (0, __WEBPACK_EXTERNAL_MODULE__rspress_shared_node_utils_78947ce6__.getNodeAttribute)(node, 'src');
|
371
|
-
if ('string' != typeof src) return;
|
372
|
-
const currentMode = (0, __WEBPACK_EXTERNAL_MODULE__rspress_shared_node_utils_78947ce6__.getNodeAttribute)(node, 'previewMode') ?? previewMode;
|
373
|
-
const isMobileAttr = (0, __WEBPACK_EXTERNAL_MODULE__rspress_shared_node_utils_78947ce6__.getNodeAttribute)(node, 'isMobile');
|
374
|
-
let isMobileMode = false;
|
375
|
-
isMobileMode = void 0 === isMobileAttr ? 'iframe' === currentMode : null === isMobileAttr ? true : 'object' == typeof isMobileAttr ? 'false' !== isMobileAttr.value : 'false' !== isMobileAttr;
|
376
|
-
const id = generateId(pageName, index++);
|
377
|
-
constructDemoNode(id, src, node, isMobileMode, externalDemoIndex++);
|
378
|
-
}
|
379
|
-
});
|
380
366
|
lib_visit(tree, 'code', (node)=>{
|
381
367
|
if ('hasVisited' in node) return;
|
382
368
|
if (node.lang && previewLanguages.includes(node.lang)) {
|
@@ -391,13 +377,13 @@ const remarkCodeToDemo = function({ getRouteMeta, previewMode, defaultRenderMode
|
|
391
377
|
});
|
392
378
|
const isMobileMode = node.meta?.includes('mobile') || node.meta?.includes('iframe') || !node.meta?.includes('web') && !node.meta?.includes('internal') && 'iframe' === previewMode;
|
393
379
|
const id = generateId(pageName, index++);
|
394
|
-
const virtualModulePath =
|
380
|
+
const virtualModulePath = join(virtualDir, `${id}.${getLangFileExt(node.lang)}`);
|
395
381
|
constructDemoNode(id, virtualModulePath, node, isMobileMode);
|
396
|
-
if (
|
397
|
-
const content =
|
382
|
+
if (node_fs.existsSync(virtualModulePath)) {
|
383
|
+
const content = node_fs.readFileSync(virtualModulePath, 'utf-8');
|
398
384
|
if (content === value) return;
|
399
385
|
}
|
400
|
-
|
386
|
+
node_fs.writeFileSync(virtualModulePath, value);
|
401
387
|
}
|
402
388
|
});
|
403
389
|
tree.children.unshift(...demoMdx);
|
@@ -414,7 +400,7 @@ function pluginPreview(options) {
|
|
414
400
|
const previewMode = options?.previewMode ?? (isMobile ? 'iframe' : 'internal');
|
415
401
|
const { devPort = 7890, framework = 'react', position = iframePosition, builderConfig = {}, customEntry } = iframeOptions;
|
416
402
|
const globalUIComponents = 'fixed' === position ? [
|
417
|
-
|
403
|
+
join(staticPath, 'global-components', 'Device.tsx')
|
418
404
|
] : [];
|
419
405
|
const getRouteMeta = ()=>src_routeMeta;
|
420
406
|
let lastDemos;
|
@@ -433,7 +419,7 @@ function pluginPreview(options) {
|
|
433
419
|
async beforeBuild (_, isProd) {
|
434
420
|
if (!isProd) try {
|
435
421
|
await new Promise((resolve, reject)=>{
|
436
|
-
const server =
|
422
|
+
const server = node_net.createServer();
|
437
423
|
server.unref();
|
438
424
|
server.on('error', reject);
|
439
425
|
server.listen({
|
@@ -449,18 +435,15 @@ function pluginPreview(options) {
|
|
449
435
|
}
|
450
436
|
},
|
451
437
|
async afterBuild (config, isProd) {
|
452
|
-
if (
|
453
|
-
lastDemos =
|
438
|
+
if (isEqual(remarkPlugin_demos, lastDemos)) return;
|
439
|
+
lastDemos = cloneDeep(remarkPlugin_demos);
|
454
440
|
await devServer?.server?.close();
|
455
441
|
devServer = void 0;
|
456
442
|
const sourceEntry = generateEntry(remarkPlugin_demos, framework, position, customEntry);
|
457
|
-
const outDir =
|
443
|
+
const outDir = join(config.outDir ?? 'doc_build', '~demo');
|
458
444
|
if (0 === Object.keys(sourceEntry).length) return;
|
459
445
|
const { html, source, output, performance } = clientConfig ?? {};
|
460
|
-
const rsbuildConfig =
|
461
|
-
dev: {
|
462
|
-
progressBar: false
|
463
|
-
},
|
446
|
+
const rsbuildConfig = mergeRsbuildConfig({
|
464
447
|
server: {
|
465
448
|
port: devPort,
|
466
449
|
printUrls: ()=>void 0,
|
@@ -477,7 +460,7 @@ function pluginPreview(options) {
|
|
477
460
|
},
|
478
461
|
output: {
|
479
462
|
...output,
|
480
|
-
assetPrefix: output?.assetPrefix ? `${
|
463
|
+
assetPrefix: output?.assetPrefix ? `${removeTrailingSlash(output.assetPrefix)}/~demo` : '/~demo',
|
481
464
|
distPath: {
|
482
465
|
root: outDir
|
483
466
|
},
|
@@ -485,7 +468,8 @@ function pluginPreview(options) {
|
|
485
468
|
},
|
486
469
|
plugins: config?.builderPlugins
|
487
470
|
}, builderConfig);
|
488
|
-
const rsbuildInstance = await
|
471
|
+
const rsbuildInstance = await createRsbuild({
|
472
|
+
callerName: 'rspress',
|
489
473
|
rsbuildConfig
|
490
474
|
});
|
491
475
|
const { pluginSass } = await import("@rsbuild/plugin-sass");
|
@@ -495,13 +479,13 @@ function pluginPreview(options) {
|
|
495
479
|
pluginLess()
|
496
480
|
]);
|
497
481
|
if ('solid' === framework) rsbuildInstance.addPlugins([
|
498
|
-
|
482
|
+
pluginBabel({
|
499
483
|
include: /\.(?:jsx|tsx)$/
|
500
484
|
}),
|
501
|
-
|
485
|
+
pluginSolid()
|
502
486
|
]);
|
503
487
|
if ('react' === framework) rsbuildInstance.addPlugins([
|
504
|
-
|
488
|
+
pluginReact()
|
505
489
|
]);
|
506
490
|
if (isProd) rsbuildInstance.build();
|
507
491
|
else devServer = await rsbuildInstance.startDevServer();
|
@@ -509,7 +493,7 @@ function pluginPreview(options) {
|
|
509
493
|
builderConfig: {
|
510
494
|
source: {
|
511
495
|
include: [
|
512
|
-
|
496
|
+
join(__dirname, '..')
|
513
497
|
]
|
514
498
|
},
|
515
499
|
tools: {
|
@@ -540,7 +524,6 @@ function pluginPreview(options) {
|
|
540
524
|
},
|
541
525
|
extendPageData (pageData, isProd) {
|
542
526
|
if (!isProd) pageData.devPort = port;
|
543
|
-
pageData.extraHighlightLanguages = previewLanguages;
|
544
527
|
},
|
545
528
|
markdown: {
|
546
529
|
remarkPlugins: [
|
@@ -557,11 +540,11 @@ function pluginPreview(options) {
|
|
557
540
|
]
|
558
541
|
],
|
559
542
|
globalComponents: [
|
560
|
-
|
543
|
+
join(staticPath, 'global-components', 'Container.tsx')
|
561
544
|
]
|
562
545
|
},
|
563
546
|
globalUIComponents,
|
564
|
-
globalStyles:
|
547
|
+
globalStyles: join(staticPath, 'global-styles', `${previewMode}.css`)
|
565
548
|
};
|
566
549
|
}
|
567
550
|
export { pluginPreview };
|
package/index.d.ts
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@rspress/plugin-preview",
|
3
|
-
"version": "2.0.0-beta.
|
3
|
+
"version": "2.0.0-beta.20",
|
4
4
|
"description": "A plugin for rspress to preview the code block in markdown/mdx file.",
|
5
5
|
"bugs": "https://github.com/web-infra-dev/rspress/issues",
|
6
6
|
"repository": {
|
@@ -23,36 +23,36 @@
|
|
23
23
|
"static"
|
24
24
|
],
|
25
25
|
"dependencies": {
|
26
|
-
"@rsbuild/core": "1.3
|
26
|
+
"@rsbuild/core": "~1.4.3",
|
27
27
|
"@rsbuild/plugin-babel": "~1.0.5",
|
28
|
-
"@rsbuild/plugin-less": "~1.2.
|
29
|
-
"@rsbuild/plugin-react": "~1.
|
30
|
-
"@rsbuild/plugin-sass": "~1.3.
|
28
|
+
"@rsbuild/plugin-less": "~1.2.4",
|
29
|
+
"@rsbuild/plugin-react": "~1.3.3",
|
30
|
+
"@rsbuild/plugin-sass": "~1.3.2",
|
31
31
|
"@rsbuild/plugin-solid": "~1.0.5",
|
32
32
|
"lodash": "4.17.21",
|
33
33
|
"qrcode.react": "^4.2.0",
|
34
|
-
"@rspress/shared": "2.0.0-beta.
|
35
|
-
"@rspress/theme-default": "2.0.0-beta.
|
34
|
+
"@rspress/shared": "2.0.0-beta.20",
|
35
|
+
"@rspress/theme-default": "2.0.0-beta.20"
|
36
36
|
},
|
37
37
|
"devDependencies": {
|
38
|
-
"@rslib/core": "0.
|
39
|
-
"@types/lodash": "^4.17.
|
38
|
+
"@rslib/core": "0.10.4",
|
39
|
+
"@types/lodash": "^4.17.20",
|
40
40
|
"@types/mdast": "^4.0.4",
|
41
|
-
"@types/node": "^
|
42
|
-
"@types/react": "^
|
43
|
-
"@types/react-dom": "^
|
41
|
+
"@types/node": "^22.8.1",
|
42
|
+
"@types/react": "^19.1.8",
|
43
|
+
"@types/react-dom": "^19.1.6",
|
44
44
|
"mdast-util-mdx-jsx": "^3.2.0",
|
45
45
|
"mdast-util-mdxjs-esm": "^2.0.1",
|
46
46
|
"react": "^19.1.0",
|
47
47
|
"react-dom": "^19.1.0",
|
48
48
|
"react-router-dom": "^6.29.0",
|
49
|
-
"rsbuild-plugin-publint": "^0.3.
|
49
|
+
"rsbuild-plugin-publint": "^0.3.2",
|
50
50
|
"typescript": "^5.8.2",
|
51
51
|
"unified": "^11.0.5",
|
52
52
|
"unist-util-visit": "^5.0.0"
|
53
53
|
},
|
54
54
|
"peerDependencies": {
|
55
|
-
"@rspress/core": "^2.0.0-beta.
|
55
|
+
"@rspress/core": "^2.0.0-beta.20",
|
56
56
|
"react": ">=18.0.0",
|
57
57
|
"react-router-dom": "^6.8.1"
|
58
58
|
},
|
@@ -1,12 +1,29 @@
|
|
1
|
-
@import url(@rspress/theme-default/bundle.css);
|
2
|
-
|
3
1
|
:root {
|
4
|
-
--rp-iframe-bg:
|
2
|
+
--rp-iframe-bg: #f6f8fa;
|
3
|
+
--rp-iframe-nav-bg: #ffffff;
|
5
4
|
}
|
6
5
|
|
6
|
+
/* TODO: support dark mode */
|
7
|
+
/* .dark {
|
8
|
+
--rp-iframe-bg: #242424;
|
9
|
+
--rp-iframe-nav-bg: #191d24;
|
10
|
+
} */
|
11
|
+
|
7
12
|
body {
|
8
|
-
background-color: var(--rp-iframe-bg);
|
13
|
+
background-color: var(--rp-iframe-bg) !important;
|
14
|
+
margin: 0px; /* copied from preflight.css */
|
15
|
+
}
|
16
|
+
|
17
|
+
/* #region copied from preflight.css */
|
18
|
+
*,
|
19
|
+
::before,
|
20
|
+
::after {
|
21
|
+
box-sizing: border-box; /* 1 */
|
22
|
+
border-width: 0; /* 2 */
|
23
|
+
border-style: solid; /* 2 */
|
24
|
+
border-color: theme('borderColor.DEFAULT', currentColor); /* 2 */
|
9
25
|
}
|
26
|
+
/* #endregion copied from preflight.css */
|
10
27
|
|
11
28
|
.preview-nav {
|
12
29
|
position: relative;
|
@@ -14,7 +31,7 @@ body {
|
|
14
31
|
align-items: center;
|
15
32
|
justify-content: center;
|
16
33
|
height: 56px;
|
17
|
-
background-color: var(--rp-
|
34
|
+
background-color: var(--rp-iframe-nav-bg) !important;
|
18
35
|
font-weight: 600;
|
19
36
|
font-size: 17px;
|
20
37
|
}
|