代码拉取完成,页面将自动刷新
#!/usr/bin/env node
const fs = require('fs')
const path = require('path')
const argv = require('minimist')(process.argv.slice(2), { string: ['_'] })
const prompts = require('prompts')
const { red, green } = require('kolorist')
const cwd = process.cwd()
const renameFiles = {
// _gitignore: '.gitignore',
// _eslintignore: '.eslintignore',
// '_eslintrc.js': '.eslintrc.js',
// _prettierrc: '.prettierrc'
}
async function init() {
// 获取参数 - 项目名称
let targetDir = argv._[0]
// 设置默认项目名称
const defaultProjectName = !targetDir ? 'vite-vue2' : targetDir
let result = {}
try {
result = await prompts(
[
{
type: targetDir ? null : 'text',
name: 'projectName',
message: '项目目录:',
onState: (state) =>
(targetDir = state.value.trim() || defaultProjectName),
},
{
type: () =>
!fs.existsSync(targetDir) || isEmpty(targetDir) ? null : 'confirm',
name: 'overwrite',
message: () =>
targetDir === '.'
? '当前目录'
: `目录:"${targetDir}"不是空目录,是否移除已有文件并进行下一步?`,
},
{
type: (_, { overwrite } = {}) => {
if (overwrite === false) {
throw new Error(red('❌') + '操作取消')
}
return null
},
name: 'overwriteChecker',
},
{
name: 'packageName',
type: () => (isValidPackageName(targetDir) ? null : 'text'),
message: '包名称:',
initial: () => toValidPackageName(targetDir),
validate: (dir) => isValidPackageName(dir) || '非法包名',
},
],
{
oncancel: () => {
throw new Error(red('❌') + '操作取消')
},
}
)
} catch (cancelled) {
console.log(cancelled.message)
return
}
// 用户输入配置
const { overwrite, packageName } = result
// 根目录
const root = path.join(cwd, targetDir)
if (overwrite) {
emptyDir(root)
} else if (!fs.existsSync(root)) {
// 不存在目录则创建目录
fs.mkdirSync(root)
}
console.log(`\n 脚手架正在${root}目录创建项目中...`)
const templateDir = path.join(__dirname, 'template')
const write = (file, content) => {
const targetPath = renameFiles[file]
? path.join(root, renameFiles[file])
: path.join(root, file)
if (content) {
fs.writeFileSync(targetPath, content)
} else {
copy(path.join(templateDir, file), targetPath)
}
}
// 读取模板目录文件
const files = fs.readdirSync(templateDir)
// 遍历,写文件
for (const file of files.filter((f) => f !== 'package.json')) {
write(file)
}
const pkg = require(path.join(templateDir, 'package.json'))
pkg.name = packageName || targetDir
write('package.json', JSON.stringify(pkg, null, 2))
// 获取客户端包管理信息
const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent)
const pkgManager = pkgInfo ? pkgInfo.name : 'npm'
console.log(`\n ${green('⭕️创建完成!')}\n运行:`)
if (root !== cwd) {
console.log(` ${green('cd ' + path.relative(cwd, root))}`)
}
switch (pkgManager) {
case 'yarn':
console.log(`$ ${green('yarn')}`)
console.log(`$ ${green('yarn dev')}`)
break
default:
console.log(`$ ${green(pkgManager + ' install')}`)
console.log(`$ ${green(pkgManager + ' run dev')}`)
break
}
}
// 判断目录是否为空
function isEmpty(path) {
return fs.readdirSync(path).length === 0
}
// 验证项目名称
function isValidPackageName(projectName) {
return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(
projectName
)
}
// 输入项目名称处理
function toValidPackageName(projectName) {
return projectName
.trim()
.toLowerCase()
.replace(/\s+/g, '-')
.replace(/^[._]/, '')
.replace(/[^a-z0-9-~]+/g, '-')
}
// 清空目录
function emptyDir(dir) {
if (!fs.existsSync(dir)) {
return
}
for (const file of fs.readdirSync(dir)) {
const abs = path.resolve(dir, file)
// baseline is Node 12 so can't use rmSync :(
if (fs.lstatSync(abs).isDirectory()) {
emptyDir(abs)
fs.rmdirSync(abs)
} else {
fs.unlinkSync(abs)
}
}
}
// 复制文件
function copy(src, dest) {
const stat = fs.statSync(src)
if (stat.isDirectory()) {
copyDir(src, dest)
} else {
fs.copyFileSync(src, dest)
}
}
// 复制目录
function copyDir(srcDir, destDir) {
fs.mkdirSync(destDir, { recursive: true })
for (const file of fs.readdirSync(srcDir)) {
const srcFile = path.resolve(srcDir, file)
const destFile = path.resolve(destDir, file)
copy(srcFile, destFile)
}
}
// 通过环境变量获取客户端包管理工具信息
function pkgFromUserAgent(userAgent) {
if (!userAgent) return undefined
const pkgSpec = userAgent.split(' ')[0]
const pkgSpecArr = pkgSpec.split('/')
return {
name: pkgSpecArr[0],
version: pkgSpecArr[1],
}
}
init().catch((e) => {
console.error(e)
})
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。