Tern - отличный инструмент для Javascript, но иногда мне трудно рассуждать о нем, что ведет меня к черным дырам несогласованной настройки конфигурации, пока он не сработает волшебным образом. Недавно я более глубоко погрузился в понимание этого и хотел поделиться с вами (и со своим будущим, когда я вернусь к поиску в Google)
Tern:
- Http-сервер, который принимает почтовые запросы JSON.
- Обычно запускают в редакторе через плагин (vim, atom и т. Д.)
- Читает из
.tern-project
файла в корне проекта - При запуске создает файл
.tern-port
, чтобы ваш редактор знал, к какому порту подключаться. - Считывает серию файлов из вашего проекта в память и по запросу возвращает тип / автозаполнение и другую полезную информацию.
- См. Больше на https://ternjs.net/doc/manual.html
Проблема, с которой я обычно сталкиваюсь, заключается в том, что он, кажется, время от времени не может завершить [некоторые] вещи. Это можно продемонстрировать, создав конфигурацию и вручную запустив сервер с установленной опцией --verbose
. В приложении stockcreate-react-app
добавьте в корень проекта следующий файл
.tern-project
{ "libs": [ "browser" ], "loadEagerly": [], "dontLoad": [], "plugins": { "modules": {}, "es_modules": {}, "requirejs": {}, "commonjs": {} } }
Установите и запустите двоичный файл в другом терминале
# if you haven't installed tern already $ yarn global add tern $ cd project-dir $ tern --verbose # Outputs: Listening on port [port#]
теперь, когда у вас есть сервер, работающий в каталоге проекта, ваш редактор (у которого должен быть плагин tern https://ternjs.net/doc/manual.html#editor) должен выбрать файл .tern-port
и знать, что там - это запущенный сервер, и ему не нужно запускать новый.
Если я открою новый файл с именем autocompleteme.js
в каталоге src и попробую что-то завершить, я увижу следующее…
Так крачка ... работает? ¯_ (ツ) _ / ¯
Ну, вроде… все настроено на работу, но если вы попытаетесь получить доступ к какому-либо свойству импортированного объекта, вы не увидите никаких завершений.
Если вы вернетесь к терминалу, на котором запущен сервер, вы должны увидеть несколько поступивших запросов и ответов (это много JSON, поэтому просто прокрутите мимо, если вам нужно только объяснение).
Request: { "query": { "type": "completions", "types": true, "depths": true, "docs": false, "filter": true, "caseInsensitive": true, "guess": true, "sort": false, "expandWordForward": true, "omitObjectPrototype": false, "includeKeywords": false, "inLiteral": true, "file": "#0", "end": { "line": 2, "ch": 0 }, "lineCharPositions": true }, "files": [ { "type": "full", "name": "src/autocompleteme.js", "text": "import React, { Component } from \"react\";\n\nRea\n" } ] } Response: { "start": { "line": 2, "ch": 0 }, "end": { "line": 2, "ch": 3 }, "isProperty": false, "isObjectKey": false, "completions": [ { "name": "React", "type": "?", "depth": 0 } ] }
Вы можете видеть, что он отправляет текущий файл, а также позицию курсора и запрашивает параметры завершения. Ближе к концу получается один ... `React` с типом ?
, который мы видели в поле автозаполнения.
Если я прокручиваю вывод терминала вниз, я вижу запрос, который поступил после того, как я попытался получить доступ к свойству объекта.
Request: { "query": { "type": "completions", "types": true, "depths": true, "docs": false, "filter": true, "caseInsensitive": true, "guess": true, "sort": false, "expandWordForward": true, "omitObjectPrototype": false, "includeKeywords": false, "inLiteral": true, "file": "#0", "end": { "line": 2, "ch": 6 }, "lineCharPositions": true }, "files": [ { "type": "full", "name": "src/autocompleteme.js", "text": "import React, { Component } from 'react';\n\nReact.\n" } ] } Response: { "start": { "line": 2, "ch": 6 }, "end": { "line": 2, "ch": 6 }, "isProperty": true, "isObjectKey": false, "completions": [] }
И есть варианты нулевой доработки… хммм. Заглянув в документацию (https://ternjs.net/doc/manual.html#req_files), я вижу, что есть конечная точка для получения файлов, проанализированных сервером, в основном всех файлов, которые tern
может рисовать. доработки из. Примерного запроса нет, поэтому, немного поработав, я смог придумать curl
запрос, который был принят ...
# get the port number from the `.tern-port` file $ curl -X POST https://localhost:57242 -d '{"query": {"type": "files"}}' # OUTPUT: {"files":[]}
Ага. Он не нашел никаких файлов, из которых можно было бы рисовать завершения, поэтому он выполняет только завершение из текста, найденного в текущем файле, который был отправлен в запросе от редактора.
По умолчанию локальные файлы загружаются на сервер Tern при выполнении запросов в редакторе. Http://ternjs.net/doc/manual.html#configuration
Это могло бы объяснить, почему он иногда работает, а иногда нет, даже с одним и тем же кодом ... Если у вас был запущен tern
server, и он читает файл, то он запомнит его и извлечет из него автозаполнения. Так что, если ваш редактор был открыт долгое время и было открыто много файлов, он мог бы, казалось бы, завершить все, только чтобы вернуться позже в тот же день, не касаясь конфигурации, и все кажется сломанным.
Как это исправить
Чтобы исправить это, убедитесь, что у вас есть правильные строки в конфигурации, которые могут указать серверу, где искать файлы и загружать их сразу при запуске. Для своих целей при написании javascript я обычно использую create-react-app
, который использует веб-пакет, поэтому я сосредоточусь на этом плагине, но есть и другие [здесь] (https://ternjs.net/doc/manual.html#plugins)
При использовании create-react-app
конфигурация веб-пакета входит в node_modules
, поэтому мы должны использовать путь к этому файлу.
{ "libs": [ "browser" ], "loadEagerly": [], "dontLoad": [], "plugins": { "modules": {}, "webpack": { "configPath": "./node_modules/react-scripts/config/webpack.config.dev.js" } } }
К сожалению, если мы попытаемся запустить здесь сервер, он выйдет из строя из-за отсутствия переменной среды, которая была бы где-то создана, если бы сценарий выполнялся обычным способом ...
Единственный способ, которым я мог это увидеть, - это создать сценарий оболочки, который устанавливает переменную и вызывает tern
custom-tern
#!/bin/bash # while debugging and experimenting, add the pipe to a log file NODE_ENV=dev tern --persistent --verbose | tee /tmp/tern.log
Как только я добавил это в свой ~/bin
и изменил свой редактор, чтобы использовать мой custom-tern
в качестве tern
исполняемого файла, я смог увидеть доработки во всей их красе. Если мы запросим файлы с curl
, можно будет убедиться, что несколько файлов были загружены в память при запуске ...
$ curl -X POST https://localhost:60662 -d '{"query": {"type": "files"}}' {"files": ["src/autocompleteme.js","node_modules/react/index.js","node_modules/react/cjs/react.production.min.js","node_modules/react/cjs/react.development.js","node_modules/object-assign/index.js","node_modules/fbjs/lib/emptyObject.js","node_modules/fbjs/lib/emptyFunction.js","node_modules/fbjs/lib/invariant.js","node_modules/fbjs/lib/warning.js","node_modules/prop-types/checkPropTypes.js","node_modules/prop-types/lib/ReactPropTypesSecret.js"]}
Эта статья больше о внутренней работе tern, а не о настройке вашего редактора, но если вы хотите увидеть мой vimrc
, вы можете проверить мою настройку
На что следует обратить внимание:
Поскольку tern по сути загружает и разрешает все модули в конфигурации веб-пакета, время запуска может быть немного медленным, поэтому первое завершение, которое вы пытаетесь выполнить, может не появиться сразу. Подождите несколько секунд и попробуйте еще раз.
Если tern ведет себя не так, как вы ожидаете, попробуйте отправить ему запросы на файлы, подобные приведенному выше примеру, и убедитесь, что исходный файл свойства, которое вы пытаетесь заполнить, находится в списке файлов. У проектов Javascript есть множество макетов, поэтому вам может потребоваться использовать разные плагины tern, чтобы файлы загружались правильно.
Как только все заработает, вы можете удалить перенаправление в скрипте custom-tern
. (Если вам нужно снова устранить неполадки, обязательно используйте tee
вместо >
, потому что перенаправление stdout с >
, похоже, все ломает)
Я думаю, что есть много путаницы в том, как работает tern
и почему он ломается, потому что большая часть работы абстрагируется в npm
пакетах и подключаемых модулях редактора, но место, где необходимо устранить проблему (сервер), часто скрыто в некоторых фоновый процесс. Итак, чтобы понять, что именно нужно исправить, людям нужно
- Вручную запустить сервер в оболочке
- Откройте другую оболочку или инструмент и отправьте ему пользовательские запросы JSON для проверки состояния сервера.
- Вернитесь и прочтите документацию, выясните, где у вас неправильная конфигурация, и попробуйте еще раз, пока не получите правильный ответ.
Я надеюсь, что любой, кто найдет свой путь к этому, будет лучше понимать, что делать, и, надеюсь, я сэкономил вам время! Спасибо