Flycheck con archivo relativo ejecutable eslint

21

En muchos proyectos en los que trabajo instalo eslint como dependencia de desarrollo, con un conjunto personalizado de complementos de eslint. En este momento, flycheck usa la versión de eslint instalada globalmente en lugar de la versión de eslint instalada con cada proyecto.

Me gustaría hacer que flycheck apunte a node_modules / eslint / bin / eslint.js en su lugar. La ruta completa debe depender de la ruta del archivo del búfer actual para que pueda trabajar en varios proyectos al mismo tiempo con cada búfer utilizando un ejecutable eslint potencialmente diferente.

es posible? ¿Alguna sugerencia sobre cómo haría para hacer esto?

pcardune
fuente

Respuestas:

32

Puede cambiar mediante programación flycheck-javascript-eslint-executable, p. Ej.

(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)

Este código busca un node_modulesdirectorio en cualquier padre del directorio del búfer y configura Flycheck para usar un ejecutable eslint desde ese directorio si existe alguno.

Lunaryorn
fuente
Desearía que mi emacs-fu fuera tan bueno. ¡Gracias por la respuesta!
pcardune
1
Si tiene configurado el modo global flycheck, le recomiendo que (and eslint (file-executable-p eslint)) me encontrase con errores que, de lo contrario, intentaría, es decir, edite mi archivo .emacs
Jason Dufair
Esto es lo que puede hacer si necesita un enlace en
Shivek Khurana
nota de seguridad: solo abra archivos en carpetas / proyectos confiables; ejecutará automáticamente cualquier malicions eslint binary
maxy
2
"node_modules/.bin/eslint"Usaría la ruta , en caso de que eslint cambie su estructura de directorios.
Cody Reichert
3

No tengo suficiente reputación para comentar sobre la solución aceptada. Pero hice una variación, que funciona bien con paquetes anidados (por ejemplo, usando lerna ). Este es exactamente el mismo código, sin embargo, busca la node_modulescarpeta principal de forma recursiva hasta que encuentra un eslintbinario y lo usa. De esta manera, puede hacer que un proyecto lerna tenga una sola configuración de eslint, compartida entre todos los subpaquetes.

(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
fuente
0

Estoy en Windows y esto no estaba funcionando para mí, creo que el archivo ejecutable-p o tal vez las partes internas de flycheck no pudieron localizar el archivo correcto. Como cuando funciona, apunta al .cmdarchivo y no al .jsarchivo.

Encontré un comentario en flycheck-eslint que no usa la versión de eslint instalada en el proyecto JavaScript y su publicación de blog para usar variables de directorio .

En el directorio raíz del proyecto, cree un archivo .dir-locals.el

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

Ahora cuando visito el archivo javascript flycheck-verify-setupencuentra correctamente el archivo<dir>/node_modules/.bin/eslint.cmd

Bae
fuente
0

Mi solución anterior fue difícil trabajar en diferentes proyectos.

He modificado la respuesta aceptada a las estupideces de Windows de código duro.

(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
fuente
0

Aquí hay una solución que combina las respuestas de Bae y lunaryorn usando un dir-locals.elarchivo en el directorio raíz del proyecto (o, más específicamente, en el directorio que contiene la node_modules/carpeta donde eslintvive el binario). Cree dicho dir-locals.elarchivo con el siguiente contenido.

((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")))))

Aquí supongo que está utilizando el js2-modemodo principal de emacs para editar archivos javascript. Si ese no es el caso, cambie esa línea en consecuencia. La segunda línea del archivo hace que el javascript-eslintverificador de sintaxis sea el único que se utilizará en este proyecto. La tercera línea establece la variable flycheck-javascript-eslint-executableen <root-dir>/node_modules/.bin/eslint. De esta manera no modificamos emacs ' exec-path.

Ricardo
fuente
0

He intentado algunas variaciones diferentes de esto y nunca encontré exactamente lo que quería. Finalmente he subido lo suficiente en Emacs lisp para modificarlo a mi gusto. Lo que hace mi versión es buscar un eslint local y, si no se encuentra, recurre a uno instalado globalmente:

(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)))
Ricky Nelson
fuente