文章目录
- 前言
- 一、源码阅读工具
- 二、阅读源码
- 1. 目录结构
- 2.package.json
- 3.index.js
- 三、使用该包
- 1. vue-cli中使用
- 2. create-react-app 中使用
- 总结
前言
validate-npm-package-name
是一个用于检测npm包是否符合标准的包,被很多脚手架创建工具使用:vue-cli
、create-react-app
源码地址:https://github.com/npm/validate-npm-package-name
一、源码阅读工具
- 本地编辑器从github上下载源码
- 在线网页版编辑器:
github.dev
(在网页端使用 VS Code 编辑 GitHub 项目——github.dev)
这里介绍下,github.dev是github官方提供的在线vscode编辑器
,将github访问URL中的com直接替换成dev,即可在网页版vscode中打开仓库代码阅读编辑。
二、阅读源码
1. 目录结构
2.package.json
- 入口文件:index.js
- builtins 依赖包会列出node所有内置模块
{
"name": "validate-npm-package-name",
"version": "3.0.0",
"description": "Give me a string and I'll tell you if it's a valid npm package name",
"main": "index.js",
"directories": {
"test": "test"
},
"dependencies": {
"builtins": "^1.0.3"
},
"devDependencies": {
"standard": "^8.6.0",
"tap": "^10.0.0"
},
...
}
打印 builtins 模块内容:(全是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'
]
3.index.js
源码如下:
'use strict'
var scopedPackagePattern = new RegExp('^(?:@([^/]+?)[/])?([^/]+?)$')
var builtins = require('builtins')
var blacklist = [
'node_modules',
'favicon.ico'
]
var validate = module.exports = function (name) {
var warnings = []
var errors = []
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')
}
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')
}
blacklist.forEach(function (blacklistedName) {
if (name.toLowerCase() === blacklistedName) {
errors.push(blacklistedName + ' is a blacklisted name')
}
})
builtins.forEach(function (builtin) {
if (name.toLowerCase() === builtin) {
warnings.push(builtin + ' is a core module name')
}
})
if (name.length > 214) {
warnings.push('name can no longer contain more than 214 characters')
}
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 ("~\'!()*")')
}
if (encodeURIComponent(name) !== name) {
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)
}
validate.scopedPackagePattern = scopedPackagePattern
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.warnings
if (!result.errors.length) delete result.errors
return result
}
三、使用该包
1. vue-cli中使用
vue create xxx 新建项目时,就用到了该包
源码地址:https://github1s.com/vuejs/vue-cli/blob/HEAD/packages/@vue/cli/lib/create.js#L8-L30
const validateProjectName = require('validate-npm-package-name')
async function create (projectName, options) {
const cwd = options.cwd || process.cwd()
const inCurrent = projectName === '.'
const name = inCurrent ? path.relative('../', cwd) : projectName
const result = validateProjectName(name)
if (!result.validForNewPackages) {
console.error(chalk.red(`Invalid project name: "${name}"`))
result.errors && result.errors.forEach(err => {
console.error(chalk.red.dim('Error: ' + err))
})
result.warnings && result.warnings.forEach(warn => {
console.error(chalk.red.dim('Warning: ' + warn))
})
exit(1)
}
...
}
2. create-react-app 中使用
源码地址:https://github1s.com/facebook/create-react-app/blob/04482a6c2c6639c19deb330c48e4fa5573a1654e/packages/create-react-app/createReactApp.js
const validateProjectName = require('validate-npm-package-name');
function createApp(name, verbose, version, template, useYarn, usePnp) {
...
const root = path.resolve(name);
const appName = path.basename(root);
checkAppName(appName);
....
}
function checkAppName(appName) {
const validationResult = validateProjectName(appName);
if (!validationResult.validForNewPackages) {
console.error(
....
);
[
...(validationResult.errors || []),
...(validationResult.warnings || []),
].forEach(error => {
console.error(chalk.red(` * ${error}`));
});
console.error(chalk.red('\nPlease choose a different project name.'));
process.exit(1);
}
...
}
总结
validate-npm-package-name 源码
- 共100行左右
- 阅读比较简单,就是一些判断。涉及较多的正则判断
- 通过
const validateProjectName = require('validate-npm-package-name')
使用 - 使用场景:用脚手架例如
vue-cli
创建项目时,能够校验创建的包名是否符合规范
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)