组件库设计 | 让你的React组件获得代码补全和属性提示功能

简介: 博主在开发组件库以及实际项目测试过程中,突然发现Concis的组件都需要去手写,而回想以前使用antd/el组件库时都是可以自动生成代码块的,并且移到标签中可以看到对应的一些提示信息,于是博主开始探索Vscode插件的开发了。

您好,如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~

写在前面

React组件库Concis在大量募集小伙伴一起参与开源项目开发,目前仍有很多计划需要去实施,包含PC端组件扩充、移动端组件开发、Concis生态插件开发等等,具体可以看此文:

React组件库Concis,寻求社区有兴趣的小伙伴加入...

Concis组件库相关链接,希望大家多多鼓励支持、多多Star,给作者更多的动力

Github
线上文档

需求来源

博主在开发组件库以及实际项目测试过程中,突然发现Concis的组件都需要去手写,而回想以前使用antd/el组件库时都是可以自动生成代码块的,并且移到标签中可以看到对应的一些提示信息,于是博主开始探索Vscode插件的开发了。

生成项目

首先全局安装vscode脚手架

npm install -g yo generator-code

安装完成后在命令行输入

yo code

在提示中直接选择New Extension,生成一个vscode插件工程,下面几项是vscode所提供单独功能开发的脚手架,可以理解成小插件,由于这里是具体化到整个Concis工程,因此选择第一个。

在这里插入图片描述

接下来输入一些插件的命名即可生成项目,经过处理后的项目目录是这样的:

在这里插入图片描述
这里后续会讲到自定义打包的一些配置。

代码补全(snippets)

代码补全功能相对简单,只需在项目中创建snippets.json文件,在里面配置snippets就可以。
有一个网站可以帮助我们快速的创建 code snippet https://snippet-generator.app/

在这里插入图片描述

把对应的snippet生成,复制到snippets.json中即可,就像这样:

在这里插入图片描述

同时在package.json中配置contributes,指定插件所生效的文件,博主是React组件库,因此定了js/ts/jsx/tsx四种文件类型

在这里插入图片描述

很简单,不需要你动脑筋写一行代码,自动补全的功能实现了。

智能提示

提示的话就需要我们入门一下,写一写vscode的api啦,打开项目生成的extension.ts文件,将代码写成这样:

import * as vscode from 'vscode'

const compileFiles = ['react', 'typescript', 'javascript', 'javascriptreact', 'typescriptreact'];

function providerHover(document: vscode.TextDocument, position: vscode.Position) {
   
   }

export function activate(context: vscode.ExtensionContext) {
   
   
  context.subscriptions.push(
    vscode.languages.registerHoverProvider(compileFiles, {
   
   
      provideHover,
    }),
  );
}

export function deactivate() {
   
   }

上面代码我们通过vscode.languages.registerHoverProvider注册了鼠标移入事件,并通过compileFiles指定了文件类型,而插件所要实现的业务功能就在provideHover中实现。

function provideHover(document: vscode.TextDocument, position: vscode.Position) {
   
   
  //移入Concis组件Dom,出现介绍
  const line = document.lineAt(position);
  let isConcisComponentDom = false;
  let matchComponent = '';
  for (let i = 0; i < componentList.length; i++) {
   
   
    const component = componentList[i];
    if (line.text.includes(`<${
     
     component}`)) {
   
   
      isConcisComponentDom = true;
      matchComponent = component;
    }
  }
  if (isConcisComponentDom) {
   
   
    const isCN = vscode.env.language === 'zh-cn';
    let componentDocPath = '';
    for (let i = 0; i < matchComponent.length; i++) {
   
   
      const str = matchComponent[i];
      if (i !== 0 && str.charCodeAt(0) >= 65 && str.charCodeAt(0) <= 90) {
   
   
        componentDocPath += '-';
      }
      componentDocPath += str;
    }
    let text = isCN
      ? `查看${
     
     matchComponent}组件官方文档\n
Concis -> http://react-view-ui.com:92/#/common/${
     
     componentDocPath.toLowerCase()}`
      : `View the official documentation of the Button component\n
Concis -> http://react-view-ui.com:92/#/common/${
     
     componentDocPath.toLowerCase()}`;

    return new vscode.Hover(text);
  }
}

接下来我们解读一下这里面的功能:

  1. 首先,通过document.lineAt获取代码行,判断Concis组件关键词是否出现在代码内容line.text中;
  2. 对满足条件的情况,获取组件线上文档地址,编辑提示的内容信息,对应代码段中的text
  3. text通过new vscode.Hover返回;

至此,代码自动补全+智能提示功能完成了,来看一下效果吧:

请添加图片描述

请添加图片描述

打包发布

1.第一步,全局安装vscode打包工具

npm i -g vsce

2.第二步,创建vscode账号

首先访问 https://login.live.com/ 登录你的Microsoft账号,没有的先注册一个,然后访问: https://aka.ms/SignupAzureDevOps,如果你从来没有使用过Azure,那么就要先创建一个Azure DevOps 组织,默认会创建一个以邮箱前缀为名的组织。

在这里插入图片描述

3.第三步,创建组织令牌

在这里插入图片描述
点击右上角的用户设置,点击创建新的个人访问令牌。

在这里插入图片描述

这里请选择All accessible organizations 否则会无法部署插件。

创建完毕会出现一个token,请手动记录下来这个token,因为官方不会为你保存,并且这个token在发布时会用到。

4.第四步,创建publisher

前往插件市场https://marketplace.visualstudio.com/创建一个publisher,并在package.json中添加
publisher字段,名字保持一致。

配置

好了,到这里你已经完成了准备工作。

博主通过rollup将代码打包后再使用vscode内置的打包发布,因此打包流程如下:

  1. rollup打包
  2. vsce打包
  3. vsce发布

rollup.config.js配置如下:

import typescript from 'rollup-plugin-typescript2';
import clear from 'rollup-plugin-clear';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import {
   
    terser } from 'rollup-plugin-terser';
import {
   
    uglify } from 'rollup-plugin-uglify';

export default {
   
   
  input: ['./src/extension.ts'],
  output: [
    {
   
   
      file: 'dist/extension.js',
      format: 'cjs',
      name: 'cjs.js',
    },
  ],
  plugins: [
    typescript(), // 会自动读取 文件tsconfig.json配置
    clear({
   
   
      targets: ['dist'],
    }),
    resolve(),
    commonjs(),
    terser(),
    uglify(),
  ],
  external: ['react', 'react-dom'],
};

在package.json中配置一下命令行,让我们的打包发布过程像如下所说的顺序:

    "scripts": {
   
   
        "upgrade": "node ../../scripts/replace-version-in-vscode.ts",                    //升级package.json中版本
        "compile": "rollup -c ./rollup.config.js",                                        //rollup打包                                                        
        "build": "vsce package",                                                        //vsce打包                                    
        "generate:readme": "node ../../scripts/vscode/generate-vscode-snippet.ts",        //生成README.md内容
        "publish": "npm run compile && npm run build && vsce publish"                    //部署
    },

这里upgradegenerate:readme是博主针对于Concis组件库自己加的两个脚本,我们看一下publish,可以看到按上述所讲的顺序进行打包构建,这样代码层面的配置已经做完了。

执行npm run publish,输入之前创建保存的token,这样就发布成功了。

请添加图片描述

看到这里,你已经掌握了开发一个vscode工程并打包发布的内容了,博主针对组件库的需求进行的扩展,也就是上面所提到的两个命令:

npm run upgrade                //升级package.json中版本
npm run generate:readme        //根据组件项目目录,自动生成README.md

Concis-snippets插件的介绍可以看到,下面有一段表格,表格介绍了每个snippet对应的介绍,看到这你应该想象到了吧?此时博主又开发了两个组件,但是不想手动去更新README.md,这时就需要自定义脚本了。

自动更新README.md

//根据项目目录写入vscode-snippets README.md
const fs = require('fs-extra');
const path = require('path');

const baseTemplate = fs.readFileSync(path.join(__dirname, 'base-template.md'), 'utf-8');
const componentList = fs.readdirSync(path.join(__dirname, '../../packages/concis-react/src'));

let tableTemplate = '';

componentList.forEach((f) => {
   
   
  if (f[0].charCodeAt(0) >= 65 && f[0].charCodeAt(0) <= 90) {
   
   
    //组件
    tableTemplate += `|c${f.toLowerCase()}|snippet a Concis ${f} Component|\n`;
  }
});

const fileContent = `${baseTemplate}${tableTemplate}`;
console.log(fileContent);

fs.writeFile(
  path.resolve(__dirname, '../../packages/concis-vscode-snippets/README.md'),
  fileContent,
  'utf-8',
).then(() => {
   
   
  console.log('生成concis-vscode-snippets 成功'); // eslint-disable-line
});

这里我们有一个基础模板,放着README.md上部分一直不会变的内容,对应代码中base-template.md,然后读取了组件目录,将基础模板和表格内容拼接起来,就可以了。

自动升级package.json版本

//更新concis-vscode-snippets/package.json中的版本
const fs = require('fs-extra');
const path = require('path');
const {
   
    version } = require('../packages/concis-vscode-snippets/package.json');

const fileText = fs.readFileSync(
  path.join(__dirname, '../packages/concis-vscode-snippets/package.json'),
  'utf-8',
);

const replacedVersion = fileText.split('\n').map((t) => {
   
   
  if (/"version":/.test(t)) {
   
   
    let newVersion = version.split('.');
    let [first, secord, third] = newVersion;
    if (third >= 10 || secord >= 10) {
   
   
      if (third >= 10) {
   
   
        third = 0;
        secord = Number(secord) + 1;
      }
      if (secord >= 10) {
   
   
        third = 0;
        secord = 0;
        first = Number(first) + 1;
      }
    } else {
   
   
      third = Number(third) + 1;
    }

    newVersion[newVersion.length - 1] = Number(newVersion[newVersion.length - 1]) + 1;
    console.log(`"version": "${first}.${secord}.${
     
     third}"`);
    return `  "version": "${first}.${secord}.${
     
     third}",`;
  }
  return t;
});

fs.outputFile(
  path.resolve(__dirname, '../packages/concis-vscode-snippets/package.json'),
  replacedVersion.join('\n'),
).then(() => {
   
   
  console.log('替换 package.json 中的 version 成功!'); // eslint-disable-line
});

代码实现了一个替换package.json文件中版本的功能,有了这两个自动脚本的支持,我们就可以把publish改成这样:

"scripts": {
   
   
    "upgrade": "node ../../scripts/replace-version-in-vscode.ts",                                
    "compile": "rollup -c ./rollup.config.js",                                                                
    "build": "vsce package",                                                                                                        
    "generate:readme": "node ../../scripts/vscode/generate-vscode-snippet.ts",        
    "publish": "npm run upgrade && npm run generate:readme && npm run compile && npm run build && vsce publish"                                
}

总结

本文通过博主对于Concis实际案例,讲解了开发一个vscode插件从准备工作到功能实现最后打包发布的全过程,如果文章有用,希望多多支持。

Concis组件库地址

请添加图片描述

Concis组件库线上链接:http://react-view-ui.com:92
github:https://github.com/fengxinhhh/Concis
npm:https://www.npmjs.com/package/concis

开源不易,欢迎学习和体验,喜欢请多多支持,有问题请留言,如果此文对你有帮助,博主需要你的支持,感谢。

目录
相关文章
|
2月前
|
前端开发
React查询、搜索类功能的实现
React查询、搜索类功能的实现
17 0
|
3月前
|
资源调度 前端开发 JavaScript
React 的antd-mobile 组件库,嵌套路由
React 的antd-mobile 组件库,嵌套路由
40 0
|
3月前
|
前端开发
React 仿淘宝图片放大镜功能
React 仿淘宝图片放大镜功能
|
1月前
|
前端开发 Android开发 iOS开发
应用研发平台EMAS使用 aliyun-react-native-push 库接入推送和辅助通道,推送都可以收到,但是在App切到后台或者杀掉进程之后就收不到推送了,是需要配置什么吗?
【2月更文挑战第31天】应用研发平台EMAS使用 aliyun-react-native-push 库接入推送和辅助通道,推送都可以收到,但是在App切到后台或者杀掉进程之后就收不到推送了,是需要配置什么吗?
32 2
|
2月前
|
JavaScript 前端开发
在React和Vue中实现锚点定位功能
在React和Vue中实现锚点定位功能
25 1
|
2月前
|
存储 前端开发 中间件
React组件间的通信
React组件间的通信
15 1
|
2月前
|
前端开发 应用服务中间件 数据库
react服务端组件
react服务端组件
21 0
|
2月前
|
前端开发 JavaScript
快速上手React:从概述到组件与事件处理
快速上手React:从概述到组件与事件处理
|
3月前
|
前端开发 JavaScript API
React组件生命周期
React组件生命周期
74 1
|
3月前
|
资源调度 前端开发 JavaScript
React组件
React组件
41 0