From a1bf380bfe5dfd6402ac0bf2648428a9ce7f9fe5 Mon Sep 17 00:00:00 2001 From: ocean_gao Date: Tue, 26 Sep 2023 14:38:00 +0800 Subject: [PATCH] =?UTF-8?q?chore(docs):=20=E6=96=87=E6=A1=A3=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E6=94=AF=E6=8C=81=E6=96=B0=E7=9A=84=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=BC=95=E5=85=A5=E6=96=B9=E5=BC=8F=20(#476)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(docs): 文档构建支持新的组件引入方式 * style: 代码格式规范 * refactor: docs构建相关代码规范 * docs: 文档规范 * chore(docs): 文档自动增加code逻辑 --- .prettierrc.js | 2 +- .stylelintrc.js | 22 +++--- docs/.vitepress/components/tag/index.md | 34 +++++--- docs/.vitepress/scripts/constants.js | 8 +- docs/.vitepress/scripts/genComponentDoc.js | 90 +++++++++++++--------- docs/.vitepress/scripts/transform.js | 68 ---------------- jest.setup.js | 2 +- 7 files changed, 90 insertions(+), 136 deletions(-) delete mode 100644 docs/.vitepress/scripts/transform.js diff --git a/.prettierrc.js b/.prettierrc.js index 5b52bed2..5f5d0dda 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -5,4 +5,4 @@ module.exports = { tabWidth: 4, useTabs: false, printWidth: 80, -} \ No newline at end of file +}; diff --git a/.stylelintrc.js b/.stylelintrc.js index 8b69a928..e7a21793 100644 --- a/.stylelintrc.js +++ b/.stylelintrc.js @@ -4,16 +4,14 @@ module.exports = { 'stylelint-config-rational-order', 'stylelint-config-prettier', // 排除与 prettier 冲突的 rule ], - plugins: [ - 'stylelint-declaration-block-no-ignored-properties' - ], + plugins: ['stylelint-declaration-block-no-ignored-properties'], // https://stylelint.docschina.org/user-guide/rules/ rules: { - "indentation": 4, - "no-empty-source": null, - "max-empty-lines": 2, - "no-duplicate-selectors": null, - "at-rule-no-unknown": null, + indentation: 4, + 'no-empty-source': null, + 'max-empty-lines': 2, + 'no-duplicate-selectors': null, + 'at-rule-no-unknown': null, 'comment-empty-line-before': null, 'no-invalid-double-slash-comments': null, 'no-descending-specificity': null, @@ -28,9 +26,9 @@ module.exports = { // https://github.com/stylelint/stylelint/blob/main/docs/migration-guide/to-14.md overrides: [ { - files: ["**/*.less"], - customSyntax: "postcss-less" - } + files: ['**/*.less'], + customSyntax: 'postcss-less', + }, ], ignoreFiles: [], -} \ No newline at end of file +}; diff --git a/docs/.vitepress/components/tag/index.md b/docs/.vitepress/components/tag/index.md index 1732198e..55586838 100644 --- a/docs/.vitepress/components/tag/index.md +++ b/docs/.vitepress/components/tag/index.md @@ -14,45 +14,59 @@ app.use(FTag); ### 基础用法 ---BASIC +:::demo +basic.vue +::: ### 可移除标签 设置 `closable` 属性可以定义一个标签是否可移除。 ---CLOSABLE +:::demo +closable.vue +::: ### 动态编辑标签 动态编辑标签可以通过点击标签关闭按钮后触发的 `close` 事件来实现 ---EDIT +:::demo +edit.vue +::: ### 不同尺寸 Tag 组件提供了以下几种尺寸,可以在不同场景下选择合适的尺寸。 ---SIZE +:::demo +size.vue +::: ### 不同主题 Tag 组件提供了三个不同的主题。 ---THEME +:::demo +theme.vue +::: ### 带图标 ---WITHICON +:::demo +withIcon.vue +::: ### 结合 Form 组件 ---WITHFORM +:::demo +withForm.vue +::: ### 超长省略 ---TOOLTIP - ---CODE +:::demo +tooltip.vue +::: ## Tag Props diff --git a/docs/.vitepress/scripts/constants.js b/docs/.vitepress/scripts/constants.js index 2be71643..17ed94e6 100644 --- a/docs/.vitepress/scripts/constants.js +++ b/docs/.vitepress/scripts/constants.js @@ -1,12 +1,6 @@ exports.SCRIPT_TEMPLATE = ` - `; diff --git a/docs/.vitepress/scripts/genComponentDoc.js b/docs/.vitepress/scripts/genComponentDoc.js index da9caebb..71836cb5 100644 --- a/docs/.vitepress/scripts/genComponentDoc.js +++ b/docs/.vitepress/scripts/genComponentDoc.js @@ -1,6 +1,5 @@ /* eslint-disable @typescript-eslint/no-var-requires */ const path = require('path'); -const fs = require('fs'); const fse = require('fs-extra'); const shiki = require('shiki'); @@ -12,8 +11,8 @@ const CODE_PATH = path.join( ); function getDemoCode() { - if (fs.existsSync(CODE_PATH)) { - return JSON.parse(fs.readFileSync(CODE_PATH, 'utf-8')); + if (fse.existsSync(CODE_PATH)) { + return JSON.parse(fse.readFileSync(CODE_PATH, 'utf-8')); } return { @@ -65,14 +64,14 @@ const highlight = async (code, lang = 'vue') => { .replace(/^/, '
');
 };
 
-async function genComponent(dir, name) {
+async function genComponentExample(dir, name) {
     const output = genOutputPath(name);
     const indexPath = path.join(dir, 'index.md');
-    if (!fs.existsSync(indexPath)) return;
+    if (!fse.existsSync(indexPath)) return;
 
-    let fileContent = fs.readFileSync(indexPath, 'utf-8');
+    let fileContent = fse.readFileSync(indexPath, 'utf-8');
 
-    const demos = fs.readdirSync(dir);
+    const demos = fse.readdirSync(dir);
     const demoMDStrs = [];
     const scriptCode = {
         imports: [],
@@ -82,7 +81,7 @@ async function genComponent(dir, name) {
     for (const filename of demos) {
         const fullPath = path.join(dir, filename);
         if (
-            fs.statSync(fullPath).isFile() &&
+            fse.statSync(fullPath).isFile() &&
             path.extname(fullPath) === '.vue'
         ) {
             const demoContent = [];
@@ -100,7 +99,7 @@ async function genComponent(dir, name) {
             fse.outputFileSync(
                 tempCompPath,
                 handleCompDoc(
-                    fs.readFileSync(fullPath, 'utf-8'),
+                    fse.readFileSync(fullPath, 'utf-8'),
                     name,
                     demoName,
                 ),
@@ -109,19 +108,23 @@ async function genComponent(dir, name) {
 
             demoContent.push(`<${compName} />`);
 
-            const rawCode = fs.readFileSync(fullPath, 'utf-8');
+            const rawCode = fse.readFileSync(fullPath, 'utf-8');
             tempCode[`${name}.${demoName}`] = rawCode;
             tempCode[`${name}.${demoName}-code`] = await highlight(rawCode);
 
-            const matchStr = new RegExp(
-                `--${demoName.toLocaleUpperCase()}\\s`,
-                'i',
+            const dashMatchRegExp = new RegExp(`--${demoName}`, 'ig');
+            const colonMatchRegExp = new RegExp(
+                `:::demo[\\s]*${demoName}\.vue[\\s]*:::`,
+                'g',
             );
-            if (matchStr.test(fileContent)) {
-                fileContent = fileContent.replace(
-                    matchStr,
-                    demoContent.join('\n\n\n'),
-                );
+
+            if (
+                dashMatchRegExp.test(fileContent) ||
+                colonMatchRegExp.test(fileContent)
+            ) {
+                fileContent = fileContent
+                    .replace(dashMatchRegExp, demoContent.join('\n\n\n'))
+                    .replace(colonMatchRegExp, demoContent.join('\n\n\n'));
             } else {
                 demoMDStrs.push(...demoContent);
             }
@@ -131,13 +134,26 @@ async function genComponent(dir, name) {
     const scriptStr = SCRIPT_TEMPLATE.replace(
         'IMPORT_EXPRESSION',
         scriptCode.imports.join('\n'),
-    ).replace('COMPONENTS', scriptCode.components.join(',\n'));
+    );
 
     demoMDStrs.push(scriptStr);
 
+    const dashCodeMatchRegExp = new RegExp(`--CODE`);
+    const colonCodeMatchRegExp = new RegExp(`:::code[\\s\\S]*:::`);
+    if (
+        !(
+            dashCodeMatchRegExp.test(fileContent) ||
+            colonCodeMatchRegExp.test(fileContent)
+        )
+    ) {
+        const appendContent = '\n\n:::code:::\n\n';
+        fileContent = fileContent + appendContent;
+    }
     fse.outputFileSync(
         output,
-        fileContent.replace('--CODE', demoMDStrs.join('\n\n')),
+        fileContent
+            .replace(dashCodeMatchRegExp, demoMDStrs.join('\n\n'))
+            .replace(colonCodeMatchRegExp, demoMDStrs.join('\n\n')),
     );
 
     if (Object.keys(tempCode).length) {
@@ -149,9 +165,9 @@ async function genComponent(dir, name) {
 }
 
 async function genComponents(src) {
-    const components = fs.readdirSync(src);
+    const components = fse.readdirSync(src);
     for (const name of components) {
-        await genComponent(path.join(src, name), name);
+        await genComponentExample(path.join(src, name), name);
     }
 }
 
@@ -160,14 +176,15 @@ async function watch(src) {
         dir: src,
         debounce: 50,
     });
+
     await watcher.init();
-    const gen = (data) => {
-        const fullPath = path.join(src, data.path);
+
+    const handleGen = (data) => {
         // 只监听目录变更
-        if (fs.statSync(fullPath).isDirectory()) {
+        if (data.stats.isDirectory()) {
             const pathSeps = data.path.split(path.sep);
-            const componentName = pathSeps[0];
-            genComponent(path.join(src, componentName), componentName);
+            const pkgName = pathSeps[0];
+            genComponentExample(path.join(src, pkgName), pkgName);
         }
     };
     const handleDelete = (data) => {
@@ -185,26 +202,25 @@ async function watch(src) {
             });
 
             if (hasDeleteCode) {
-                fs.writeFileSync(CODE_PATH, JSON.stringify(code, null, 2));
+                fse.writeFileSync(CODE_PATH, JSON.stringify(code, null, 2));
             }
             const outputPath = genOutputPath(name);
-            if (fs.existsSync(outputPath)) {
-                fs.unlinkSync(outputPath);
+            if (fse.existsSync(outputPath)) {
+                fse.unlinkSync(outputPath);
             }
         } else if (data.stats.isFile() && path.extname(data.path) === '.vue') {
+            const pkgName = pathSeps[0];
             // 删除组件属性
-            const codekey = `${pathSeps[0]}.${path.basename(
-                data.path,
-                '.vue',
-            )}`;
+            const codekey = `${pkgName}.${path.basename(data.path, '.vue')}`;
             if (code[codekey]) {
                 delete code[codekey];
-                fs.writeFileSync(CODE_PATH, JSON.stringify(code, null, 2));
+                fse.writeFileSync(CODE_PATH, JSON.stringify(code, null, 2));
             }
-            genComponent(path.join(src, pathSeps[0]), pathSeps[0]);
+            genComponentExample(path.join(src, pkgName), pkgName);
         }
     };
-    watcher.on('+', gen);
+
+    watcher.on('+', handleGen);
     watcher.on('-', handleDelete);
 }
 
diff --git a/docs/.vitepress/scripts/transform.js b/docs/.vitepress/scripts/transform.js
deleted file mode 100644
index 0e074cbf..00000000
--- a/docs/.vitepress/scripts/transform.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/* eslint-disable @typescript-eslint/no-var-requires */
-const path = require('path');
-const fs = require('fs');
-const fse = require('fs-extra');
-
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-function genComponent(dir, name) {
-    const indexPath = path.join(dir, 'index.md');
-    if (!fs.existsSync(indexPath)) return;
-
-    let fileContent = fs.readFileSync(indexPath, 'utf-8');
-
-    const demos = fs.readdirSync(dir);
-    const demoMDStrs = [];
-    for (const demoName of demos) {
-        const fullPath = path.join(dir, demoName);
-        if (fs.statSync(fullPath).isDirectory(fullPath)) {
-            const codePath = path.join(fullPath, 'index.vue');
-            const textPath = path.join(fullPath, 'index.md');
-            const demoContent = [];
-            if (fs.existsSync(textPath)) {
-                demoContent.push(fs.readFileSync(textPath, 'utf-8'));
-            }
-
-            if (fs.existsSync(codePath)) {
-                fs.writeFileSync(
-                    fullPath + '.vue',
-                    fs.readFileSync(codePath, 'utf-8'),
-                );
-                demoContent.push(`--${demoName.toLocaleUpperCase()}`);
-            }
-            if (
-                demoContent.length &&
-                fileContent.indexOf(
-                    `PREVIEW_${demoName.toLocaleUpperCase()}`,
-                ) !== -1
-            ) {
-                fileContent = fileContent.replace(
-                    `PREVIEW_${demoName.toLocaleUpperCase()}`,
-                    demoContent.join('\n\n'),
-                );
-            } else {
-                demoMDStrs.push(...demoContent);
-            }
-
-            fse.removeSync(fullPath);
-        }
-    }
-
-    demoMDStrs.push('--CODE');
-
-    fs.writeFileSync(
-        indexPath,
-        fileContent.replace('PREVIEW_CODE', demoMDStrs.join('\n\n')),
-    );
-}
-
-function genComponents(src) {
-    const components = fs.readdirSync(src);
-    for (const name of components) {
-        genComponent(path.join(src, name), name);
-    }
-}
-
-(() => {
-    const src = path.join(process.cwd(), './docs/.vitepress/components');
-    genComponents(src);
-})();
diff --git a/jest.setup.js b/jest.setup.js
index c6df8e11..f66f6239 100644
--- a/jest.setup.js
+++ b/jest.setup.js
@@ -1 +1 @@
-import { config } from '@vue/test-utils';
+// import { config } from '@vue/test-utils';