参加若川源码共读活动
1. 介绍
输入一个字符串,检验这个字符串是否是一个有效的npm包名 此包导出一个同步的方法,这个方法接受一个字符串并返回一个至少拥有两个属性的对象:
validForNewPackages::BooleanvalidForOldPackages::Boolean
2. 源码
源码很短,比较容易懂。
// 核心模块名称:builtins.json
[
"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"
]
'use strict'
// 作用域包名正则检测,如@user/package
var scopedPackagePattern = new RegExp('^(?:@([^/]+?)[/])?([^/]+?)$')
// 核心模块名称
var builtins = require('builtins')
// 黑名单列表
var blacklist = [
'node_modules',
'favicon.ico'
]
核心源码比较简单,只记录部分
if (/[~'!()*]/.test(name.split('/').slice(-1)[0])) {
warnings.push('name can no longer contain special characters ("~\'!()*")')
}
此处用到了slice(-1)。 slice() 方法是从已有的数组中返回选定的元素,不会改变原始数组,只是浅拷贝了原数组中的部分元素。 -1,则表示数组的倒数一项,-2,倒数两项,以此类推。
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')
}
此处主要就是encodeURIComponent,详情可见 developer.mozilla.org/zh-CN/docs/…