create-node-lib
Version:
Scaffolding out a Node.js library module
144 lines (139 loc) • 4.08 kB
JavaScript
const validateNpmPackageName = require('validate-npm-package-name')
const PACKAGE_MANAGER_ENGINES = {
pnpm: '>=10.26.0',
npm: '>=11.10.0'
}
const SUPPORTED_NPM_CLIENTS = Object.keys(PACKAGE_MANAGER_ENGINES)
module.exports = {
description: 'Scaffolding out a node library.',
templateData: {
year: new Date().getFullYear(),
npmClientInstall: ({ npmClient }) => {
return npmClient === 'pnpm' ? 'add' : 'install'
},
changesetRepo: ({ projectRepository }) => {
// Extract owner/repo from URL like https://github.com/username/reponame
// or https://github.com/username/reponame.git
if (!projectRepository || typeof projectRepository !== 'string') return ''
const match = projectRepository.match(/github\.com\/([^/]+\/[^/.?#]+)/)
return match ? match[1] : ''
}
},
prompts() {
return [
{
name: 'npmClient',
message: 'Which package manager do you want to use?',
default: 'pnpm',
type: 'list',
choices: SUPPORTED_NPM_CLIENTS
},
{
name: 'projectName',
message: 'What is the name of the new project',
default: this.outFolder,
filter: val => val.toLowerCase(),
validate: projectName => {
const validation = validateNpmPackageName(projectName)
return !validation.errors && !validation.warnings
}
},
{
name: 'description',
message: 'How would you describe the new project',
default: ''
},
{
name: 'keywords',
message: 'Comma-separated list of package keywords for npm',
default: ''
},
{
name: 'author',
message: 'What is your name',
default: this.gitUser.name,
store: true,
required: true
},
{
name: 'username',
message: 'What is your GitHub username',
default:
this.gitUser.username ||
this.gitUser.name
.toLowerCase()
.split(' ')
.join(''),
filter: val => val.toLowerCase(),
store: true
},
{
name: 'email',
message: 'What is your email?',
default: this.gitUser.email,
store: true,
validate: v => /.+@.+/.test(v)
},
{
name: 'projectRepository',
message: 'The URL of the repository',
default({ username, projectName }) {
return `https://github.com/${username}/${projectName}`
},
store: true
}
]
},
actions() {
const npmClient = this.answers.npmClient
return [
{
type: 'add',
templateDir: 'template',
files: '**'
},
{
type: 'modify',
files: 'package.json',
handler(data, filepath) {
delete data.scripts['lint:lockfile']
data.scripts.lint = `eslint . && ${npmClient} run lint:markdown`
data.engines[npmClient] = PACKAGE_MANAGER_ENGINES[npmClient]
data['lint-staged'] = {
'**/*.{js,json}': [`${npmClient} run lint:fix`]
}
return data
}
},
{
type: 'move',
patterns: {
gitignore: '.gitignore',
npmrc: '.npmrc'
}
},
...(npmClient !== 'pnpm'
? [
{
type: 'remove',
files: 'pnpm-workspace.yaml'
}
]
: [])
]
},
async completed() {
const spawn = require('child_process').spawnSync
spawn('git', ['init', '-b', 'main'], { cwd: this.outDir })
const repoUrl = this.answers.projectRepository
if (repoUrl) {
const remoteUrl = repoUrl.endsWith('.git') ? repoUrl : `${repoUrl}.git`
spawn('git', ['remote', 'add', 'origin', remoteUrl], { cwd: this.outDir })
}
await this.npmInstall({ npmClient: this.answers.npmClient })
await this.npmInstall({ npmClient: this.answers.npmClient, args: ['run', 'prepare'] })
this.showProjectTips()
this.logger.tip('You\'re all setup. hack away!')
}
}