[Разработка веб-сайтов, JavaScript, Программирование] Сниппет, расширение для VSCode и CLI. Часть 2
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Доброго времени суток, друзья!
В процессе разработки Современного стартового HTML-шаблона я задумался о расширении возможностей его использования. На тот момент варианты его применения ограничивались клонированием репозитория и скачиванием архива. Так появились HTML-сниппет и расширение для Microsoft Visual Studio Code — HTML Template, а также интерфейс командной строки — create-modern-template. Конечно, указанные инструменты далеки от совершенства и я буду их дорабатывать по мере сил и возможностей. Однако, в процессе их создания я узнал несколько интересных вещей, которыми и хочу с вами поделиться.
Сниппет и расширение были рассмотрены в первой части. В этой части мы рассмотрим CLI.
Если вас интересует лишь исходный код, вот ссылка на репозиторий.
Oclif
Oclif — это фреймворк от Heroku для создания интерфейсов командной строки.
Создадим с его помощью тудушку, предусматривающую возможность добавления, обновления, удаления задач и просмотра их списка.
Исходный код проекта находится здесь. Там же находится CLI для проверки работоспособности сайта по URL.
Устанавливаем oclif глобально:
npm i -g oclif / yarn global add oclif
Oclif предоставляет возможность создавать как одно-, так и мультикомандные CLI. Нам нужен второй вариант.
Создаем проект:
oclif multi todocli
- аргумент multi указывает oclif создать мультикомандный интерфейс
- todocli — название проекта
Добавляем необходимые команды:
oclif command add
oclif command update
oclif command remove
oclif command show
Файл src/commands/hello.js можно удалить.
В качестве локальной базы данных мы будем использовать lowdb. Также для кастомизации сообщений, выводимых в терминал, мы будем использовать chalk. Устанавливаем эти библиотеки:
npm i chalk lowdb / yarn add chalk lowdb
Создаем в корневой директории пустой файл db.json. Это будет нашим хранилищем задач.
В директории src создаем файл db.js следующего содержания:
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
Редактируем файл src/commands/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
Редактируем файл src/commands/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
Файл src/commands/remove.js выглядит похожим образом:
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
Наконец, редактируем файл 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
Находясь в корневой директории проекта, выполняем следующую команду:
npm link / yarn link
Далее выполняем несколько операций.
Отлично. Все работает, как ожидается. Осталось отредактировать package.json и README.md, и можно публиковать пакет в реестре npm.
CLI своими руками
Наш CLI по своему функционалу будет напоминать create-react-app или vue-cli. По команде create он будет создавать в целевой директории проект, содержащий все необходимые для работы приложения файлы. Кроме того, в нем будет предусмотрена возможность опциональной инициализации git и установки зависимостей.
Исходный код проекта находится здесь.
Создаем директорию и инициализируем проект:
mkdir create-modern-template
cd create-modern-template
npm init -y / yarn init -y
Устанавливаем необходимые библиотеки:
yarn add arg chalk clear esm execa figlet inquirer listr ncp pkg-install
- arg — инструмент для разбора аргументов командной строки
- clear — инструмент для очистки терминала
- esm — инструмент, обеспечивающий поддержку ES6-модулей в Node.js
- execa — инструмент для автоматического выполнения некоторых распространенных операций (мы будем использовать его для инициализации git)
- figlet — инструмент для вывода в терминал кастомизированного текста
- inquirer — инструмент для работы с командной строкой, в частности, позволяет задавать вопросы пользователю и разбирать его ответы
- listr — инструмент для создания списка задач и визуализации их выполнения в терминале
- ncp — инструмент для копирования файлов и директорий
- pkg-install — инструмент для программной установки зависимостей проекта
В корневой директории создаем файл bin/create (без расширения) следующего содержания:
#!/usr/bin/env node
require = require('esm')(module)
require('../src/cli').cli(process.argv)
Редактируем package.json:
"main": "src/main.js",
"bin": "bin/create"
Команда create зарегистрирована.
Создаем директорию src/template и помещаем туда файлы проекта, которые будут копироваться в целевую директорию.
Создаем файл src/cli.js следующего содержания:
// импорт необходимого функционала
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)
}
Файл src/main.js выглядит так:
// импорт необходимого функционала
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
}
Подключаем CLI (находясь в корневой директории):
yarn link
Создаем целевую директорию и проект:
mkdir test-dir
cd test-dir
create-modern-template && code .
Прекрасно. CLI готов к публикации.
Публикация пакета в реестре npm
Для того, чтобы иметь возможность публиковать пакеты, прежде всего необходимо создать аккаунт в реестре npm.
Затем нужно авторизоваться, выполнив команду npm login и указав email и пароль.
После этого редактируем package.json и создаем файлы .gitignore, .npmignore, LICENSE и README.md (см. репозиторий проекта).
Упаковываем файлы проекта с помощью команды npm package. Получаем файл create-modern-template.tgz. Публикуем данный файл, выполняя команду npm publish create-modern-template.tgz.
Получение ошибки при публикации пакета, обычно, означает, что пакет с таким названием уже существует в реестре npm. Для обновления пакета необходимо изменить версию проекта в package.json, снова создать TGZ-файл и отправить его на публикацию.
После публикации пакета, его можно устанавливать как любой другой пакет с помощью npm i / yarn add.
Как видите, в создании CLI и публикации пакета в реестре npm нет ничего сложного.
Надеюсь, вы нашли для себя что-нибудь интересное. Благодарю за внимание.
===========
Источник:
habr.com
===========
Похожие новости:
- [Программирование, Kotlin] Проверка на равенство в Kotlin (перевод)
- [Python, Программирование] Ультимативный гайд по поиску утечек памяти в Python
- [Программирование, Проектирование и рефакторинг] Универсальная архитектура приложений
- [Ненормальное программирование, Visual Studio, Софт] Разработчик VS Code Stories написал Tinder для программистов
- [Программирование, Разработка мобильных приложений, Разработка под Android, Kotlin] Практическое руководство по использованию Hilt с Kotlin (перевод)
- [Разработка веб-сайтов, Учебный процесс в IT, Карьера в IT-индустрии] Frontend-образование или как могут помочь курсы новичку
- [Программирование, C++] Введение в регулярные выражения в современном C++ (перевод)
- [Программирование, Разработка игр] Семь талантливых стажеров AI@Unity 2020. Часть 2 (перевод)
- [Глобальные системы позиционирования, Программирование, Компиляторы, Lua, Робототехника] Umka и трактор: первый опыт практического применения нового языка
- [JavaScript, Интерфейсы, ReactJS, TypeScript] Использование Effector в стеке React + TypeScript
Теги для поиска: #_razrabotka_vebsajtov (Разработка веб-сайтов), #_javascript, #_programmirovanie (Программирование), #_javascript, #_snippet, #_extension, #_visual_studio_code, #_vscode, #_command_line, #_cli, #_snippet (сниппет), #_rasshirenie (расширение), #_komandnaja_stroka (командная строка), #_interfejs_komandnoj_stroki (интерфейс командной строки), #_razrabotka_vebsajtov (
Разработка веб-сайтов
), #_javascript, #_programmirovanie (
Программирование
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 02:16
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Доброго времени суток, друзья! В процессе разработки Современного стартового HTML-шаблона я задумался о расширении возможностей его использования. На тот момент варианты его применения ограничивались клонированием репозитория и скачиванием архива. Так появились HTML-сниппет и расширение для Microsoft Visual Studio Code — HTML Template, а также интерфейс командной строки — create-modern-template. Конечно, указанные инструменты далеки от совершенства и я буду их дорабатывать по мере сил и возможностей. Однако, в процессе их создания я узнал несколько интересных вещей, которыми и хочу с вами поделиться. Сниппет и расширение были рассмотрены в первой части. В этой части мы рассмотрим CLI. Если вас интересует лишь исходный код, вот ссылка на репозиторий. Oclif Oclif — это фреймворк от Heroku для создания интерфейсов командной строки. Создадим с его помощью тудушку, предусматривающую возможность добавления, обновления, удаления задач и просмотра их списка. Исходный код проекта находится здесь. Там же находится CLI для проверки работоспособности сайта по URL. Устанавливаем oclif глобально: npm i -g oclif / yarn global add oclif
Oclif предоставляет возможность создавать как одно-, так и мультикомандные CLI. Нам нужен второй вариант. Создаем проект: oclif multi todocli
Добавляем необходимые команды: oclif command add
oclif command update oclif command remove oclif command show Файл src/commands/hello.js можно удалить. В качестве локальной базы данных мы будем использовать lowdb. Также для кастомизации сообщений, выводимых в терминал, мы будем использовать chalk. Устанавливаем эти библиотеки: npm i chalk lowdb / yarn add chalk lowdb
Создаем в корневой директории пустой файл db.json. Это будет нашим хранилищем задач. В директории src создаем файл db.js следующего содержания: 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 Редактируем файл src/commands/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 Редактируем файл src/commands/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 Файл src/commands/remove.js выглядит похожим образом: 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 Наконец, редактируем файл 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 Находясь в корневой директории проекта, выполняем следующую команду: npm link / yarn link
Далее выполняем несколько операций. Отлично. Все работает, как ожидается. Осталось отредактировать package.json и README.md, и можно публиковать пакет в реестре npm. CLI своими руками Наш CLI по своему функционалу будет напоминать create-react-app или vue-cli. По команде create он будет создавать в целевой директории проект, содержащий все необходимые для работы приложения файлы. Кроме того, в нем будет предусмотрена возможность опциональной инициализации git и установки зависимостей. Исходный код проекта находится здесь. Создаем директорию и инициализируем проект: mkdir create-modern-template
cd create-modern-template npm init -y / yarn init -y Устанавливаем необходимые библиотеки: yarn add arg chalk clear esm execa figlet inquirer listr ncp pkg-install
В корневой директории создаем файл bin/create (без расширения) следующего содержания: #!/usr/bin/env node
require = require('esm')(module) require('../src/cli').cli(process.argv) Редактируем package.json: "main": "src/main.js",
"bin": "bin/create" Команда create зарегистрирована. Создаем директорию src/template и помещаем туда файлы проекта, которые будут копироваться в целевую директорию. Создаем файл src/cli.js следующего содержания: // импорт необходимого функционала
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) } Файл src/main.js выглядит так: // импорт необходимого функционала
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 } Подключаем CLI (находясь в корневой директории): yarn link
Создаем целевую директорию и проект: mkdir test-dir
cd test-dir create-modern-template && code . Прекрасно. CLI готов к публикации. Публикация пакета в реестре npm Для того, чтобы иметь возможность публиковать пакеты, прежде всего необходимо создать аккаунт в реестре npm. Затем нужно авторизоваться, выполнив команду npm login и указав email и пароль. После этого редактируем package.json и создаем файлы .gitignore, .npmignore, LICENSE и README.md (см. репозиторий проекта). Упаковываем файлы проекта с помощью команды npm package. Получаем файл create-modern-template.tgz. Публикуем данный файл, выполняя команду npm publish create-modern-template.tgz. Получение ошибки при публикации пакета, обычно, означает, что пакет с таким названием уже существует в реестре npm. Для обновления пакета необходимо изменить версию проекта в package.json, снова создать TGZ-файл и отправить его на публикацию. После публикации пакета, его можно устанавливать как любой другой пакет с помощью npm i / yarn add. Как видите, в создании CLI и публикации пакета в реестре npm нет ничего сложного. Надеюсь, вы нашли для себя что-нибудь интересное. Благодарю за внимание. =========== Источник: habr.com =========== Похожие новости:
Разработка веб-сайтов ), #_javascript, #_programmirovanie ( Программирование ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 02:16
Часовой пояс: UTC + 5