Bonne journée, mes amis!
Lors du développement du modèle de démarrage HTML moderne, j'ai pensé à étendre sa convivialité. À cette époque, les options pour son utilisation se limitaient au clonage du référentiel et au téléchargement de l'archive. C'est ainsi que l' extrait de code HTML et l'extension pour Microsoft Visual Studio Code - HTML Template , ainsi que l'interface de ligne de commande - create-modern-template sont apparus . Bien sûr, ces outils sont loin d'être parfaits et je vais les affiner autant que possible. Cependant, en les créant, j'ai appris quelques choses intéressantes que je souhaite partager avec vous.
L'extrait et l'expansion ont été traités dans la première partie... Dans cette partie, nous allons jeter un œil à la CLI.
Si vous n'êtes intéressé que par le code source, voici le lien vers le référentiel .
Oclif
Oclif est un framework Heroku pour créer des interfaces de ligne de commande.
Nous l'utiliserons pour créer une astuce qui offre la possibilité d'ajouter, de mettre à jour, de supprimer des tâches et d'afficher leur liste.
Le code source du projet est ici . Il existe également une CLI pour vérifier la fonctionnalité du site par URL.
Installez oclif globalement:
npm i -g oclif / yarn global add oclif
Oclif offre la possibilité de créer des CLI à commande unique et à commandes multiples. Nous avons besoin d'une deuxième option.
Nous créons un projet:
oclif multi todocli
- l'argument multi indique à oclif de créer une interface multi-commandes
- todocli - nom du projet
Ajoutez les commandes nécessaires:
oclif command add oclif command update oclif command remove oclif command show
Le fichier src / commandes / hello.js peut être supprimé.
Nous utiliserons lowdb comme base de données locale . Nous utiliserons également la craie pour personnaliser les messages affichés dans le terminal . Installez ces bibliothèques:
npm i chalk lowdb / yarn add chalk lowdb
Créez un fichier db.json vide dans le répertoire racine. Ce sera notre référentiel de tâches.
Dans le répertoire src, créez un fichier db.js avec le contenu suivant:
const low = require('lowdb')
const FileSync = require('lowdb/adapters/FileSync')
const adapter = new FileSync('db.json')
const db = low(adapter)
// todos db.json
db.defaults({ todos: [] }).write()
//
const Todo = db.get('todos')
module.exports = Todo
Modification du fichier src / commandes / add.js:
//
const { Command } = require('@oclif/command')
const Todo = require('../db')
const chalk = require('chalk')
class AddCommand extends Command {
async run() {
//
const { argv } = this.parse(AddCommand)
try {
//
await Todo.push({
id: Todo.value().length,
// ,
//
task: argv.join(' '),
done: false
}).write()
//
this.log(chalk.green('New todo created.'))
} catch {
//
this.log(chalk.red('Operation failed.'))
}
}
}
//
AddCommand.description = `Adds a new todo`
//
AddCommand.strict = false
//
module.exports = AddCommand
Modification du fichier src / commandes / update.js:
const { Command } = require('@oclif/command')
const Todo = require('../db')
const chalk = require('chalk')
class UpdateCommand extends Command {
async run() {
//
const { id } = this.parse(UpdateCommand).args
try {
// id
await Todo.find({ id: parseInt(id, 10) })
.assign({ done: true })
.write()
this.log(chalk.green('Todo updated.'))
} catch {
this.log('Operation failed.')
}
}
}
UpdateCommand.description = `Marks a task as done by id`
//
UpdateCommand.args = [
{
name: 'id',
description: 'todo id',
required: true
}
]
module.exports = UpdateCommand
Le fichier src / commandes / remove.js ressemble Ă ceci:
const { Command } = require('@oclif/command')
const Todo = require('../db')
const chalk = require('chalk')
class RemoveCommand extends Command {
async run() {
const { id } = this.parse(RemoveCommand).args
try {
await Todo.remove({ id: parseInt(id, 10) }).write()
this.log(chalk.green('Todo removed.'))
} catch {
this.log(chalk.red('Operation failed.'))
}
}
}
RemoveCommand.description = `Removes a task by id`
RemoveCommand.args = [
{
name: 'id',
description: 'todo id',
required: true
}
]
module.exports = RemoveCommand
Enfin, Ă©ditez le fichier src / commands / show.js:
const { Command } = require('@oclif/command')
const Todo = require('../db')
const chalk = require('chalk')
class ShowCommand extends Command {
async run() {
// id
const res = await Todo.sortBy('id').value()
//
//
if (res.length) {
res.forEach(({ id, task, done }) => {
this.log(
`[${
done ? chalk.green('DONE') : chalk.red('NOT DONE')
}] id: ${chalk.yellowBright(id)}, task: ${chalk.yellowBright(task)}`
)
})
//
} else {
this.log('There are no todos.')
}
}
}
ShowCommand.description = `Shows existing tasks`
module.exports = ShowCommand
Étant dans le répertoire racine du projet, exécutez la commande suivante:
npm link / yarn link
Ensuite, nous effectuons plusieurs opérations.
Excellent. Tout fonctionne comme prévu. Il ne reste plus qu'à modifier package.json et README.md, et vous pouvez publier le package dans le registre npm.
CLI de bricolage
Notre CLI dans la fonctionnalité ressemblera à create-react-app ou vue-cli . Sur la commande create, il créera un projet dans le répertoire cible contenant tous les fichiers nécessaires au fonctionnement de l'application. De plus, il offrira la possibilité d'initialiser éventuellement git et d'installer des dépendances.
Le code source du projet est ici .
Créez un répertoire et initialisez le projet:
mkdir create-modern-template cd create-modern-template npm init -y / yarn init -y
Installez les bibliothèques requises:
yarn add arg chalk clear esm execa figlet inquirer listr ncp pkg-install
- arg - un outil pour analyser les arguments de ligne de commande
- clear —
- esm — , ES6- Node.js
- execa — ( git)
- figlet —
- inquirer — , ,
- listr —
- ncp —
- pkg-install —
Dans le répertoire racine, créez un fichier bin / create (sans extension) avec le contenu suivant:
#!/usr/bin/env node
require = require('esm')(module)
require('../src/cli').cli(process.argv)
Modification de package.json:
"main": "src/main.js",
"bin": "bin/create"
La commande create est enregistrée.
Créez un répertoire src / template et placez-y les fichiers du projet, qui seront copiés dans le répertoire cible.
Créez un fichier src / cli.js avec le contenu suivant:
//
import arg from 'arg'
import inquirer from 'inquirer'
import { createProject } from './main'
//
// --yes -y git
// --git -g git
// --install -i
const parseArgumentsIntoOptions = (rawArgs) => {
const args = arg(
{
'--yes': Boolean,
'--git': Boolean,
'--install': Boolean,
'-y': '--yes',
'-g': '--git',
'-i': '--install'
},
{
argv: rawArgs.slice(2)
}
)
//
return {
template: 'template',
skipPrompts: args['--yes'] || false,
git: args['--git'] || false,
install: args['--install'] || false
}
}
//
const promptForMissingOptions = async (options) => {
// --yes -y
if (options.skipPrompts) {
return {
...options,
git: false,
install: false
}
}
//
const questions = []
// git
if (!options.git) {
questions.push({
type: 'confirm',
name: 'git',
message: 'Would you like to initialize git?',
default: false
})
}
//
if (!options.install) {
questions.push({
type: 'confirm',
name: 'install',
message: 'Would you like to install dependencies?',
default: false
})
}
//
const answers = await inquirer.prompt(questions)
//
return {
...options,
git: options.git || answers.git,
install: options.install || answers.install
}
}
//
export async function cli(args) {
let options = parseArgumentsIntoOptions(args)
options = await promptForMissingOptions(options)
await createProject(options)
}
Le fichier src / main.js ressemble Ă ceci:
//
import path from 'path'
import chalk from 'chalk'
import execa from 'execa'
import fs from 'fs'
import Listr from 'listr'
import ncp from 'ncp'
import { projectInstall } from 'pkg-install'
import { promisify } from 'util'
import clear from 'clear'
import figlet from 'figlet'
//
const access = promisify(fs.access)
const copy = promisify(ncp)
//
clear()
// HTML -
console.log(
chalk.yellowBright(figlet.textSync('HTML', { horizontalLayout: 'full' }))
)
//
const copyFiles = async (options) => {
try {
// templateDirectory - ,
// targetDirectory -
await copy(options.templateDirectory, options.targetDirectory)
} catch {
//
console.error('%s Failed to copy files', chalk.red.bold('ERROR'))
process.exit(1)
}
}
// git
const initGit = async (options) => {
try {
await execa('git', ['init'], {
cwd: options.targetDirectory,
})
} catch {
//
console.error('%s Failed to initialize git', chalk.red.bold('ERROR'))
process.exit(1)
}
}
//
export const createProject = async (options) => {
//
options.targetDirectory = process.cwd()
//
const fullPath = path.resolve(__filename)
//
const templateDir = fullPath.replace('main.js', `${options.template}`)
options.templateDirectory = templateDir
try {
//
// R_OK -
await access(options.templateDirectory, fs.constants.R_OK)
} catch {
//
console.error('%s Invalid template name', chalk.red.bold('ERROR'))
process.exit(1)
}
//
const tasks = new Listr(
[
{
title: 'Copy project files',
task: () => copyFiles(options),
},
{
title: 'Initialize git',
task: () => initGit(options),
enabled: () => options.git,
},
{
title: 'Install dependencies',
task: () =>
projectInstall({
cwd: options.targetDirectory,
}),
enabled: () => options.install,
},
],
{
exitOnError: false,
}
)
//
await tasks.run()
//
console.log('%s Project ready', chalk.green.bold('DONE'))
return true
}
Nous connectons la CLI (étant dans le répertoire racine):
yarn link
Créez un répertoire cible et un projet:
mkdir test-dir cd test-dir create-modern-template && code .
Ă€ la perfection. CLI prĂŞt Ă publier.
Publication d'un package dans le registre npm
Pour pouvoir publier des packages, vous devez d'abord créer un compte dans le registre npm .
Ensuite, vous devez vous connecter en exécutant la commande de connexion npm et en spécifiant votre adresse e-mail et votre mot de passe.
Ensuite, nous éditons package.json et créons les fichiers .gitignore, .npmignore, LICENSE et README.md (voir le référentiel du projet).
Nous empaquetons les fichiers de projet à l'aide de la commande npm package. Nous obtenons le fichier create-modern-template.tgz. Nous publions ce fichier en exécutant la commande npm publish create-modern-template.tgz.
Obtenir une erreur lors de la publication d'un package signifie généralement qu'un package portant ce nom existe déjà dans le registre npm. Pour mettre à jour un package, vous devez modifier la version du projet dans package.json, créer à nouveau le fichier TGZ et l'envoyer pour publication.
Une fois qu'un paquet a été publié, il peut être installé comme n'importe quel autre paquet en utilisant npm i / yarn add.
Comme vous pouvez le voir, la création de l'interface de ligne de commande et la publication du package dans le registre npm sont simples.
J'espère que vous avez trouvé quelque chose d'intéressant pour vous-même. Merci de votre attention.