作用
校验npm包的名称是否符合规则
使用方法
引入
const validate = require("validate-npm-package-name");
具体使用方法
let res = validate("package-name");
如果通过,会打印出以下信息
res { validForNewPackages: true, validForOldPackages: true
如果不通过,会显示以下信息
{
validForNewPackages: false,
validForOldPackages: true,
warnings: [ 'name can no longer contain capital letters' ]
}
源码分析
// 输出的校验函数
var validate = module.exports = function (name) {
// 包名不能为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)
}
//包名必须具有长度,不能是空字符串
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
var blacklist = [ 'node_modules','favicon.ico']
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
builtins.forEach(function (builtin) {
if (name.toLowerCase() === builtin) {
warnings.push(builtin + ' is a core module name')
}
})
// 包名不能包含大写字母
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 ("~'!()*")')
}
// 只能含有url中能识别的字符
if (encodeURIComponent(name) !== name) {
// Maybe it's a scoped package name, like @user/package
var nameMatch = name.match(scopedPackagePattern)
if (nameMatch) {
var user = nameMatch[1]
var pkg = nameMatch[2]
if (encodeURIComponent(user) === user && encodeURIComponent(pkg) === pkg) {
return done(warnings, errors)
}
}
errors.push('name can only contain URL-friendly characters')
}
return done(warnings, errors)
}
注意这个scopedPackagePattern,这个正则赋值给了函数,暴露的validate函数具有这个属性并可以修改,以便于用户自定义校验规则
validate.scopedPackagePattern = scopedPackagePattern
其中builtins最终只是一个json,里面有各种包名,是node的内置模块
[ "assert", "buffer", "child_process", "cluster", "console", "constants", "crypto", "dgram", "dns", "domain", "events", "fs", "http", "https", "module", "net", "os", "path", "process", "punycode", "querystring", "readline", "repl", "stream", "string_decoder", "timers", "tls", "tty", "url", "util", "v8", "vm", "zlib"]
done函数就是上方的返回值
var done = function (warnings, errors) {
// 这个result就是返回的result
var result = {
validForNewPackages: errors.length === 0 && warnings.length === 0,
validForOldPackages: errors.length === 0,
warnings: warnings,
errors: errors
}
if (!result.warnings.length) delete result.warnings
if (!result.errors.length) delete result.errors
return result
}
总结
内容不多而且很简单,就是各个类型的校验