Оригинальный адрес:GitHub.com/jiang Tao/Первоначально…, Пожалуйста, укажите источник.
В конце 2016 года мои коллеги говорили о строительных лесах. В связи с деятельностью компании多样性
, передняя часть灵活性
, поэтому мы должны думать о более общих лесах. Вместо того, чтобы постоянно тратить время на разработку передовых технологий配置
начальство. тогдаchef-cliродившийся. В начале 2018 года я разобрал и подытожил дела прошедшего года, и заново усилил исходные лесаproject-next-cli, не только для удовлетворения потребностей нашей команды, но и потребностей других.
project-next-cli
Целевые пользователи:
- Бизнес компании сложен, но есть определенное накопление
- Подбрасывание одноклассников и команды
- Разрабатывайте с большим количеством шаблонов разработки на github
развитие
С тех пор, как я начинал как фронтенд (13 лет), фронтенд в последние годы стремительно развивается.Основные показатели:
Примечания: происходит следующий процесс разработки, пожалуйста, не путайте порядок появления [закрой лицо]
- Библиотеки/фреймворки: jQuery, backbone, angular, react, vue
- Модульный: commonjs, AMD(CMD), UMD, модуль es
- Диспетчер задач: скрипты npm, grunt, gulp
- Сборщики модулей: r.js, webpack, rollup, browserify
- Препроцессоры CSS: Sass, Less, Stylus, Postcss
- Статическая проверка: поток/машинопись
- Тестовые инструменты: мокко, жасмин, джест, ава
- Инструменты обнаружения кода: eslint, jslint
развивать
Когда мы на самом деле разрабатываем, мы сталкиваемся с различными бизнес-требованиями (сценариями) и выбираем различные технологические стеки в соответствии с требованиями и сценариями.Из-за технического прогресса и ограничений различных сред выполнения браузера нам необходимо настроить соответствующую среду и т. д., ведет нас к удовлетворению потребностей бизнеса.
Нарисуйте картинку, чтобы представить взаимосвязь между бизнесом, конфигурацией (окружающей средой) и технологией.
Front-end инженер по настройке
Таким образом, Минцзянь начал новую карьеру, инженер по настройке внешнего интерфейса O (∩_∩) O~
Статус сообщества
специальные леса
В сообществе есть большое количество специализированных фреймворков, которые в основном заточены под целевую задачу. такие как следующие леса
vue-cli
Обеспечьте разработку с помощью vuewebpack
, pwa
В ожидании шаблона, эта статья относится к лесамvue-cli
реализация.
dva-cli
В основном дляdvaЛеса для развития
labrador
это微信小程序
Компонентная среда разработки, хотя апплет уже поддерживает компоненты, другие функции скаффолда также очень хороши. Кому интересно, могут узнать.
В сообществе есть много отличных специфических лесов, которые здесь не перечислены. Популярность фронтенд-сообщества позволила мне использовать суть фронтенда и продолжать двигаться вперед.
Универсальные леса
yeoman
Это надежный и универсальный каркас с набором инструментов, но yeoman выпускает указанное имя пакета и использует его инструменты разработки. может быть конкретнымНажмите здесь, чтобы увидеть правила добавления генератора yoman
Намерение и цели развития
Из-за определенной формы финансовых компаний, различных типов бизнеса и итераций развития передовых технологий он родился, чтобы следить за развитием сообщества и лучше достигать следующих целей.
- Займитесь делом: сосредоточенно, стабильно, быстро
- Спецификация команды: спецификация кода, процесс выпуска, непрерывная интеграция/доставка/развертывание
- Осадки: постоянное и стабильное внедрение новых технологий
- Преимущество: меньше сверхурочной работы, меньше времени на сборку колес, полные ключевые показатели эффективности и более значимые вещи.
готовность к реализации
Опираясь на Github, согласноGithub API
добиться следующим образом:
- получить предмет
curl -i https://api.github.com/orgs/project-scaffold/repos
- получить версию
curl -i https://api.github.com/repos/project-scaffold/cli/tags
реализовать логику
в соответствии сgithub api
Получив список проектов и номер версии, вы можете сделать общие леса.Следующий код является основным кодом для легкого понимания.
общий дизайн
- Спецификация
- Разработка скаффолдинга с помощью Node, выбор версии
>=6.0.0
- Используйте асинхронную/ожидающую разработку для решения проблемы асинхронного обратного вызова
- Компилировать с помощью Babel
- Канонический код с использованием ESLint
- Функции
подчиниться单一职责原则
, каждый файл представляет собой отдельный модуль, решающий независимые задачи. Можно свободно комбинировать для достижения повторного использования. Вот окончательная структура каталогов:
├── LICENSE
├── README.md
├── bin
│ └── project
├── package.json
├── src
│ ├── clear.js
│ ├── config.js
│ ├── helper
│ │ ├── metalAsk.js
│ │ ├── metalsimth.js
│ │ └── render.js
│ ├── index.js
│ ├── init.js
│ ├── install.js
│ ├── list.js
│ ├── project.js
│ ├── search.js
│ ├── uninstall.js
│ ├── update.js
│ └── utils
│ ├── betterRequire.js
│ ├── check.js
│ ├── copy.js
│ ├── defs.js
│ ├── git.js
│ ├── loading.js
│ └── rc.js
└── yarn.lock
Поговорим о логике реализации каждой команды.
скачать
- использовать
project i
- логика
Github API ===> 获取项目列表 ===> 选择一个项目 ===> 获取项目版本号 ===> 选择一个版本号 ===> 下载到本地仓库
Если данные на каждом шаге пусты/файл не существует, будет выдано приглашение
- основной код
// 获取github项目列表
const repos = await repoList();
choices = repos.map(({ name }) => name);
answers = await inquirer.prompt([
{
type : 'list',
name : 'repo',
message: 'which repo do you want to install?',
choices
}
]);
// 选择的项目
const repo = answers.repo;
// 项目的版本号劣币爱哦
const tags = await tagList(repo);
if (tags.length === 0) {
version = '';
} else {
choices = tags.map(({ name }) => name);
answers = await inquirer.prompt([
{
type : 'list',
name : 'version',
message: 'which version do you want to install?',
choices
}
]);
version = answers.version;
}
// 下载
await download([repo, version].join('@'));
построить проект
- использовать
project init
- логика
获取本地仓库列表 ===> 选择一个本地项目 ===> 输入基本信息 ===> 编译生成到临时文件 ===> 复制并重名到目标目录
Если данные на каждом шаге пусты/файл не существует/сгенерированный каталог был продублирован, будет выдано подсказка
- основной код
// 获取本地仓库项目
const list = await readdir(dirs.download);
// 基本信息
const answers = await inquirer.prompt([
{
type : 'list',
name : 'scaffold',
message: 'which scaffold do you want to init?',
choices: list
}, {
type : 'input',
name : 'dir',
message: 'project name',
// 必要的验证
async validate(input) {
const done = this.async();
if (input.length === 0) {
done('You must input project name');
return;
}
const dir = resolve(process.cwd(), input);
if (await exists(dir)) {
done('The project name is already existed. Please change another name');
}
done(null, true);
}
}
]);
const metalsmith = await rc('metalsmith');
if (metalsmith) {
const tmp = `${dirs.tmp}/${answers.scaffold}`;
// 复制一份到临时目录,在临时目录编译生成
await copy(`${dirs.download}/${answers.scaffold}`, tmp);
await metal(answers.scaffold);
await copy(`${tmp}/${dirs.metalsmith}`, answers.dir);
// 删除临时目录
await rmfr(tmp);
} else {
await copy(`${dirs.download}/${answers.scaffold}`, answers.dir);
}
Механизм шаблонов компилирует и реализует основной код следующим образом:
// metalsmith逻辑
function metal(answers, tmpBuildDir) {
return new Promise((resolve, reject) => {
metalsmith
.metadata(answers)
.source('./')
.destination(tmpBuildDir)
.clean(false)
.use(render())
.build((err) => {
if (err) {
reject(err);
return;
}
resolve(true);
});
});
}
// metalsmith render中间件实现
function render() {
return function _render(files, metalsmith, next) {
const meta = metalsmith.metadata();
/* eslint-disable */
Object.keys(files).forEach(function(file){
const str = files[file].contents.toString();
consolidate.swig.render(str, meta, (err, res) => {
if (err) {
return next(err);
}
files[file].contents = new Buffer(res);
next();
});
})
}
}
обновить/понизить версию
- использовать
project update
- логика
获取本地仓库列表 ===> 选择一个本地项目 ===> 获取版本信息列表 ===> 选择一个版本 ===> 覆盖原有的版本文件
Если данные на каждом шаге пусты/файл не существует, будет выдано приглашение
- основной код
// 获取本地仓库列表
const list = await readdir(dirs.download);
// 选择一个要升级的项目
answers = await inquirer.prompt([
{
type : 'list',
name : 'scaffold',
message: 'which scaffold do you want to update?',
choices: list,
async validate(input) {
const done = this.async();
if (input.length === 0) {
done('You must choice one scaffold to update the version. If not update, Ctrl+C');
return;
}
done(null, true);
}
}
]);
const repo = answers.scaffold;
// 获取该项目的版本信息
const tags = await tagList(repo);
if (tags.length === 0) {
version = '';
} else {
choices = tags.map(({ name }) => name);
answers = await inquirer.prompt([
{
type : 'list',
name : 'version',
message: 'which version do you want to install?',
choices
}
]);
version = answers.version;
}
// 下载覆盖文件
await download([repo, version].join('@'))
настроить
Конфигурация используется для получения основных настроек скаффолда, таких как реестр, тип и другая основная информация.
- использовать
project config set registry koajs # 设置本地仓库下载源
project config get registry # 获取本地仓库设置的属性
project config delete registry # 删除本地设置的属性
- логика
判定本地设置文件存在 ===> 读/写
Если данные на каждом шаге пусты/файл не существует, будет выдано приглашение
- основной код
switch (action) {
case 'get':
console.log(await rc(k));
console.log('');
return true;
case 'set':
await rc(k, v);
return true;
case 'remove':
await rc(k, v, true);
return true;
default:
console.log(await rc());
поиск
Найдите список проектов в удаленном репозитории github.
- использовать
project search
- логика
获取github项目列表 ===> 输入搜索的内容 ===> 返回匹配的列表
Если данные на каждом шаге пусты, будет выдано приглашение
- основной код
const answers = await inquirer.prompt([
{
type : 'input',
name : 'search',
message: 'search repo'
}
]);
if (answers.search) {
let list = await searchList();
list = list
.filter(item => item.name.indexOf(answers.search) > -1)
.map(({ name }) => name);
console.log('');
if (list.length === 0) {
console.log(`${answers.search} is not found`);
}
console.log(list.join('\n'));
console.log('');
}
Суммировать
Вышеупомянутое является предысторией этой общей структуры леса.Для пользователей и конкретных реализаций леса в настоящее время имеют некоторые области, которые можно оптимизировать:
- Разные источники, храните разные файлы
- Поддержка автономной функции
Жесткий широкий: если вы чувствуетеproject-next-cliПростота в использовании, добро пожаловать в звезду и добро пожаловать в форк для обслуживания.