Vue.js — одна из самых популярных интерфейсных сред, поэтому разработка компонента на основе Vue.js — это желание каждого фронтенда. Каждый раз, когда вы разрабатываете новый компонент Vue.js, вы делаете следующее:
- Создать каталог проекта
- инициализация git
- инициализация нпм
- Создайте среду разработки
- Проверка грамматики
- компиляция кода
- упаковка кода
- Локальный предварительный просмотр и горячая перезагрузка
- Создайте производственную среду
- Проверка грамматики
- компиляция кода
- Упаковка и сжатие кода
- Конфигурация непрерывной интеграции
Так почему бы не извлечь эти задания и не позволить ему генерировать их одним щелчком мыши? В настоящее время существует множество инструментов для генерации в один клик, таких какyeomanЖдать. Пакет строительных лесов yoman должен быть предоставлен для создания проекта с помощью yoman. Пакет строительных лесов yeoman по сути представляет собой шаблон проекта с полной файловой структурой.Пользователям необходимо вручную загрузить эти пакеты строительных лесов на локальный сервер, после чего yeoman автоматически создаст различные проекты на основе этих пакетов строительных лесов.
yoman прост в использовании, но добавить еще один шаг всегда проблематично, и вам нужно загрузить пакет поддержки. Популярна на рынке и технология cli, то есть шаблон удаленного склада подтягивается к локальному по некоторым конфигурациям. Судя по всему с модом кли все в порядке, качать не надо. На основе этого принципа мы построилиfecliстроительных лесов.
стек технологий
- Среда разработки: OS X El Capitan 10.11.6
- Инструменты разработки:Atom
- Node.js: Рабочая среда всех строительных лесов. Версия этого каркаса для Node.js: 9.11.1.
- es6: Новый синтаксис для JavaScript.
- commander: Инструмент, разработанный TJ для лучшей организации и обработки ввода командной строки. Командирский вариант этой лески: 2.15.1.
- co: Инструмент управления асинхронным потоком. Совместная версия этого скаффолдинга: 4.6.0.
- co-prompt: Пошаговый прием пользовательского ввода. Совместная версия этого скаффолда: 1.0.0.
- chalk: красочный терминальный инструмент. меловая версия этой лески: 2.3.2.
- ora: Элегантный счетчик терминала, который может управлять выводом терминала. Версия ora этого скаффолдинга: 2.0.0.
ядро проекта
Схема, иллюстрирующая общую архитектуру. ⤵️
О шаблонах
шаблонЭто то, что будет снесено в будущем. Этот шаблон часто содержит некоторую конфигурацию среды, конфигурацию обнаружения синтаксиса, конфигурацию модульного теста, конфигурацию непрерывной интеграции и т. д.
Информация о шаблоне будет храниться вtemplates.jsonв файле. Пользователи также могут работать с помощью некоторых командtemplates.jsonсодержание в .
Файловая структура скаффолдинга
. ├── bind/ # 运行命令的入口文件 │ └── ... ├── lib/ # 核心代码 │ ├── table.js # 模板列表表格形式的封装 │ ├── tip.js # 终端提示信息的封装 │ ├── cli/ # 命令管理 │ │ └── ... │ └── cmd/ # 命令操作 │ │ └── ... ├── public/ # 命令预览 │ └── ... └── templates.json # 模板管理
Настроить глобальное использование
создать новый каталогmkdir fecli
и введитеcd fecli
. Затем npm инициализирует егоnpm init
. Чтобы быть доступными по всему миру, нам нужноpackage.jsonУстановите его внутри:
"bin": {
"fe": "./bin/fe.js"
},
При локальной отладке выполняйте в корневом каталоге проекта:npm link
.
положитьfecliКоманда привязана к глобальной и может быть использована напрямую в будущем.feначать с команды.
Параметры файла ввода
Запишите зависимости в package.json и выполнитеnpm install
илиyarn install
:
"dependencies": {
"chalk": "^2.3.2",
"co": "^4.6.0",
"co-prompt": "^1.0.0",
"commander": "^2.15.1",
"ora": "^2.0.0"
}
Создал в корневом каталоге\binпапку, создайтеfe.js
документ. этоbin/fe.jsФайл является входным файлом для всего скаффолдинга, поэтому давайте сначала напишем его.
Первый — это некоторый код инициализации, очень просто обратиться к файлу, управляемому командой (lib/cli/index.js):
require('../lib/cli/');
командное управление (lib/cli/index.js)
Сначала некоторые вещи инициализации:
const program = require('commander');
const packageInfo = require('../../package.json');
program
.version(packageInfo.version)
мы проходимcommanderдля установки различных команд.commandМетод заключается в установке имени команды.descriptionМетод заключается в установке описания.aliasМетод задается сокращенно.actionСпособ - установить обратный вызов.
program
.command('init') // fe init
.description('生成一个项目')
.alias('i') // 简写
.action(() => {
require('../cmd/init')();
});
program
.command('add') // fe add
.description('添加新模板')
.alias('a') // 简写
.action(() => {
require('../cmd/add')();
});
program
.command('list') // fe list
.description('查看模板列表')
.alias('l') // 简写
.action(() => {
require('../cmd/list')();
});
program
.command('delete') // fe delete
.description('查看模板列表')
.alias('d') // 简写
.action(() => {
require('../cmd/delete')();
});
Если аргументов нет, запустите вспомогательный метод. Далее следует разбор аргументов в program.args :
program.parse(process.argv);
if(!program.args.length){
program.help()
}
бегатьfe
Результат после:
commanderКонкретный метод использования не будет здесь раскрываться, вы можете перейти непосредственно кОфициальный сайтСм. подробную документацию.
Обработка пользовательского ввода
Установлено в соответствии с корневым каталогом проекта/lib/cmdПапка, специально используемая для хранения файлов обработки команд.
Создал в корневом каталогеtemplates.jsonфайл и напишите следующее содержимое для хранения информации о шаблоне:
{"tpl":{}}
Добавьте шаблон (fe add
)
Перейдите в /lib/cmd и создайте новыйadd.jsдокумент.
'use strict'
const co = require('co');
const prompt = require('co-prompt');
const fs = require('fs');
const table = require('../table');
const tip = require('../tip');
const tpls = require('../../templates');
const writeFile = (err) => {
// 处理错误
if (err) {
console.log(err);
tip.fail('请重新运行!');
process.exit();
}
table(tpls);
tip.suc('新模板添加成功!');
process.exit();
};
const resolve = (result) => {
const { tplName, gitUrl, branch, description, } = result;
// 避免重复添加
if (!tpls[tplName]) {
tpls[tplName] = {};
tpls[tplName]['url'] = gitUrl.replace(/[\u0000-\u0019]/g, ''); // 过滤unicode字符
tpls[tplName]['branch'] = branch;
tpls[tplName]['description'] = description;
} else {
tip.fail('模板已经存在!');
process.exit();
};
// 把模板信息写入templates.json
fs.writeFile(__dirname + '/../../templates.json', JSON.stringify(tpls), 'utf-8', writeFile);
};
module.exports = () => {
co(function *() {
// 分步接收用户输入的参数
const tplName = yield prompt('模板名字: ');
const gitUrl = yield prompt('Git https 链接: ');
const branch = yield prompt('Git 分支: ');
const description = yield prompt('模板描述: ');
return new Promise((resolve, reject) => {
resolve({
tplName,
gitUrl,
branch,
description,
});
});
}).then(resolve);
};
удалить шаблон (fe delete
)
Перейдите в /lib/cmd и создайте новыйdelete.jsдокумент.
'use strict'
const co = require('co');
const prompt = require('co-prompt');
const fs = require('fs');
const table = require('../table');
const tip = require('../tip');
const tpls = require('../../templates');
const writeFile = (err) => {
if (err) {
console.log(err);
tip.fail('请重新运行!');
process.exit();
}
tip.suc('新模板删除成功!');
if (JSON.stringify(tpls) !== '{}') {
table(tpls);
} else {
tip.info('还未添加模板!');
}
process.exit();
};
const resolve = (tplName) => {
// 删除对应的模板
if (tpls[tplName]) {
delete tpls[tplName];
} else {
tip.fail('模板不经存在!');
process.exit();
}
// 写入template.json
fs.writeFile(__dirname + '/../../templates.json', JSON.stringify(tpls), 'utf-8', writeFile);
};
module.exports = () => {
co(function *() {
// 分步接收用户输入的参数
const tplName = yield prompt('模板名字: ');
return new Promise((resolve, reject) => {
resolve(tplName);
});
}).then(resolve);
};
Инициализировать проект (fe init
)
Перейдите в /lib/cmd и создайте новыйinit.jsдокумент.
'use strict'
// 操作命令行
const exec = require('child_process').exec;
const co = require('co');
const ora = require('ora');
const prompt = require('co-prompt');
const tip = require('../tip');
const tpls = require('../../templates');
const spinner = ora('正在生成...');
const execRm = (err, projectName) => {
spinner.stop();
if (err) {
console.log(err);
tip.fail('请重新运行!');
process.exit();
}
tip.suc('初始化完成!');
tip.info(`cd ${projectName} && npm install`);
process.exit();
};
const download = (err, projectName) => {
if (err) {
console.log(err);
tip.fail('请重新运行!');
process.exit();
}
// 删除 git 文件
exec('cd ' + projectName + ' && rm -rf .git', (err, out) => {
execRm(err, projectName);
});
}
const resolve = (result) => {
const { tplName, url, branch, projectName, } = result;
// git命令,远程拉取项目并自定义项目名
const cmdStr = `git clone ${url} ${projectName} && cd ${projectName} && git checkout ${branch}`;
spinner.start();
exec(cmdStr, (err) => {
download(err, projectName);
});
};
module.exports = () => {
co(function *() {
// 处理用户输入
const tplName = yield prompt('模板名字: ');
const projectName = yield prompt('项目名字: ');
if (!tpls[tplName]) {
tip.fail('模板不存在!');
process.exit();
}
return new Promise((resolve, reject) => {
resolve({
tplName,
projectName,
...tpls[tplName],
});
});
}).then(resolve);
}
Показать список шаблонов (fe list
)
Перейдите в /lib/cmd и создайте новыйlist.jsдокумент.
'use strict'
const table = require('../table');
module.exports = () => {
table(require('../../templates'));
process.exit();
};
Теперь нашfecliИнструмент для строительных лесов создан, давайте попробуем вместе!
использовать тест
-
fe add
Добавить шаблон
-
fe delete
Добавить шаблон
-
fe list
Добавить шаблон
-
fe init
Добавить шаблон
Исходный код проекта
Для получения дополнительной информации об источнике, пожалуйста, переместитеfecli.