1. 前言
1.1 环境
- 操作系统: macOS 11.5.2
- 浏览器: Chrome 94.0.4606.81
validate-npm-package-name 3.0.0
1.2 阅读该文章可以get以下知识点
-
2. 开始
2.1 如何使用
```javascript var validate = require(“validate-npm-package-name”)
// 正确的名称 validate(“some-package”) validate(“example.com”) validate(“under_score”) validate(“123numeric”) validate(“@npm/thingy”) validate(“@jane/foo.js”)
// All of the above names are valid, so you’ll get this object back: // 如果校验通过,返回下面的对象 { validForNewPackages: true, validForOldPackages: true }
// 非法名称 validate(“excited!”) validate(“ leading-space:and:weirdchars”)
// That was never a valid package name, so you get this: // 名称有问题,返回下面的报错信息 { validForNewPackages: false, validForOldPackages: false, errors: [ ‘name cannot contain leading or trailing spaces’, ‘name can only contain URL-friendly characters’ ] }
<a name="fYtTV"></a>## 2.2 源码```javascript// 作用域正则,例如@vue/component,会被match拆分成vue和componentvar scopedPackagePattern = new RegExp('^(?:@([^/]+?)[/])?([^/]+?)$')// 返回node内置模块列表['assert','buffer','child_process','cluster','console','constants','crypto','dgram','dns','domain','events','fs','http','https','module','net','os','path','punycode','querystring','readline','repl','stream','string_decoder','sys','timers','tls','tty','url','util','vm','zlib']// 里面就是一个json文件,所以不与安装的node程序有关var builtins = require('builtins')// 黑名单,不管node_modules和ico文件var blacklist = ['node_modules','favicon.ico']var validate = module.exports = function (name) {var warnings = []var errors = []// null的判断if (name === null) {errors.push('name cannot be null')return done(warnings, errors)}// undefined判断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)}// 上面的三个判断都直接return// 空字符串if (!name.length) {errors.push('name length must be greater than zero')}// 以英文句号开头if (name.match(/^\./)) {errors.push('name cannot start with a period')}// 以下划线开头if (name.match(/^_/)) {errors.push('name cannot start with an underscore')}// 两边有空格if (name.trim() !== name) {errors.push('name cannot contain leading or trailing spaces')}// No funny business 不用使用黑名单中的名称blacklist.forEach(function (blacklistedName) {if (name.toLowerCase() === blacklistedName) {errors.push(blacklistedName + ' is a blacklisted name')}})// Generate warnings for stuff that used to be allowed// core module names like http, events, util, etc// 不能使用node内置模块命名builtins.forEach(function (builtin) {if (name.toLowerCase() === builtin) {warnings.push(builtin + ' is a core module name')}})// really-long-package-names-------------------------------such--length-----many---wow// the thisisareallyreallylongpackagenameitshouldpublishdowenowhavealimittothelengthofpackagenames-poch.// 超过长度if (name.length > 214) {warnings.push('name can no longer contain more than 214 characters')}// mIxeD CaSe nAMEs 不能有大写if (name.toLowerCase() !== name) {warnings.push('name can no longer contain capital letters')}// 名称不能有中括号里面的字符if (/[~'!()*]/.test(name.split('/').slice(-1)[0])) {warnings.push('name can no longer contain special characters ("~\'!()*")')}// ;/?:@&=+$,# 这些用于分隔 URI 组件的标点符号,会被转义,如%26等等,目前大部分scope的包都是以@开头if (encodeURIComponent(name) !== name) {// Maybe it's a scoped package name, like @user/packagevar nameMatch = name.match(scopedPackagePattern)if (nameMatch) {// 前面是作用域uservar user = nameMatch[1]// 后面是具体的包 packagevar pkg = nameMatch[2]// 相等直接返回if (encodeURIComponent(user) === user && encodeURIComponent(pkg) === pkg) {return done(warnings, errors)}}// 不相等抛出错误errors.push('name can only contain URL-friendly characters')}// 最后都到了done函数return done(warnings, errors)}validate.scopedPackagePattern = scopedPackagePattern// 清洗数据,将不存在的warngings和errors删除,返回需要的数据var done = function (warnings, errors) {var result = {validForNewPackages: errors.length === 0 && warnings.length === 0,validForOldPackages: errors.length === 0,warnings: warnings,errors: errors}if (!result.warnings.length) delete result.warningsif (!result.errors.length) delete result.errorsreturn result}
3. 总结
源码很短就100行左右,主要用来校验npm包名是否符合标准,主要校验以下几种情况,是不合法的
- 直接返回的情况
- undefined
- null
- 不是字符串类型
放入警告和错误列表的情况
