Selamat siang teman!
Saat mengembangkan Template Pemula HTML Modern, saya berpikir untuk memperluas kegunaannya. Pada saat itu, opsi penggunaannya terbatas pada kloning repositori dan mengunduh arsip. Beginilah cuplikan dan ekstensi HTML untuk Kode Microsoft Visual Studio - Template HTML , serta antarmuka baris perintah - buat-modern-template muncul . Tentu saja, alat-alat ini jauh dari sempurna dan saya akan menyempurnakannya semampu saya. Namun, dalam proses pembuatannya, saya mempelajari beberapa hal menarik yang ingin saya bagikan kepada Anda.
Cuplikan dan perluasan dibahas di bagian pertama . Pada bagian ini, kita akan melihat CLI.
Jika Anda hanya tertarik pada kode sumbernya, berikut ini tautan ke repositori .
Oclif
Oclif adalah framework Heroku untuk membangun antarmuka baris perintah.
Mari kita gunakan untuk membuat trik yang memberikan kemampuan untuk menambah, memperbarui, menghapus tugas, dan melihat daftarnya.
Kode sumber proyek ada di sini . Ada juga CLI untuk memeriksa fungsionalitas situs dengan URL.
Instal oclif secara global:
npm i -g oclif / yarn global add oclif
Oclif menyediakan kemampuan untuk membuat CLI perintah tunggal dan multi-perintah. Kami membutuhkan opsi kedua.
Kami membuat proyek:
oclif multi todocli
- argumen multi memberitahu oclif untuk membuat antarmuka multi-perintah
- todocli - nama proyek
Tambahkan perintah yang diperlukan:
oclif command add oclif command update oclif command remove oclif command show
File src / commands / hello.js bisa dihapus.
Kami akan menggunakan lowdb sebagai database lokal . Kami juga akan menggunakan kapur untuk menyesuaikan pesan yang ditampilkan di terminal . Instal perpustakaan ini:
npm i chalk lowdb / yarn add chalk lowdb
Buat file db.json kosong di direktori root. Ini akan menjadi tempat penyimpanan tugas kita.
Di direktori src, buat file db.js dengan konten berikut:
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
Mengedit file 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
Mengedit file 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
File src / commands / remove.js terlihat seperti ini:
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
Terakhir, edit file 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
Berada di direktori root proyek, jalankan perintah berikut:
npm link / yarn link
Selanjutnya, kami melakukan beberapa operasi.
Baik. Semuanya bekerja seperti yang diharapkan. Yang tersisa hanyalah mengedit package.json dan README.md, dan Anda dapat menerbitkan paket ke registri npm.
CLI DIY
CLI kami akan menyerupai fungsi create-react-app atau vue-cli . Pada perintah create, itu akan membuat proyek di direktori target yang berisi semua file yang diperlukan agar aplikasi berfungsi. Selain itu, ini akan memberikan kemampuan untuk menginisialisasi git dan menginstal dependensi secara opsional.
Kode sumber proyek ada di sini .
Buat direktori dan inisialisasi proyek:
mkdir create-modern-template cd create-modern-template npm init -y / yarn init -y
Instal perpustakaan yang diperlukan:
yarn add arg chalk clear esm execa figlet inquirer listr ncp pkg-install
- arg - alat untuk mengurai argumen baris perintah
- clear - alat untuk membersihkan terminal
- esm adalah alat yang menyediakan dukungan modul ES6 di Node.js
- execa adalah alat untuk secara otomatis melakukan beberapa operasi umum (kita akan menggunakannya untuk menginisialisasi git)
- figlet - alat untuk mengeluarkan teks yang disesuaikan ke terminal
- Inquirer - alat untuk bekerja dengan baris perintah, khususnya, memungkinkan Anda untuk mengajukan pertanyaan kepada pengguna dan mengurai jawabannya
- listr - alat untuk membuat daftar tugas dan memvisualisasikan pelaksanaannya di terminal
- ncp - alat untuk menyalin file dan direktori
- pkg-install - alat untuk menginstal dependensi proyek secara terprogram
Di direktori root, buat bin / buat file (tanpa ekstensi) dengan konten berikut:
#!/usr/bin/env node
require = require('esm')(module)
require('../src/cli').cli(process.argv)
Mengedit package.json:
"main": "src/main.js",
"bin": "bin/create"
Perintah buat terdaftar.
Buat direktori src / template dan letakkan file proyek di sana, yang akan disalin ke direktori target.
Buat file src / cli.js dengan konten berikut:
//
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)
}
File src / main.js terlihat seperti ini:
//
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
}
Kami menghubungkan CLI (berada di direktori root):
yarn link
Buat direktori dan proyek target:
mkdir test-dir cd test-dir create-modern-template && code .
Sempurna. CLI siap untuk dipublikasikan.
Menerbitkan paket ke registri npm
Untuk dapat menerbitkan paket, Anda harus membuat akun di registri npm terlebih dahulu .
Kemudian Anda harus masuk dengan menjalankan perintah login npm dan menentukan email dan kata sandi Anda.
Setelah itu kita mengedit package.json dan membuat file .gitignore, .npmignore, LICENSE dan README.md (lihat repositori proyek).
Kami mengemas file proyek menggunakan perintah paket npm. Kami mendapatkan file create-modern-template.tgz. Kami menerbitkan file ini dengan menjalankan perintah npm publish create-modern-template.tgz.
Mendapat kesalahan saat menerbitkan paket biasanya berarti bahwa paket dengan nama yang sama sudah ada di registri npm. Untuk memperbarui paket, Anda perlu mengubah versi proyek di package.json, membuat file TGZ lagi dan mengirimkannya untuk publikasi.
Setelah sebuah paket diterbitkan, itu dapat diinstal seperti paket lainnya yang menggunakan npm i / yarn add.
Seperti yang Anda lihat, membuat CLI dan menerbitkan paket ke registri npm sangatlah mudah.
Saya harap Anda menemukan sesuatu yang menarik untuk diri Anda sendiri. Terima kasih atas perhatian Anda.