小曹同学的百草园
首页
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

小曹同学

一个普通的前端开发
首页
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • validate-npm-package-name 检测 npm 包是否符合标准

    • ⭐️前言
      • 🎯目标
        • 📝相关方法介绍
          • scopedPackagePattern正则表达式[^1]
          • builtins: 列出了 node 所有的内置模块
          • String.tirm()方法
          • match()方法
          • page name基本内容判断
        • 📏 规则:[^3]
          • 包名不能是空字符串
          • 不能以.或者_开头
          • 前后不能有空格
          • 不能是黑名单内包和node内置包
          • 长度不可以超过214
          • 不可以包含~'!()*中的任意一个字符串
        • 📦总结
          • 📃参考资料
          • 源码学习笔记
          小曹同学
          2021-12-22
          目录

          validate-npm-package-name 检测 npm 包是否符合标准

          # ⭐️前言

          # 包介绍

          Give me a string and I'll tell you if it's a valid npm package name. This package exports a single synchronous function that takes a string as input and returns an object with two properties: validForNewPackages :: Boolean

          validForOldPackages :: Boolean

          接受一个字符串参数, 检验该字符串是否是一个有效的包命名, 该工具 提供一个 接受字符串的函数, 并且返回 一个拥有2个属性的对象 validForNewPackages :: Boolean validForOldPackages :: Boolean

          # 包的应用[^4]

          • vue-create xx 新建项目时有用到这个包:相关链接 (opens new window)

          • create-react-app:相关链接 (opens new window)

          • 检测示例[^2]

            • const validate = require("validate-npm-package-name")
              validate('some-page')
              validate('example.com')
              validate(' has empty ') // 报错1:包名不可有前后格
              validate('123number')
              validate('http')// 报错2:规则中不能是node内置的包
              validate('@babel/core')
              validate('jane/foo.js')
              
              1
              2
              3
              4
              5
              6
              7
              8

          # 🎯目标

          • [x] 掌握tirm()方法
          • [x] 掌握正则中的match()方法
          • [x] page name命名规则
          • [x] 学习规范的工具编写方法

          # 📝相关方法介绍

          # scopedPackagePattern正则表达式[^1]

          var scopedPackagePattern = new RegExp('^(?:@([^/]+?)[/])?([^/]+?)$'

          下载.png

          匹配结果:

          • @user 以@开头
          • @user/test
          • 非‘/’的字符串
          • image.png

          # builtins (opens new window): 列出了 node 所有的内置模块

          # String.tirm() (opens new window)方法

          • trim() 方法用于删除字符串的头尾空白符,空白符包括:空格、制表符 tab、换行符等其他空白符等。

          • trim() 方法不会改变原始字符串。

          📌示例代码:

          const name1 = " hello word "
          const name2 = "helloword"
          const hasEmp = name1.trim()// hello word 去除头尾空格
          const notEmp = name2.trim()// helloword
          
          1
          2
          3
          4

          💡源码相关代码:

          // 校验包名不能包含任何的前导、后导空格
            if (name.trim() !== name) {
              errors.push('name cannot contain leading or trailing spaces')
            }
          
          1
          2
          3
          4

          # match() (opens new window)方法

          match() 方法检索返回一个字符串匹配正则表达式的结果。

          📌示例代码:

          image-20211222094703554
          const exmp = 'Hello Word'
          const regex = /[A-Z]/g
          const found = exmp.match(regex) // ['H', 'W']
          
          1
          2
          3

          💡源代码相关代码:

            // 校验包名不能以.开头
            if (name.match(/^\./)) {
              errors.push('name cannot start with a period')
            }
            // 校验包名不能以_开头、这里复习了下match用法
            // '.'.match(/^_/) === null
            if (name.match(/^_/)) {
              errors.push('name cannot start with an underscore')
            }
          
          1
          2
          3
          4
          5
          6
          7
          8
          9

          # page name基本内容判断

          💡源代码:

           if (name === null) {
              errors.push('name cannot be null')
              return done(warnings, errors)
            }
          
            if (name === undefined) {
              errors.push('name cannot be undefined')
              return done(warnings, errors)
            }
          
            if (typeof name !== 'string') {
              errors.push('name must be a string')
              return done(warnings, errors)
            }
          
            if (!name.length) {
              errors.push('name length must be greater than zero')
            }
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18

          # 📏 规则:[^3]

          # 包名不能是空字符串

          💡源码:

           if (name === null) {
              errors.push('name cannot be null')
              return done(warnings, errors)
            }
          
            if (name === undefined) {
              errors.push('name cannot be undefined')
              return done(warnings, errors)
            }
          
            if (typeof name !== 'string') {
              errors.push('name must be a string')
              return done(warnings, errors)
            }
          
            if (!name.length) {
              errors.push('name length must be greater than zero')
            }
          
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19

          所有字符串必须小写

          💡源码:

          // mIxeD CaSe nAMEs
            if (name.toLowerCase() !== name) {
              warnings.push('name can no longer contain capital letters') // 报名不能包含大写字母
            }
          
          1
          2
          3
          4

          # 不能以.或者_开头

          💡源码:

            if (name.match(/^\./)) {
              errors.push('name cannot start with a period')
            }
          
            if (name.match(/^_/)) {
              errors.push('name cannot start with an underscore')
            }
          
          1
          2
          3
          4
          5
          6
          7

          # 前后不能有空格

          💡源码:

           if (name.trim() !== name) {
              errors.push('name cannot contain leading or trailing spaces')
            }
          
          1
          2
          3

          # 不能是黑名单内包和node内置包

          💡源码:

          // 检测黑名单列表
          blacklist.forEach(function (blacklistedName) {
              if (name.toLowerCase() === blacklistedName) {
                errors.push(blacklistedName + ' is a blacklisted name')
              }
            })
          
            // Generate warnings for stuff that used to be allowed
            // 不可以是node内置包,否则警告
            // core module names like http, events, util, etc
            builtins.forEach(function (builtin) {
              if (name.toLowerCase() === builtin) {
                warnings.push(builtin + ' is a core module name')
              }
            })
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15

          # 长度不可以超过214

          💡源码:

           if (name.length > 214) {
              warnings.push('name can no longer contain more than 214 characters')
            }
          
          1
          2
          3

          # 不可以包含~'!()*中的任意一个字符串

          💡源码:

          if (/[~'!()*]/.test(name.split('/').slice(-1)[0])) {
              warnings.push('name can no longer contain special characters ("~\'!()*")')
            }
          
          1
          2
          3

          # 📦总结

          本次源码阅读的源码并不是很难,从中学习到了如何更加规范化的代码编写和考虑到各个方面可能出现的问题并写出对于的代码进行应对调整。

          # 📃参考资料

          [^1]:请叫我张先森 validate-npm-package-name 源码阅读 (opens new window) [^2]:reset reset | 第七期 | validate-npm-package-name源码分析 (opens new window) [^3]:NuoHui (opens new window) 每天一个npm包:validate-npm-package-name (opens new window) [^4]:若川 第7期 | validate-npm-package-name 检测 npm 包是否符合标准 (opens new window)

          编辑 (opens new window)
          上次更新: 2022/02/21, 05:57:00
          最近更新
          01
          优雅代码书写之道
          06-07
          02
          图片懒加载
          05-05
          03
          项目部署
          04-16
          更多文章>
          Theme by Vdoing
          • 跟随系统
          • 浅色模式
          • 深色模式
          • 阅读模式