Долгое время я думал, что сделать мой VS Code довольным внешним импортом файла Solidity (так, как того требует Трюфель, - это безнадежная задача). Я справился с красными кричащими волнистыми линиями. Я научился игнорировать и 😒.

TL; DR

Если вы настраиваете стандартный проект трюфелей через `truffle init` или` truffle unbox`, вы можете использовать следующие настройки в VS Code:

"solidity.packageDefaultDependenciesContractsDirectory": "",
"solidity.packageDefaultDependenciesDirectory": "node_modules"

Импортировать из внешнего пакета как обычно (после установки с помощью npm) вот так:

import "openzeppelin-solidity/contracts/math/SafeMath.sol";

Счастливый взлом Solidity с безошибочной IDE, автозаполнением и поиском определений.

Почему (собственно) импорт полезен

При правильной настройке плагин Solidity может получить автозаполнение из всех импортированных файлов (и их дочерних импортируемых файлов тоже). Автозаполнение еще не контекстно, но дает некоторую информацию о том, где определен элемент завершения.

С последней версией вы можете перейти к определениям внешнего импорта, а также к переменным и функциям, определенным во внешних пакетах 🎉.

Я внес эту функциональность, реализовав соответствующее событие в LSP (Протокол языкового сервера), поэтому потенциально его можно использовать и в других IDE (Atom, Sublime, Remix). Есть еще много функций, которые мы можем реализовать для Go to Definition и LSP в целом в VSCode Solidity. Зайдите на Github и присоединяйтесь к поезду #BUIDL, если у вас есть что-то в вашем списке желаний.

Как работает импорт в Solidity

Читайте предысторию моего решенного разочарования и неприятных вещей под ковриком плагинов Solidity, Truffle и VSCode Solidity.

Это была обычная ночь, когда меня все больше раздражало (снова!):

  • я не помню подпись конструктора контракта, которую я унаследовал от
  • OpenZeppelin продолжает изменять реализацию контракта и интерфейсы (по уважительным причинам)
  • Плагин VS code Solidity не позволяет мне перейти к импортированному файлу
  • Контракт OpenZeppelin c̶o̶n̶v̶o̶l̶u̶t̶e̶d̶l̶y̶ ̶n̶e̶s̶t̶e̶d̶ категоризирован во вложенных папках
  • и код VS, по умолчанию не разрешающий поиск в node_modules.

Я решил превратить свои бесконечные щелчки мышью и прокрутку в более продуктивные детективные забавы (вставьте шутки о отвлеченных программистах). По-видимому, это была не необычная проблема, и (шокирующе) плагин Solidity разработан для работы с импортом »🤔.

Ответ заключается в двух упомянутых выше настройках, packageDefaultDependenciesContractsDirectory и packageDefaultDependenciesDirectory, а также в том факте, что в Solidity нет стандарта на то, как ссылаться на импорт внешнего пакета.

Для нелокального импорта (тот, который не начинается с . И не является абсолютным путем), компилятор по своему усмотрению применяет переназначение для разрешения импорта:

Когда компилятор вызывается, можно не только указать, как обнаруживать первый элемент пути, но также можно указать переопределение префиксов пути, например, github.com/ethereum/dapp-bin/library переназначается на /usr/local/dapp-bin/library, и компилятор будет читать файлы оттуда.

Трюфель

Truffle использует truffle-resolver для разрешения зависимостей от EthPM и NPM. В частности, для NPM он ищет пакеты в node_modules и заменяет префикс только на путь файловой системы.

Кроме того, Трюфель заявляет, что проект Truffle должен использовать / контракты для хранения файлов * .sol и / build (/ контракты) для вывода сборки. Однако преобразователь не обеспечивает соблюдение этой структуры проекта, поскольку не все пакеты npm Solidity следуют этому макету.

Поэтому мы импортируем по имени пакета, за которым следует относительный путь от корня пакета npm. Для openzeppelin-solidity мы используем

import "openzeppelin-solidity/contracts/math/SafeMath.sol";

VSCode Solidity

Расширение VSCode Solidity предоставляет две настройки со значениями по умолчанию для управления разрешением внешних зависимостей:

  • solidity.packageDefaultDependenciesDirectory: node_modules
  • solidity.packageDefaultDependenciesContractsDirectory: контракты

packageDefaultDependenciesDirectory добавляет префикс к пакету и разрешается из корня проекта. packageDefaultDependenciesContractsDirectory указывает, где искать файлы * .sol внутри внешнего пакета.

import "package/folder1/contract.sol";

расширяется до

import "{projectRoot}/{packageDefaultDependenciesDirectory}/package/{packageDefaultDependenciesContractsDirectory}/folder1/contract.sol";

Хотя значение по умолчанию контракты может показаться невинным, на самом деле оно создает дубликат в проекте Truffle. Предыдущий импорт расширится до

import "{projectRoot}/node_modules/openzeppelin-solidity/contracts/contracts/math/SafeMath.sol";

Ой. Установка пустого значения packageDefaultDependenciesContractsDirectory будет соответствовать стандарту Truffle 🧐.

Бонусный совет🤫

Вы были разочарованы, когда VSCode закрывает каждый файл, который вы открывали для справки, но не редактировали? Оказывается, это особенность (?!), А не ошибка. Вы можете закрепить файл для выхода из режима предварительного просмотра, дважды щелкнув заголовок файла или вкладки. Вы также можете отключить режим предварительного просмотра при определенных условиях или полностью в настройках.

Я понимаю, насколько это полезно для поддержания чистоты на рабочем месте, но я часто обнаруживал, что эта функция контрпродуктивна. Было бы лучше, если бы файл закрылся после некоторого времени бездействия или спрятался в списке вкладок?

Подтверждение

И последнее, но не менее важное, я хотел бы поблагодарить Хуана Бланко и всех других участников до меня за замечательный плагин VSCode Solidity. Ставьте звезду репо, чтобы показать свою любовь уже сегодня!