npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

chtty-component

v0.1.3

Published

web component

Downloads

7

Readme

从零学习搭建开发项目业务组件库

搭建模版工程

  • 依赖安装

    1. 基础配置

      • webpack webpack-cli
      • clean-webpack-plugin / html-webpack-plugin
    2. 开发配置

      • webpack5 已集成 webpack-dev-server
      • webpack serve
    3. react 配置

      • react react-dom

      • typescript @types/react @types/react-dom babel-loader @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript

      • babel 配置(会根据预设的浏览器兼容列表从 stage-4 选取必须的 plugin)

        • @babel/preset-env

          • 三个概念
            • 最新 ES 语法:比如,箭头函数
            • 最新 ES API:,比如,Promise
            • 最新 ES 实例方法:比如,String.prototype.includes
          • useBuiltIns:
            • false,无视 browserslist 配置引入 polyfill
              • 需要入口手动引入 import '@babel/polyfill';
            • entry,根据 browserslist 配置全量引入 polyfill
              • 需要指定 corejs,即使用腻子定义的版本
                • corejs v2 老 @babel/preset-env 会引入 v2
                  • 入口手动引入 import '@babel/polyfill'
                • corejs 指定为 3 版本时,使用方式
                  • 则 import '@babel/polyfill' 需要改成 import 'core-js/stable';import 'regenerator-runtime/runtime';
                  • 单独安装 core-js@3
            • usage
              • 会根据配置的浏览器兼容,以及你代码中用到的 API 来进行 polyfill
              • 需要指定 corejs
                • v2
                • v3
            • usage vs entry
              • usage : 局部引入,可能会有代码冗余(不同模块可能会引入相同的腻子),增加代码体积
              • entry: 入口全局引入,可能会污染全局作用域
        • @babel-runtime

          • 解决 preset-env 的全局污染
          • 手动按需加载腻子
          import Promise from "babel-runtime/core-js/promise";
          const p = new Promise(() => {});
          console.log(p);
        • @babel-plugin-transform-runtime

          • 按需引入、局部引入
          • 解决的问题
            • 文件重复引入的问题
            • 全局引入的全局污染问题
          • 可以在我们使用新 API 时自动 import babel-runtime 里面的 polyfill
          • 参数
            • corejs
              • @babel/runtime-corejs2
              • @babel/runtime-corejs3
            • helpers
              • 移除局部的 babel helpers 引用 babel-runtime/helpers
            • regenerator
              • false 使用的是全局的 regeneratorRuntime
              • true 使用的是自定义 runtime
        • polyfill-service

          • https://polyfill.io/v3/
        • 基本解析配置

          • preset
        • 装饰器语法支持

          • @babel/plugin-proposal-decorators
          • @babel/plugin-proposal-class-propertiess
            • loose 严格模式 ,定义属性的方式不同
        • 兼容性 polify vs runtime

          • polyfill(腻子),会直接在全局对象的原型上添加属性,造成全局污染,开发业务常用
          • runtime 重新构建新原生的对象,体积较大,开发第三方库常用
    4. style-loader css-loader sass-loader sass post-loader

       - node-sadd to dart-sass
      
       ```js
        {
          loader: "sass-loader",
          options: {
              implementation: require("sass"), //使用dart-sass代替node-sass
          },
        },
       ```
      
       - 兼容性
         - postcss-loader 可以使用 PostCSS 处理 CSS
         - postcss-preset-env 把现代的 CSS 转换成大多数浏览器能理解的,该包已经包含了 autoprefixer 和 browsers 选项
      
       ```js
       npm i postcss-loader postcss-preset-env -D
       ```
      
       ```js
        <!-- postcss.config.js -->
        let postcssPresetEnv = require('postcss-preset-env');
      
        module.exports={
        plugins:[postcssPresetEnv({
            browsers: 'last 5 version'
        })]
        }
        ```
    5. 代码格式化

    • npm install prettier -D --save-exact
    • husky&lint-staged
    • json
      • 文件提示
      • https://github.com/schemastore/schemastore/#contribute
      • https://cloud.tencent.com/developer/article/1633934

组件开发流程

  • 样式

    • 定义全局变量、mixin
      • !default 定义变量默认值
      • hsl($hue,$saturation,$lightness):通過色相(hue)、飽和度(saturation)和亮度(lightness)的值創建一個顏色;
      • 定义对象
      • The _ (underscore) is a partial for scss. That means the stylesheet its going to be imported (@import) to a main stylesheet i.e. styles.scss.
  • 组件开发

    • 需求分析
      • 属性
    • 开发
      • mvp(最小可用原型)
      • 接口定义
      • 取出所有的属性
      • 计算属性
      • 根据属性显示具体的节点
      • 定义组件的样式变量
      • 添加注释
      • story
      • test
        • 改变 input value
        • async await
    • 持续优化(warnning 错误引起,在组件内部 hack)
      • onChange
      • 受控组件 vs 非受控组件
        • value&defaultValue 同时存在
          • 在组件内部 fixed delete defaultValue
        • value
          • 由 undefined 到被赋值,React 会抛错
          • 在组件内部 fixed,默认赋值为空
  • test 开发

    • jest

      • 概念
        • 断言 https://jestjs.io/docs/using-matchers
    • 使用

      • 安装
        • jest
        • react 集成
          • Enzyme(airbnb),操作如 jq
          • @testing-library/react
          npm i jest @types/jest @testing-library/react @testing-library/jest-dom -D
        • jest: jest 核心库
        • @testing-library/react: 测试 React 组件的解决方案
        • @testing-library/jest-dom : 扩展 jest 的 dom 断言
      • add jest.config.js
      • setupTests.ts
        • 全局 test 通用配置
      • 使用
        • getByText vs queryByText
          • 返回类型不同
        • mock Funcitons:捕获函数是否被调用
          • 定义 disabledProps
          • 触发事件
          <!-- import { render, fireEvent } from "@testing-library/react"; -->
          fireEvent.click(element);

      testing-library

组件文档生产

  • 组件开发的痛点

    • 入口文件不适合组件库
    • 行为事件的调用和属性设置
  • 组件库开发

    • 属性展示
    • 事件调用
    • 生产使用文档
  • storybook

    • install
      • npx sb init
      • Storybook 6.2 includes experimental Webpack 5 support. webpack 兼容有问题
        • https://github.com/storybookjs/storybook/issues/14878
      • Clean install https://gist.github.com/shilman/8856ea1786dcd247139b47b270912324
    • post-scss
      • add @storybook/addon-postcss in addons
      • Deprecated default PostCSS plugins
      • webpack TypeError: Cannot read property 'get' of undefined
      • https://github.com/storybookjs/storybook/issues/14497
  • scss

    • npm i -D @storybook/preset-scss css-loader sass sass-loader style-loader
  • 待修复

    • scss+postcss??
  • 展示源码

    • https://github.com/storybookjs/deprecated-addons/tree/master/addons/info
    • add @storybook/addon-info @types/storybook__addon-info
    //preview.js
    import React from "react";
    import { withInfo } from "@storybook/addon-info";
    import "../src/styles/index.scss";
    export const parameters = {
      actions: { argTypesRegex: "^on[A-Z].*" },
      controls: {
        matchers: {
          color: /(background|color)$/i,
          date: /Date$/,
        },
      },
      info: { inline: true, header: false },
    };
    
    export const decorators = [
      withInfo,
      (Story) => (
        <div style={{ margin: "3em" }}>
          <Story />
        </div>
      ),
    ];
  • 展示参数

    // main.js
    module.exports = {
      stories: ["../src/**/*.stories.@(js|jsx|ts|tsx|mdx)"],
      addons: [
        "@storybook/addon-links",
        "@storybook/addon-essentials",
        "@storybook/preset-scss",
      ],
      core: {
        builder: "webpack5",
      },
      webpackFinal: (config) => {
        config.module.rules.push({
          test: /\.tsx?$/,
          use: [
            {
              loader: require.resolve("babel-loader"),
              options: {
                presets: [require.resolve("babel-preset-react-app")],
              },
            },
            {
              loader: require.resolve("react-docgen-typescript-loader"),
              options: {
                shouldExtractLiteralValuesFromEnum: true,
                propFilter: (prop) => {
                  if (prop.parent) {
                    return !prop.parent.fileName.includes("node_modules");
                  }
                  return true;
                },
              },
            },
          ],
        });
        return config;
      },
    };
  • 打包

    • 什么是模块
      • 可重用
      • 可维护
    • 模块化历史
      • 全局+命名口空间
      • commjs+AMD
      • es6 esMoudle
        • 允许静态分析,可以实现 tree-shaking
        • 循环引用&动态绑定
    • 输出的模块类型
      • eg:
        • Ant Design 支持浏览器引入
          • 不支持按需加载
      • 采用 esmoudle 打包文档
    • 入口文件
      • package.json
        • main
        • module
      • index.tsx(入口文件)
    • 样式采用文件单独引入的方式
    • 配置打包 tsconfig.build.json
    • 配置打包命令
      • 打包
    • 开发测试
      • 发布测试包安装
      • npm link
        • 源码目录执行 npm link 会创建软链
          • /usr/local/lib/node_modules/component -> /Users/kong.ds/Documents/person/component
        • 开发项目
          • npm link component 建立软链接
          • /Users/kong.ds/Documents/test/my-test/node_modules/component -> /usr/local/lib/node_modules/component -> /Users/kong.ds/Documents/person/component
          • package.json 中手动添加依赖
        • bug
          • index.js:1 Could not find icon {prefix: "fas", iconName: "check-circle"}
            • 定位: ICON 组件引用了第三的库没有打包
          • Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
            • 定位:React 版本不一致
            • 解决方式:
              • https://reactjs.org/warnings/invalid-hook-call-warning.html
              • 源码 React 的包引用项目的 React
                • npm link 项目 React 地址
                  sudo npm link ../../test/my-test/node_modules/react/
              • 发布时 package.jon 中将 React 定义为 peerDependencies

发布

  • npm whoami(npm 源设置)
  • package 维护
    • version:版本号 https://semver.org/
    • files: 上传文件,默认按照 gitignore 上传
  • 添加 publish 钩子,执行 build
  • 精简依赖包
    • peerDependencies 处理版本冲突
      • 本地开发时可将依赖设置为 devDependencies
  • lint & test
    • 发布前执行代码规范和测试用例
  • 生成文档首页

CI/CD

  • git push->运行单元测试->npm publish->生成文档首页->上传服务器->生产文档站点
  • CI : 持续集成
    • 频繁将代码 merge master
    • 快速发现问题
    • 防止分支代码偏离
  • CD:持续交付、持续部署
    • 将新版本交付给用户
    • 部署生产环境
  • 工具
    • travis ci
    • prepublish vs prepublishOnly
      • prepublish 每次 install 都执行
      • prepublishOnly 只有 publish
    • githu pages
      • 更新.travis.yml 配置文件
        • 新增 script 执行脚本
        • 新增 deploy
          • add github_token 设置 travis 的 github_token
          • add local_dir
        • chtty-component
    • npm publish
  • Beautiful shell
    • git 文件名大小写不敏感