vue-cli — это официальный инструмент командной строки для создания шаблонов для Vue.js. Мы можем использовать его для быстрого создания проектов Vue.js. Основная функция vue-cli — инициализация проектов. Вы можете использовать официальные шаблоны или пользовательские шаблоны для создания проектов. , А начиная с версии 2.8.0, vue-cli добавилbuildкоманда, которая позволяет вам запускать приложение Vue.js с нулевой конфигурацией. Далее давайте рассмотрим, как работает vue-cli.
Установить глобально
Во-первых, vue-cli — это пакет узла, и его можно передать прямо в терминале.vueВызов команды, поэтому vue-cli необходимо установить глобально.Когда npm устанавливает пакет глобально, он в основном делает две вещи:
- Установите пакет в глобальный каталог node_modules.
- Создайте соответствующую команду в каталоге bin и свяжите ее с соответствующим исполняемым скриптом.
Глядя на package.json vue-cli, вы можете найти следующий код:
{
"bin": {
"vue": "bin/vue",
"vue-init": "bin/vue-init",
"vue-list": "bin/vue-list",
"vue-build": "bin/vue-build"
}
}
Таким образом, после глобальной установки vue-cli, npm поможет вам зарегистрироватьсяvue, vue-init, vue-list, vue-buildэти команды.
Структура проекта
Сам проект vue-cli не большой, а структура проекта следующая:
.
├── bin
├── docs
├── lib
└── test
└── e2e
binКаталог - это исполняемый файл,docsВот новые функцииvue buildдокументация,libэто разделенная библиотека классов,testНиже приведен тестовый файл, давайте сосредоточимся наbinфайлы в каталоге.
bin/vue
Первый взглядbin/vue, содержание очень короткое, только следующий код:
#!/usr/bin/env node
require('commander')
.version(require('../package').version)
.usage('<command> [options]')
.command('init', 'generate a new project from a template')
.command('list', 'list available official templates')
.command('build', 'prototype a new project')
.parse(process.argv)
vue-cli основан наcommander.jsнаписано, поддерживаетсяGit-style sub-commands, поэтому выполнитеvue initможет достигать иvue-initТот же эффект.
bin/vue-init
см. далееbin/vue-init,vue-initОсновная функция — генерировать прототипы проектов по заданному шаблону. Файл сначала представляет некоторые зависимые модули и вспомогательные функции в lib, потому что команда init должна получить хотя бы один параметр, поэтомуvue-initПервое, что нужно выполнить, это проверить входные параметрыhelpфункция, если параметры не переданы, будет напечатано приглашение, а если параметры переданы, операция будет продолжена.
Далее идет процесс разбора параметров:
var template = program.args[0]
var hasSlash = template.indexOf('/') > -1
var rawName = program.args[1]
var inPlace = !rawName || rawName === '.'
var name = inPlace ? path.relative('../', process.cwd()) : rawName
var to = path.resolve(rawName || '.')
var clone = program.clone || false
var tmp = path.join(home, '.vue-templates', template.replace(/\//g, '-'))
if (program.offline) {
console.log(`> Use cached template at ${chalk.yellow(tildify(tmp))}`)
template = tmp
}
templateимя шаблона, второй параметр (program.args[1])rawNameимя проекта, если оно не существует или.считается инициализированным в текущем каталоге (inPlace = true), имя проекта по умолчаниюnameТакже текущее имя папки.to— выходной путь проекта, который будет использоваться позже.cloneПараметр определяет, следует ли использовать git clone для загрузки шаблона, что полезно, когда шаблон находится в частном репозитории.offlineПараметр определяет, использовать ли автономный режим.Если используется автономный режим, vue-cli попытается~/.vue-templatesПолучите соответствующий шаблон ниже, вы можете сохранить долгоdownloading templateВремя ожидания, но шаблон не последняя версия не может быть определена.
Вы получите переменную при обработке параметров ранееto, указывающий путь к проекту, который должен быть сгенерирован, если он уже существует, будет выведено предупреждение, чтобы пользователь мог подтвердить, следует ли продолжать, и выполнить после подтвержденияrunфункция:
if (exists(to)) {
inquirer.prompt([{
type: 'confirm',
message: inPlace
? 'Generate project in current directory?'
: 'Target directory exists. Continue?',
name: 'ok'
}], function (answers) {
if (answers.ok) {
run()
}
})
} else {
run()
}
запустить функциюВ основном он проверяет, является ли шаблон локальным шаблоном, затем получает или загружает шаблон и выполняет его после получения шаблона.generateфункция.
Генерирующая функция генерации является ядром проекта, основной код:
module.exports = function generate (name, src, dest, done) {
var opts = getOptions(name, src)
// Metalsmith读取template下所有资源
var metalsmith = Metalsmith(path.join(src, 'template'))
var data = Object.assign(metalsmith.metadata(), {
destDirName: name,
inPlace: dest === process.cwd(),
noEscape: true
})
opts.helpers && Object.keys(opts.helpers).map(function (key) {
Handlebars.registerHelper(key, opts.helpers[key])
})
var helpers = {chalk, logger}
if (opts.metalsmith && typeof opts.metalsmith.before === 'function') {
opts.metalsmith.before(metalsmith, opts, helpers)
}
// 一次使用askQuestions, filterFiles, renderTemplateFiles处理读取的内容
metalsmith.use(askQuestions(opts.prompts))
.use(filterFiles(opts.filters))
.use(renderTemplateFiles(opts.skipInterpolation))
if (typeof opts.metalsmith === 'function') {
opts.metalsmith(metalsmith, opts, helpers)
} else if (opts.metalsmith && typeof opts.metalsmith.after === 'function') {
opts.metalsmith.after(metalsmith, opts, helpers)
}
// 将处理后的文件输出
metalsmith.clean(false)
.source('.') // start from template root instead of `./src` which is Metalsmith's default for `source`
.destination(dest)
.build(function (err, files) {
done(err)
if (typeof opts.complete === 'function') {
var helpers = {chalk, logger, files}
opts.complete(data, helpers)
} else {
logMessage(opts.completeMessage, data)
}
})
return data
}
сначала черезgetOptionsПолучена основная информация о конфигурации некоторых проектов, такая как имя проекта, информация о пользователе git и т. д. затем пройтиmetalsmithкомбинироватьaskQuestions,filterFiles,renderTemplateFilesЭти промежуточные компоненты завершают процесс создания шаблона проекта. **metalsmith** — генератор статических веб-сайтов с плагинами, все работает через плагины, поэтому его можно легко расширить.
По коду функции генерации легко увидеть, что процесс генерации проекта в основном состоит из следующих этапов.
Каждый процесс в основном использует следующие библиотеки:
- getOptions: в основном читается под шаблоном
meta.jsonилиmeta.js,meta.jsonОбязательный файл, который предоставляет различную информацию для cli, такую как пользовательские помощники, настраиваемые параметры, правила фильтрации файлов и многое другое. Как написать собственный шаблон, вы можете обратиться кздесь - Прочитайте содержимое шаблона через Metalsmith.Следует отметить, что содержимое шаблона в настоящее время еще не обработано, поэтому оно выглядит так:
/* eslint-disable no-new */
new Vue({
el: '#app',
{{#router}}
router,
{{/router}}
{{#if_eq build "runtime"}}
render: h => h(App){{#if_eq lintConfig "airbnb"}},{{/if_eq}}
{{/if_eq}}
{{#if_eq build "standalone"}}
template: '<App/>',
components: { App }{{#if_eq lintConfig "airbnb"}},{{/if_eq}}
{{/if_eq}}
}){{#if_eq lintConfig "airbnb"}};{{/if_eq}}
- Получить индивидуальную конфигурацию: в основном черезasyncа такжеinquirerКооперация завершает набор пользовательских конфигураций.
- filterFiles: фильтровать файлы поminimatchВыполните сопоставление файлов.
- Шаблон рендеринга: пройтиconsolidate.jsСотрудничатьhandlebarsфайл рендеринга.
- выход: прямой выход
vue-initВесь рабочий процесс примерно такой,vue-cliЯвляясь удобным инструментом командной строки, его код также лаконичен и прост для понимания, а проанализировав исходный код, можно найти множество интересных модулей, используемых в нем.
bin/vue-list
vue-listФункция очень проста, потянитеvuejs-templatesинформация о шаблоне и вывод.
bin/vue-build
vue-buildЭто запуск проекта через конфигурацию веб-пакета, если запись только одна.vueкомпонент, используйте значение по умолчаниюdefault-entry.es6Загрузите компонент и визуализацию.
разное
При просмотре исходного кода vue-cli я обнаружилuser-homeЭтот модуль, содержание этого модуля выглядит следующим образом:
'use strict';
module.exports = require('os-homedir')();
os-homedirЭтот пакет являетсяos.homedirполифилл, вWhy not just use the os-home module?вниз, я вижуModules are cheap in Node.jsэтот блог. ФактическиsindresorhusНаписал множество однострочных узловых модулей, и ему также нравятся однострочные узловые модули, потому что чем меньше модуль, тем выше гибкость и возможность повторного использования. Конечно, по поводу One-line модулей у всех разное мнение, ведь не в первый раз слышу слова "просто эта функция может написать пакет в tm". Я думаю это зависит от человека к человеку.Кто sindresorhus,автор многих известных open source проектов,опубликовал 1000+ npm пакетов,и большинство используемых им модулей написаны им самим,поэтому для него с помощью различных удобно использовать «строительные блоки» для формирования «высотных зданий». Однако для других людей, если они привыкли к этому методу, они могут стать более зависимыми от этих вещей, точно так же, как многие фронтенд-разработчики теперь полагаются на фреймворки, а не на фундамент, поэтому я думаю, что этот метод разработки «строительных блоков» вполне подходит. Хорошо, но лучше знать почему. Но я чувствую, что модули One-line малоэффективны, как и модуль user-home, без него,const home = require('os-homedir')();Он также может достичь своей цели. Это может быть связано с обсессивно-компульсивным расстройством. Пользователь-дом родился, и это похоже наnegative-zeroТакие однострочные модули — один из немногих сценариев использования, и никакого удобства они не приносят, особенно в версии 2.0, этот пакет напрямую использует Object.is для суждения:
'use strict';
module.exports = x => Object.is(x, -0);
Я не знаю, что все думают об однострочных модулях?
#### Завершение объявления о вакансии NetEase Koala набирает старших инженеров по разработке интерфейсов в здании NetEase Building, Биньцзян, Ханчжоу.Нажмите на меня, чтобы узнать подробности и отправить резюме.