阅读 3309

使用TypeScript + React发布组件到Npm

最近封装了项目中使用的React地图组件,摸爬滚打发布到npm上;学到的知识点也比较散,如TypeScript、Commit规范/版本语义化、React组件测试、Npm发布更新、Readme模板、组件文档搭建等,有的知识点也是浅尝辄止(一知半解😱),先记录下来,后期有时间深挖。

目录

  1. 脚手架选择
  2. tsdx使用与配置
  3. TypeScript基础
  4. Commit规范
  5. Npm发布/配置/更新
  6. Readme模板
  7. React测试
  8. 组件文档搭建

1. 脚手架选择

发布前看了很多教程,都是自己配置Webpack、Babel、Rollup,辅助的还有ESLint、Jest,想想都头大,社区有很多开箱即用的零配置脚手架,我用的tsdx,自行参考吧。

有推荐或更好用的脚手架还请告知😘,留着下次用。

2. tsdx使用与配置

按照文档生成项目即可,需自己手动配置Less、ESLint,如下:

Less配置

安装依赖插件

$ yarn add rollup-plugin-postcss autoprefixer cssnano less --dev
复制代码

tsdx.config.js配置文件修改

const postcss = require('rollup-plugin-postcss');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');

module.exports = {
  rollup(config, options) {
    config.plugins.push(
      postcss({
        plugins: [
          autoprefixer(),
          cssnano({
            preset: 'default',
          }),
        ],
        inject: false,
        // only write out CSS for the first bundle (avoids pointless extra files):
        // extract: !!options.writeMeta,
        extract: 'mapLine.min.css',
      })
    );
    return config;
  },
};
复制代码

ESLint配置

脚手架创建的项目没有.eslintrc.js.eslintignore文件,需手动添加。

也可以用yarn lint --write-file生成,文档有说明。

.eslintrc.js文件:

module.exports = {
  "extends": [
    "react-app",
    "prettier/@typescript-eslint",
    "plugin:prettier/recommended" // 重点
  ],
  "settings": {
    "react": {
      "version": "detect"
    }
  }
}
复制代码

Start 预览

源码在src目录下,example目录可预览,需要分别在根目录和example下安装依赖和Start,先在根目录Startexample Start

参考教程

3. TypeScript基础

刚开始使用TypeScript很可能会写出AnyScript风格的代码,画风如下🙋(我写的)。

阮一峰推荐教程:TypeScript 入门教程很赞 👍。

我是先用jsx写出功能,又迁移到TypeScript,记录几个常用的Interface定义语法。

非必选

在类型定义中,有些属性为非必须参数,使用?标识。

interface anime {
  show?: boolean;
  icon?: string;
  pathColor?: string;
  type?: string;
}
复制代码

数组类型

在数组中放置对象,可使用Array<InterfaceName>InterfaceName[]定义。

interface pathItem {
  iconText: string;
  title: string;
  theme?: number;
}

interface defaultOptions {
  path: Array<pathItem>;
  pathColor?: string;
  donePath?: pathItem[];
}
复制代码

未知属性、继承

已知属性名但不知道类型,可以用any定义,未知属性名已知类型可使用[propName: string]: string;定义;为了不重复定义,使用extends关键词继承其他interface

代码:

interface pathItem extends donePathItem {
  iconText: string;
  title: string;
  [propName: string]: any;
}

interface donePathItem {
  LT: number[];
}
复制代码

4. Commit规范

之前对Git规范不是很深入,只有使用 git rebase合并一些无用commit信息,推荐下开源的规范文档。

7个类别

翻看了几个开源项目的commit和规范说明,主要是标明commit的7个类别。

- feat:新功能(feature)
- fix:修补bug
- docs:文档(documentation)
- style: 格式(不影响代码运行的变动)
- refactor:重构(即不是新增功能,也不是修改bug的代码变动)
- test:增加测试
- chore:构建过程或辅助工具的变动
复制代码

VsCode插件使用

我个人主要是在VsCode中提交Commit,推荐2个插件。

快捷生成message:git-commit-plugin

Commit记录展示:Git History

命令行配置

在命令行中使用Git可以使用Commitizen生成Commit message模板,并用Commitlint检查;参见教程

5. Npm发布/配置/更新

注册不再赘述,我这么笨的人都可以搞定,聪明的你一定没问题👩‍🎓‍,以下是细节。

打包路径

使用yarn build打包完以后,文件生成到dist目录,检查package.json中的main与打包路径一致即可。

主页与仓库地址

正确配置homepagerepository才能在Npm介绍中展示出来。

{
  "homepage": "http://nihaojob.gitee.io/carui/#/carui/maps",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/nihaojob/mapLine.git"
  },
}
复制代码

发布

国内很多小伙伴设置过npm镜像源,记得还原为官方,然后按照提示输入信息就成功了,简单吧💁 ?

$ npm config set registry https://registry.npmjs.org/
$ npm publish
复制代码

更新

修改Readem文件后,使用以下命令更新。

官方文档:docs.npmjs.com/about-packa…

$ npm version patch
$ npm publish
复制代码

版本也要遵循规范,没有来得及深挖,先留坑位🏌。

6. Readme模板

Readme应该告诉人们为什么应该使用以及如何安装、使用。留坑优化🏌。

模板

推荐一份高Start的模板:standard-readme

也可以使用readme-md-generator交互式的生成Readme文件。

徽标生成

shields.io可根据GitHub仓库自动生成徽标。

CI徽标

GitHub配置的Actions成功执行,就可以从CI页面拷贝徽标。

阮一峰:GitHub Actions 入门教程

测试覆盖率徽标

多种多样的的工具和方法,我还没学会,等我更新🏌。

7. React测试

tsdx并没有自动生成jest.config.js文件,如需定义可以手动增加,列下遇见的问题。

组件中引入less报错

安装依赖

$ yarn add --dev identity-obj-proxy
复制代码

package.json配置moduleNameMapper

{
 "jest": {
    "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
      "\\.(css|less)$": "identity-obj-proxy"
    }
  },
}
复制代码

document is not defined

在测试文件头部增加环境说明,例子

/**
 * @jest-environment jsdom
 */
复制代码

引入第三方sdk

我在组件内有使用高德的全局变量,需要高德的SDK文件加载完毕后再执行测试,参考了react-amap的实现。

// PromiseScript加载
function getAmapuiPromise() {
  const script = buildScriptTag(
    'https://webapi.amap.com/maps?v=1.4.15&key=你的key&plugin=AMap.Driving'
  );
  const p = new Promise(resolve => {
    script.onload = () => {
      resolve();
    };
  });
  document.body.appendChild(script);
  return p;
}
// 创建script标签
function buildScriptTag(src: string) {
  const script = document.createElement('script');
  script.type = 'text/javascript';
  script.async = true;
  script.defer = true;
  script.src = src;
  return script;
}

describe('it', () => {
  it('正常渲染', () => {
    // 加载高德后执行
    getAmapuiPromise().then(() => {
      initDemo();
    });
    function initDemo() {
      const div = document.createElement('div');
      ReactDOM.render(<Maps {...options} />, div);
      ReactDOM.unmountComponentAtNode(div);
    }
  });

});
复制代码

8. 组件文档搭建

有很多类似的工具,主要是为了解决组件文档的问题。

我选了dumi,原因是文档好看💁,dumi刚发布不久,但使用体验真的不错。

官方介绍为:是一款基于 Umi 打造、为组件开发场景而生的文档工具。

文档源码:gitee.com/nihaojob/Ca…

留坑与总结

还有很多没有搞定的事情,需要学的也越来越多,为了质量和落地,先列个ToDoList。

  • VsCode Jest debug配置
  • React Jest 补充测试用例
  • 测试覆盖率徽标
  • Readme按照模板修改
  • 版本语义化落地
  • np工具熟悉
  • TypeScript深入学习

才疏学浅,恳请斧正,还请Stars、点赞鼓励💁。

GitHub项目:github.com/nihaojob/ma…