предисловие
Постепенно мы все стали тем человеком (титульным участником), которого больше всего ненавидели в то время.
Но содержание явно важнее формы. Я надеюсь, что благодаря этой статье читатели смогут в полной мере ощутить процесс разработки лесов с нуля до единицы.
Исследования и обсуждение
Хотя проекту не уделяется много внимания, процесс проекта все равно должен существовать. Во-первых, два члена были завербованы через Амли. Просто пообщайтесь с вами на встрече:
1. Исследование основных решений на рынке
Во-первых, когда дело доходит до скаффолдинга, он должен быть неотделим от мейнстрима в реагирующем сообществе.create-react-app
, но был неожиданно всеми исключен в первый раз. В основном потому, что его конфигурация недостаточно гибкая, правильноwebpack
Пакет слишком мёртв, что делает его немного бессильным при работе со сложными проектами, и хотя предоставляемые им функции очень общие, они также достаточно просты. Я думаю, в этот момент кто-то скажет, вы можетеeject
Давай, выложи исходный код? Но в данном случае мне нет смысла его использовать, а стоимость вторичной разработки на основе его исходников точно не будет низкой.
Затем мы повернули цель кvue-cli
, Неожиданно завоевал единодушную похвалу всех. Я думаю, что самое лучшее в нем то, что он обеспечивает хороший баланс между универсальностью и гибкостью своих функций. Это сvue.js
Философия фреймворка очень последовательна, поэтому сvue
Совмещая девелоперские проекты, будет ощущение текущей воды, и с этим согласны все.cli
(Интерактивный инструмент командной строки) Мне это нравится, и это то, что ниже. Те, кто его использовал, должны быть впечатлены.
Сказать, что если у него есть какие-то серьезные проблемы, подумайте об этом, считается ли это отсутствием поддержки?
Затем наша цель — разработать метод использования, аналогичныйvue-cli
Реагировать на строительные леса. до@vue/cli
Понимание этого остается только на уровне использования, поэтому сначала необходимо понять его реализацию. Как говорится, легко реализовать (скопировать), познав себя и познав другого.
2. Анализ исходного кода @vue/cli
мой клон4.5.14версии, когда была написана новая версия 5.0, и она все еще находилась в стадии бета-версии, пропустите ее.
Общий код должен использоватьlerna + yarn-workspace
Пакеты, которые поддерживаются и связаны с официальными функциями Vue, включены в@vue
под этим доменом npm (кто-то также назвал организацию npm).
Как показано выше, полный@vue/cli
Функция в основном состоит из трех частей:
-
@vue/cli
Отвечает за сбор параметров командной строки. -
@vue/cli-service
Этот пакет является движком и ядром запуска vue и содержит конфигурацию веб-пакета. -
@vue/plugin-xxx
Плагин vue-cli, один плагин соответствует одной функции и взаимно-однозначное соответствие с пользовательскими параметрами функций, указанными выше.
Разделение cli и основного пакета функций является основным методом распаковки.webpack-cli & webpack
,@babel/cli & @babel/core
Все они реализованы таким образом, что относится к многоуровневой архитектуре разработки программы: cli (верхний уровень) должен зависеть от основной службы (нижний уровень), но основная служба (нижний уровень) не зависит от cli ( верхний слой) и по-прежнему может работать независимо.
Первый шаг в чтении исходного кода, начните сpackage.json
Начать. Этот тип пакета, используемый командой, передается черезpackage.json
изbinполе для реализации.
"bin": {
"vue": "bin/vue.js"
},
Следуй за виноградной лозой, открывайbin/vue.js
,здесь
использовать здесьCommander
Этот инструмент синтаксического анализа командной строки регистрирует некоторые глобальные команды, обратите внимание только здесьcreate
Эта команда в порядке.
глобальныеvue create xxx
При выполнении команды запускается именно этот файл.когдаvue create xxx
Когда команда сработает, она будет выполнена../lib/create
Этот файл поместит имя проектаname
Передайте это, продолжайте следить../lib/create.js
.
существуетcreate
в основной функции. Сначала укажите целевой путь, по которому будет создан проект.targetDir
(В большинстве случаев здесь стучитеvue create
Каталог, в котором находится команда + входящий проектname
).
Далее идет обработка элемента с таким же названием, который уже существует на диске. Далее дело в том,new Creator
Этот класс официально запускает основной процесс создания проекта.
найти этоCreator
class, вы можете обнаружить, что он наследует узелEventEmiter
Этот класс обработки событий должен реализовать весь свой механизм подключаемых модулей, который аналогичен процессу написания подключаемых модулей веб-пакетов, который требует подписки на некоторые внутренние перехватчики для реализации режима событий на основе публикации и подписки, что будет объяснено ниже. подробно ниже.
Спускаясь вниз, вам нужно включить отладку точек останова, чтобы вы могли более четко видеть весь его запущенный процесс.
Похожа ли опция взаимодействия в красном поле слева? Да, соответствующий интерактивный интерфейс появился выше.
Чтобы облегчить выбор пользователя, vue предварительно устанавливает некоторые наборы функций.Creator
Категорияconstuctor
Он просто инициализирует некоторые атрибутивные переменные, а ядром является следующий вызовcreate
Метод экземпляра.
передачаpromptAndResolvePreset
, появится интерфейс предустановленных параметров, ✅ вариант по умолчанию, продолжайте;
можно увидеть слеваpresets
Это указывает на то, что данные выбранного пресета уже содержат данные, содержащиеся в пресете.babel、 eslint
и другие плагины.
Изменить пресет и выбрать ручной режим? Как показано ниже: получается та же структура данных.
Далее стоит датьpresets
внутреннийplugins
Для каждого плагина в массиве инициализируйте некоторые параметры по умолчанию.
Далее инициализируем генерациюpackage.json
Необходимые данные.
Вставьте плагин, включенный в пресет, прямо сейчасdevDependencies
зависимости развития.
Вставка прошла успешно, и вы уже можете видеть, что 3 зависимости разработки включены в стек отладки
Далее будетpackage.json
Записать на диск.
воплощать в жизньnpm install
, установить зависимости.
Затем сделайте еще кое-что: напишитеnpmrc、yarnrc
файл, инициализироватьgit
Склады и прочие неважные вещи проходят быстро.
Суть в том, чтобы использовать только что установленный плагин для создания шаблона проекта.
this.resolvePlugins(preset.plugins, pkg)
Этот метод имеет решающее значение и используется для внедрения плагинов. Но прежде чем представить этот метод, я хотел бы рассказать о механизме плагинов фреймворка и его использовании вvue/cli
Дизайн и реализация в .
Механизм плагина:
Он предназначен для инкапсуляции некоторых дополнительных или определяемых пользователем функций.Вставить по требованиюПреимущества этого дизайна: он может разделить сложность кода и функциональную связность, а также значительно увеличить производительность фреймворка.Масштабируемость.
Плагины, вы должны сначала определить, как подключить. Это также самый важный момент вставного механизма, т.Разработчики фреймворка и разработчики подключаемых модулей должны согласовать фиксированный метод доступа к подключаемым модулям.. Это соглашение, отраженное в vue/cli, показано на следующем рисунке.
Каждый плагин имеетgenerator
папка должна бытьindex.js
,Потомindex.js
Функцию необходимо экспортировать, а в теле функции можно вызывать некоторые методы инструментов внедрения внешнего тела, например,
-
api.injectImport()
Вставьте модуль импорта в проект. -
api.extendPackage()
package.json проекта расширения -
api.render('./template')
Используйте ejs для рендеринга файлов шаблонов (условная компиляция)
Оглянись на вершинуthis.resolvePlugins(preset.plugins, pkg)
метод, полученное здесь применение на самом деле является функцией, экспортируемой соглашением о подключаемом модуле, но здесь следует отметить, что это толькоВременно сохраните метод применения, и вызываться не будет.
Оригиналplugins
, после обработки этот метод преобразуется в новый, содержащий определенные функции плагинаplugins
.
{ id: options } => [{ id, apply, options }]
Затем передайте отсортированные плагиныGenerator
В этом классе начинается последний и самый существенный шаг:построить проект.
Можно сказать, что большая подготовительная работа, такая как сбор параметров, сортировка и внедрение плагинов, приходится на окончательный этап генерации.
new
После этого последовалgenerate
Этот метод экземпляра, поэтому далее сосредоточьтесь на реализации этого метода
выполнение метода, первый вызовthis.initPlugins()
, самое главное в этом методе — пройти и выполнить метод применения по умолчанию всех плагинов (то есть функцию, которая экспортируется по умолчанию в упомянутом выше механизме плагина),apply
Первый параметрapi
Содержатьrender
Рендеринг шаблонов EJS и другие возможности, и эти возможности приходят изGeneratorAPI
Этот класс, обратите внимание на второй параметр, поставит текущийthis
входящий.
Далее продолжайте читатьGeneratorAPI
реализация. сначала исключить@vue/cli-service
этот пакет, потому что этот пакет существует вplugins
В массиве, но он очень особенный. Он относится к основному сервису. Он не относится к категории плагинов в строгом смысле. Его не нужно обрабатывать как плагин, а нужно только участвуйте в установке.Ничего особенного.
GeneratorAPI
Общая реализация принимает дизайн промежуточного программного обеспечения, на котором_injectFileMiddleware
метод, вызов метода в API будет сохранен первым в виде функции push и не будет выполняться в настоящее время.
взять то, что было сказано вышеapi.render()
Пример метода шаблона рендеринга при вызове плагина exportedapply
метод, он вызываетapi.render()
звонить, но не использоватьejs
Скомпилируйте файлы шаблонов, но подготовьте ихthis.generator.fileMiddlewares
в этом промежуточном временном массиве.
Такapi.render()
Где эти методы действительно работают?
Откройте немедленно выполненныйthis.resolveFiles
метод, правда здесь.
использоватьfor of
последовательно вызывать каждыйmiddleware
функция для получения окончательного содержимого файла, которое будет сгенерировано
сейчас,this.files
сохранить полныйПуть к файлуприбытьсодержание документаотображения, как показано в левой части рисунка выше.
Далее некоторые общие операции.sortPkg
даpackage.json
Зависит от того, чтобы разобраться в порядке, чтобы удовлетворить чувства какого-то обсессивно-компульсивного расстройства.
Далее, согласноthis.files
,передачаwriteFileTree
С удовольствием записывайте файлы на диск.
Окончательная сгенерированная структура каталогов выглядит следующим образом, и процесс представлен.
3. Определите функции и цели
передняя пара@vue/cli
Подробный анализ можно свести к трем ключевым моментам.
-
- использоватьИнтерфейс командной строкивыбор функций
-
-
cli
а также核心服务
@vue/cli-service (конфигурация веб-пакета) использует многоуровневый дизайн,независимый пакет
-
-
- Механизм плагина, создавать различные файлы шаблонов функций по мере необходимости
Такой дизайн необходим для поддержки всех разработчиков Vue, потому что он должен быть очень гибким. Однако для скаффолда, удовлетворяющего только конкретную команду, он слишком сложен, а стоимость разработки будет очень высока, просто для того, чтобы разделить различные функциональные плагины, требуется очень большая рабочая нагрузка. Во-вторых, самое главное для командной разработки проекта — это унификация и стандартизация.Многие конфигурации и функции могут быть встроены по умолчанию, например процессоры eslint, babel и css.Все это необходимые функции при командной разработке проекта, поэтомуРазнообразие конфигураций и гибкость не являются основными факторами. Следовательно, от третьего подключаемого механизма можно отказаться.
cli отделен от конфигурации веб-пакета, так что оба могут быть достигнутыОбновление автономной версии, что способствует непрерывному сопровождению пользовательских проектов, но стоимость этого заключается в том, что вам нужно определить наборwebpack
Конфигурация сильно отличается от соглашения о конфигурации, это в@vue/cli-service
в использованииvue.config.js
В качестве файла конфигурации другие основные каркасы, такие какcreate-react-app
Это полностью. В этом случае также требуется подробный документ конфигурации скаффолдинга, а веб-пакет настраивается путем настройки скаффолдинга, что делает знания о конфигурации веб-пакета, которые мы освоили, бесполезными.chainWebpack
Это решение, но насколько сложно им пользоваться, это могут оценить только те, кто им пользовался. Нам может просто понадобиться прозрачныйwebpack
конфигурация, всеrules、plugins
Все они могут быть изменены напрямую, так что никакой документации не требуется, и все можно сделать с помощью конфигурации веб-пакета, тем более, что эта конфигурация веб-пакета уже готова в нашей команде, поэтому второй пункт, упомянутый выше, не требуется.
Таким образом, нам нужно научиться в основном интерактивным инструментам командной строки и компиляции шаблонов ejs по запросу. В то же время мы уточняем функции, исходя из особенностей проекта нашей команды.После обсуждения с нашими партнерами у нас в основном есть следующие варианты:
(1) Мобильный или ПК?
Сторона ПК будет иметь встроенныйantd
Шаблон макета , мобильный терминал откроетсяpx2rem
Адаптация, встроенная в htmlflexible.js
сценарий.
(2) Создать одностраничный или многостраничный шаблон?
MPA
а такжеSPA
Требования существуют в сценариях наших проектов, поэтому имеет смысл различать их на уровне каркаса.
(3) Библиотека управления состояниями, версия React-Router установлена по требованию
развитие функции
Инициализировать проект
- monorepo
Его преимущество перед единым хранилищем заключается в том, что он способствует эффективной совместной отладке между несколькими npm.node_modules
совместное использование дискового пространства
Поскольку продвижение зависимостей lerna слишком строгое в отношении номера версии зависимости и не хватает многихyarn-workspace
Уникальная функция (особенно локальная обработка мягких ссылок для корзины и модуля). В настоящее время общепринятой практикой является использованиеyarn
изworkspace
До зависит от руководства,lerna
Автоматическое управление версиями и распространение пакетов npm.
используется здесьmonorepo
Причина в том, что такие проекты, как библиотеки компонентов или веб-плагины, могут быть разработаны на основе этих каркасов, чтобы облегчить совместную отладку между ними.
npm i -g lerna
lerna init
lerna.json
{
"packages": [
"packages/*"
],
"version": "0.1.6",
"npmClient": "yarn",
"useWorkspaces": true
}
package.json
...
"workspaces": [
"packages/*"
],
...
Создать кли-пакет
lerna create react-booster-cli
Инициализировать следующий проект
yarn install
Следующим шагом является реализация функции cli.Во-первых, при анализе исходного кода vue/cli было упомянуто, что глобальная команда, используемая глобальным пакетом, проходит черезpackage.json
изbin
Полевая реализация, мы делаем то же самое.
booster/packages/react-booster-cli/package.json
"bin": {
"booster": "bin/booster.js"
},
Далее создайте./bin/booster.js
документ
#!/usr/bin/env node
// 命令行解析工具
const program = require('commander');
program
.version(require("../package").version)
.usage("<command> [options]");
program.command("create <project-name>")
.description("创建一个新的项目")
.action((projectName)=>{
require('../lib/create')(projectName)
})
program.parse(process.argv);
#!/usr/bin/env node
Это предложение очень важно, заявив, что этот файл нужно использоватьnode
программа для выполнения. используется внутриcommander
Эта библиотека разбора параметров командной строки, установите ее
yarn workspace react-booster-cli add commander
Теперь мы можем протестировать и запустить наш процесс и выполнить его в корневом каталоге бустера.
npx booster
Следующий экран появляется даже в случае успешного
Некоторым может быть любопытна причина успеха операции, я кратко объясню ее здесь. Прежде всего,npx xxx
сначала пойдет в текущий каталогnode_modules/.bin/
Найдите файл xxx в каталоге. Очевидно, он существует. Почему так?Хотя объявлена глобальная команда, но написанный пакет cli не выдается, а другой не устанавливается.
На самом деле этоyarn install
Побочная (супер приятная) функция , если быть точным, с помощьюworkspace
,yarn install
Автоматически поможет решить проблемы установки и ссылки, принцип находится вnode_modules/.bin
Создайте софт-цепочку в каталоге (по аналогии с ярлыком файла на win), ссылку наpackages/react-booster-cli/bin/booster.js
.
выполнить следующийcreate
Командование пойдет командиромaction
, передайте имя проекта методу создания в файле создания, что согласуется с vue/cli
Реализация функции
Реализовать метод создания
Есть много наборов инструментов, которые обычно используются в cli. Ниже есть примечания о назначении каждого инструмента. Многие на самом деле используются для того, чтобы сделать командную строку более красивой. Возможно, большая часть экосистемы npm — это фронтенд-разработчики, а типы и количество пакетов, украшающих командную строку, чрезвычайно богаты. Например, вы можете использоватьora
,chalk
Очень удобно реализовать некоторые эффекты загрузки командной строки, цветные шрифты и индикаторы выполнения, чтобы повысить удобство работы с командной строкой.
lib/create.js
const path = require("path");
const fs = require("fs");
// 检测目录是否存在
const exists = fs.existsSync;
// 删除文件
const rm = require("rimraf").sync;
//询问cli输入参数
const ask = require("./ask");
// 命令行交互工具
const inquirer = require("inquirer");
// 命令行loading
const ora = require("ora");
// 输出增色
const chalk = require("chalk");
// 检测版本
const checkVersion = require("./check-version");
const generate = require("./generate");
const { writeFileTree } = require("./util/file");
const runCommand = require("./util/run");
// loading
const spinner = ora();
async function create(projectName) {
const cwd = process.cwd(); //当前运行node命令的目录
const projectPath = path.resolve(cwd, projectName);
// 假如当前已存在同名项目,询问是否覆盖
if (exists(projectPath)) {
const answers = await inquirer.prompt([
{
type: "confirm",
message: "Target directory exists. Do you want to replace it?",
name: "ok",
},
]);
if (answers.ok) {
console.log(chalk.yellow("Deleting old project ..."));
rm(projectPath);
await create(projectName);
}
} else {
// 收集用户输入选项
const answers = await ask();
spinner.start("check version");
// 检测版本
await checkVersion();
spinner.succeed();
console.log(`✨ Creating project in ${chalk.yellow(projectPath)}.`);
// console.log(answers);
// 更新 package.json
const pkg = require("../template/package.json");
// 生成项目配置文件,app.config.json
const appConfig = {};
const { platform, isMPA, stateLibrary,reactRouterVersion } = answers;
if (platform === "mobile") {
pkg.devDependencies["postcss-pxtorem"] = "^6.0.0";
pkg.dependencies["lib-flexible"] = "^0.3.2";
} else if (platform === "pc") {
pkg.dependencies["antd"] = "latest";
}
pkg.dependencies[stateLibrary] = "latest";
if (reactRouterVersion === "v5") {
pkg.devDependencies["react-router"] = "5.1.2";
} else if (reactRouterVersion === "v6") {
pkg.dependencies["react-router"] = "^6.x";
}
appConfig.platform = platform;
spinner.start("rendering template");
const filesTreeObj = await generate(answers,projectPath);
spinner.succeed();
spinner.start("🚀 invoking generators...");
await writeFileTree(projectPath, {
...filesTreeObj,
"package.json": JSON.stringify(pkg, null, 2),
"app.config.json": JSON.stringify(appConfig, null, 2),
});
spinner.succeed();
console.log(`🗃 Initializing git repository...`)
await runCommand('git init')
console.log();
console.log(
`🎉 Successfully created project ${chalk.yellow(projectName)}.`
);
console.log(
`👉 Get started with the following commands:\n\n` +
chalk.cyan(` ${chalk.gray("$")} cd ${projectName}\n`) +
chalk.cyan(` ${chalk.gray("$")} npm install or yarn\n`) +
chalk.cyan(` ${chalk.gray("$")} npm run dev`)
);
console.log();
}
}
module.exports = (...args) => {
return create(...args).catch((err) => {
spinner.fail("create error");
console.error(chalk.red.dim("Error: " + err));
process.exit(1);
});
};
Определить версию
lib/check-version.js
const request = require('request')
const semver = require('semver')
const chalk = require('chalk')
const packageConfig = require('../package.json')
module.exports = function checkVersion() {
return new Promise((resolve,reject)=>{
if (!semver.satisfies(process.version, packageConfig.engines.node)) {
return console.log(chalk.red(
` You must upgrade node to >= ${packageConfig.engines.node} .x to use react-booster-cli`
))
}
request({
url: 'https://registry.npmjs.org/react-booster-cli',
}, (err, res, body) => {
if (!err && res.statusCode === 200) {
const latestVersion = JSON.parse(body)['dist-tags'].latest
const localVersion = packageConfig.version
if (semver.lt(localVersion, latestVersion)) {
console.log()
console.log(chalk.yellow(' A newer version of booster-cli is available.'))
console.log()
console.log(` latest: ${chalk.green(latestVersion)}`)
console.log(` installed: ${chalk.red(localVersion)}`)
console.log()
}
resolve()
}else{
reject()
}
})
})
}
Выбор функций командной строки
Ядро заключается в использованииinquirer
Этот пакет используется для реализации интерактивного интерфейса командной строки.Этот очень мощный пакет предоставляет интерактивные методы, такие как одиночный выбор, множественный выбор, поле ввода и т. д., как и командная строка.form
какие!
lib/ask.js
const { prompt } = require('inquirer');//生成命令行交互界面
const questions = [
{
name: 'platform',
type: 'list',
message: '您的web应用需要运行在哪个端呢?',
choices: [{
name: 'PC端',
value: 'pc',
}, {
name: '移动端',
value: 'mobile',
}]
},
{
name: 'isMPA',
type: 'list',
message: '生成单页or多页模版?',
choices: [{
name: '单页(SPA)',
value: false,
}, {
name: '多页(MPA)',
value: true,
}]
},
{
name: 'stateLibrary',
type: 'list',
message: '您希望安装的状态管理库是?',
choices: [{
name: 'mobx',
value: 'mobx',
}, {
name: 'redux',
value: 'redux',
}]
},
{
name: 'reactRouterVersion',
type: 'list',
message: '选择react-router版本',
choices: [{
name: 'v5(推荐)',
value: 'v5',
}, {
name: 'v6(对hook支持度较好,但api不够稳定)',
value: 'v6',
}]
},
]
module.exports = function ask () {
return prompt(questions)
}
Создание файлов проекта
lib/generate.js
const { isBinaryFileSync } = require("isbinaryfile");
const fs = require("fs");
const ejs = require("ejs");
const path = require("path");
/**
* @name 渲染文件
* @param {*} filePath 文件路径
* @param {*} ejsOptions ejs注入数据对象
* @returns 文件内容
*/
function renderFile(filePath, ejsOptions = {}) {
// 二进制文件直接返回
if (isBinaryFileSync(filePath)) {
return fs.readFileSync(filePath);
}
const content = fs.readFileSync(filePath, "utf-8");
//src目录下需要经过ejs动态编译
if (/[\\/]src[\\/].+/.test(filePath)) {
return ejs.render(content, ejsOptions);
}
// 其他文件,比如webpack的配置文件,直接读取返回
return content;
}
/**
* @name 生成项目文件
* @param {*} answers 收集的问题
* @returns 文件树 eg { '/path/a/b' : 文件内容 }
*/
async function generate(answers, targetDir) {
const globby = require("globby");
// 匹配脚手架文件夹所有文件
const fileList = await globby(["**/*"], {
cwd: path.resolve(__dirname, "../template"),
gitignore: true,
dot: true,
});
const { isMPA } = answers;
// ejs注入的模版变量
const ejsData = {
...answers,
projectDir: targetDir,
pageName:'index'
};
// 生成文件树对象
const filesTreeObj = {};
fileList.forEach((oriPath) => {
let targetPath = oriPath;
const absolutePath = path.resolve(__dirname, "../template", oriPath);
if (isMPA && /^src[\\/].+/.test(oriPath)) {
// 针对多页场景,生成多页面模版
const [dir, file] = oriPath.split(/[\\/]+/);
["index", "pageA", "pageB"].forEach((pageName) => {
targetPath = `${dir}/pages/${pageName}/${file}`;
filesTreeObj[targetPath] = renderFile(absolutePath, {
...ejsData,
pageName,
});
});
} else {
const content = renderFile(absolutePath, ejsData);
filesTreeObj[targetPath] = content;
}
});
return filesTreeObj;
}
module.exports = generate;
Вставьте параметры, собранные из командной строки, в шаблон ejs.
Например, собирается из командной строки при взаимодействии с пользователем.platform
Этот параметр представляет веб-платформу.
Когда ejs рендерит,platform = mobile
, а это значит, что выборка мобильная, достаточно вставить ее в тег head в html-шаблонеflexible.js
Скрипт, ПК, значит, не требуется. Это позволяет разделить окончательный сгенерированный код для различных функций.
После того, как разработка функции будет завершена, поскольку у большинства компаний есть свои собственные библиотеки npm, я продемонстрирую здесь шаги по выпуску общедоступного пакета, которые на самом деле похожи.
Опубликовать пакет npm
npm login
lerna publish
На этом этапе отправки посылки довольно легко наступить на яму Вот краткое изложение того, с чем я столкнулся:
-
-
Имя пакета, предоставляемого npm, должно быть уникальным.
лучше идти пораньшеnpmВыполните поиск на веб-сайте, чтобы узнать, существует ли уже имя пакета, который вы собираетесь отправить. Или заплатите за частный домен, что-то вроде @vue/xxx.
-
-
-
Ударение Lerna Pream не вступает в силу.
При запуске lerna publish, если в середине произойдет сбой выпуска пакета, при повторном запуске lerna publish из-за того, что тег git был помечен, пакет не будет повторно опубликован в NPM.
Решение: запустите lerna publish из-git, пакет NPM, задействованный в текущем теге, будет снова опубликован, PS: package.json не будет обновляться, просто выполните npm publish
-
-
- Проблема, вызванная глобальной модификацией исходного кода Taobao npm
-
Есть задержка в синхронизации между источником Taobao и официальным источником
Пакет npm был успешно выпущен, но поскольку глобальной настройкой является источник Taobao, в личном тесте будет определенная задержка синхронизации, примерно от получаса до часа, поэтому он может не быть обновлен до последней версии пакета или первый релиз прошел успешно, через некоторое время пакет не был найден.
-
Если источник Taobao используется глобально, это приведет к сбою пакета.
Потому что источник Taobao может только загружать пакеты, но не загружать пакеты. Но без исходного кода Taobao установка других зависимостей происходит медленно. Решение: Устанавливайте зависимости и единообразно извлекайте их из источников Taobao, чтобы обеспечить скорость установки зависимостей. При отправке пакета используйте package.json пакета npm.
publishConfig
Поле указывает официальный источник, чтобы убедиться, что пакет может быть отправлен успешно."publishConfig": { "registry": "https://registry.npmjs.org/", "access": "public" },
-
- devDependenciesа такжеdependenciesразница
Во-первых, в обычных бизнес-проектах между ними нет существенной разницы. То есть при установке, с --dev или без, это повлияет только на окончательный
package.json
Расположение классификации в , в конечном итоге будет упаковано и построено с помощью таких инструментов, как веб-пакет, зависит только от того, есть ли на него ссылка в проекте.Но для проектов, размещенных на npm, это важно. Когда пользователь устанавливает ваш пакет,Только производственные зависимости будут установлены вместе, зависимости разработки не будет. Если он используется неправильно, например, при случайной загрузке производственной зависимости в зависимость для разработки, пользователь, установивший ваш пакет npm, выдаст ошибку и не сможет найти модуль xx.
наконец
адрес нпм,гитхаб-адрес, вы можете попробовать это,issues
. Этот проект был разработан в свободное время,Приведенное выше название и сюжетная линия также являются чисто вымышленными.. Код полностью десенсибилизирован и общедоступен. Если у вашей команды есть похожие потребности, вы можете предоставить вам ссылку. Это моя лучшая прибыль.