Флайчек с файлом относительно исполняемого файла eslint

21

Многие проекты, над которыми я работаю, устанавливают eslint как dev-зависимость с пользовательским набором плагинов eslint. Прямо сейчас flycheck использует глобально установленную версию eslint, а не версию eslint, установленную с каждым проектом.

Я бы хотел, чтобы flycheck указывал на node_modules / eslint / bin / eslint.js. Полный путь должен зависеть от пути к файлу текущего буфера, поэтому я могу работать над несколькими проектами одновременно с каждым буфером, используя потенциально разные исполняемые файлы eslint.

Это возможно? Любые предложения о том, как я буду делать это?

pcardune
источник

Ответы:

32

Вы можете программно изменить flycheck-javascript-eslint-executable, например,

(defun my/use-eslint-from-node-modules ()
  (let* ((root (locate-dominating-file
                (or (buffer-file-name) default-directory)
                "node_modules"))
         (eslint
          (and root
               (expand-file-name "node_modules/.bin/eslint"
                                 root))))
    (when (and eslint (file-executable-p eslint))
      (setq-local flycheck-javascript-eslint-executable eslint))))

(add-hook 'flycheck-mode-hook #'my/use-eslint-from-node-modules)

Этот код ищет node_modulesкаталог в любом родительском каталоге буфера и настраивает Flycheck для использования исполняемого файла eslint из этого каталога, если таковой существует.

lunaryorn
источник
Я бы хотел, чтобы мои emacs-fu были такими хорошими. Спасибо за ответ!
pcardune
1
Если у вас установлен режим global-flycheck-mode, то я рекомендую, чтобы (and eslint (file-executable-p eslint)) я столкнулся с ошибками, в противном случае я пытался отредактировать мой файл .emacs
Jason Dufair
Вот что вы можете сделать, если вам нужен встроенный хук (и избегать добавления пользовательских функций): emacs-fu.blogspot.in/2008/12/hooks.html
Шивек Хурана
примечание по безопасности: открывайте файлы только в надежных папках / проектах; Вы будете автоматически выполнять любые двоичные файлы, если не используете malicions
maxy
2
Я бы использовал путь "node_modules/.bin/eslint", на всякий случай, если eslint когда-либо изменит свою структуру каталогов.
Коди Райхерт
3

У меня недостаточно репутации, чтобы комментировать принятое решение. Но я сделал вариант, который хорошо работает с вложенными пакетами (например, с использованием lerna ). Это точно такой же код, однако он node_modulesрекурсивно ищет родительскую папку, пока не находит eslintдвоичный файл и не использует его. Таким образом, у проекта lerna может быть только одна конфигурация eslint, совместно используемая всеми подпакетами.

(defun my/use-eslint-from-node-modules ()
  (let ((root (locate-dominating-file
               (or (buffer-file-name) default-directory)
               (lambda (dir)
                 (let ((eslint (expand-file-name "node_modules/eslint/bin/eslint.js" dir)))
                  (and eslint (file-executable-p eslint)))))))
    (when root
      (let ((eslint (expand-file-name "node_modules/eslint/bin/eslint.js" root)))
        (setq-local flycheck-javascript-eslint-executable eslint)))))
(add-hook 'flycheck-mode-hook #'my/use-eslint-from-node-modules)
Soreine
источник
0

Я нахожусь на Windows, и это не работало для меня, я думаю, что file-исполняемый-p или, возможно, внутренности flycheck не смогли найти правильный файл. Когда он работает, он указывает на .cmdфайл, а не на .jsфайл.

Я нашел комментарий в flycheck-eslint не использует версию eslint , установленной в проекте JavaScript и их блоге на использование переменных каталогов вместо.

В корневой директории проекта создайте файл .dir-locals.el

((nil . ((eval . (progn
                   (add-to-list 'exec-path (concat (locate-dominating-file default-directory ".dir-locals.el") "node_modules/.bin/")))))))

Теперь, когда я захожу в файл javascript, flycheck-verify-setupправильно находит файл<dir>/node_modules/.bin/eslint.cmd

Bae
источник
0

Моим предыдущим решением было мучительно работать с разными проектами.

Я изменил принятый ответ на глупости окон с жестким кодом.

(defun my/use-eslint-from-node-modules ()
  (let* ((root (locate-dominating-file
                (or (buffer-file-name) default-directory)
                "node_modules"))
         (eslint (and root
                      (expand-file-name "node_modules/.bin/eslint.cmd"
                                        root))))
    (when (and eslint (file-exists-p eslint))
      (setq-local flycheck-javascript-eslint-executable eslint))))
Bae
источник
0

Вот решение, которое объединяет ответы Bae и lunaryorn, используя dir-locals.elфайл в корневом каталоге проекта (или, более конкретно, в каталоге, в котором находится node_modules/папка, в которой находится eslintдвоичный файл). Создайте указанный dir-locals.elфайл со следующим содержанием.

((js2-mode
   (flycheck-checker . javascript-eslint)
   (eval . (setq-local flycheck-javascript-eslint-executable
             (concat (locate-dominating-file default-directory
                       ".dir-locals.el") "node_modules/.bin/eslint")))))

Здесь я предполагаю, что вы используете js2-modeосновной режим emacs для редактирования файлов javascript. Если это не так, измените эту строку соответственно. Вторая строка файла делает javascript-eslintпроверку синтаксиса единственной, которая будет использоваться в этом проекте. Третья строка устанавливает переменную flycheck-javascript-eslint-executableв <root-dir>/node_modules/.bin/eslint. Таким образом, мы не модифицируем emacs exec-path.

Рикардо
источник
0

Я попробовал несколько разных вариантов этого и так и не нашел именно то, что хотел. Я наконец-то выровнялся в Emacs lisp, чтобы изменить его по своему вкусу. Моя версия ищет локальный eslint, и если он не найден, он возвращается к глобально установленному:

(defun configure-web-mode-flycheck-checkers ()
    ;; See if there is a node_modules directory
    (let* ((root (locate-dominating-file
                  (or (buffer-file-name) default-directory)
                  "node_modules"))
           (eslint (or (and root
                            ;; Try the locally installed eslint
                            (expand-file-name "node_modules/eslint/bin/eslint.js" root))

                       ;; Try the global installed eslint
                       (concat (string-trim (shell-command-to-string "npm config get prefix")) "/bin/eslint"))))

      (when (and eslint (file-executable-p eslint))
        (setq-local flycheck-javascript-eslint-executable eslint)))

    (if eslint
        (flycheck-select-checker 'javascript-eslint)))
Рики Нельсон
источник