Flycheck mit ausführbarer Datei

21

Viele Projekte, an denen ich arbeite, installieren eslint als Entwicklungsabhängigkeit mit einem benutzerdefinierten Satz von eslint-Plugins. Momentan verwendet flycheck die global installierte Version von eslint und nicht die Version von eslint, die mit jedem Projekt installiert wird.

Ich möchte Flycheck stattdessen auf node_modules / eslint / bin / eslint.js verweisen lassen. Der vollständige Pfad sollte vom Pfad der aktuellen Pufferdatei abhängen, damit ich mit jedem Puffer, der eine möglicherweise andere ausführbare ESLINT-Datei verwendet, gleichzeitig an mehreren Projekten arbeiten kann.

Ist das möglich? Irgendwelche Vorschläge, wie ich das machen würde?

pcardune
quelle

Antworten:

32

Sie können programmgesteuert ändern flycheck-javascript-eslint-executable, z

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

Dieser Code sucht nach einem node_modulesVerzeichnis in einem übergeordneten Verzeichnis des Puffers und konfiguriert Flycheck so, dass eine ausführbare Datei aus diesem Verzeichnis verwendet wird, falls vorhanden.

Mondhorn
quelle
Ich wünschte, mein Emacs-Fu wäre so gut. Danke für die Antwort!
Pcardune
1
Wenn Sie den Global-Flycheck-Modus eingestellt haben, empfehle ich, dass (and eslint (file-executable-p eslint)) ich beim Versuch, meine .emacs-Datei zu bearbeiten
Jason Dufair,
Folgendes
Shivek Khurana
Sicherheitshinweis: Nur Dateien in vertrauenswürdigen Ordnern / Projekten öffnen. Sie werden alle Malicions Eslint Binary automatisch ausführen
bis
2
Ich würde den Pfad verwenden "node_modules/.bin/eslint", nur für den Fall, dass eslint jemals ihre Verzeichnisstruktur ändert.
Cody Reichert
3

Ich habe nicht genug Ansehen, um die akzeptierte Lösung zu kommentieren. Aber ich habe eine Variation davon gemacht, die gut mit verschachtelten Paketen funktioniert (zum Beispiel mit lerna ). Dies ist genau derselbe Code, jedoch wird der übergeordnete node_modulesOrdner rekursiv durchsucht, bis eine eslintBinärdatei gefunden und verwendet wird. Auf diese Weise können Sie für ein Lerna-Projekt nur eine Eslint-Konfiguration festlegen, die von allen Unterpaketen gemeinsam genutzt wird.

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

Ich arbeite unter Windows und das hat bei mir nicht funktioniert. Ich denke, die Datei-ausführbare-p oder die Flycheck-Interna haben die richtige Datei nicht gefunden. Als ob es funktioniert, zeigt es auf die .cmdDatei und nicht auf die .jsDatei.

Ich fand einen Kommentar in flycheck-eslint verwendet keine Version von eslint, die in JavaScript-Projekten und deren Blog- Posts installiert ist , um stattdessen Verzeichnisvariablen zu verwenden.

Erstellen Sie im Stammverzeichnis des Projekts eine Datei .dir-locals.el

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

Wenn ich jetzt die Javascript-Datei besuche flycheck-verify-setup, findet die Datei richtig<dir>/node_modules/.bin/eslint.cmd

Bae
quelle
0

Meine bisherige Lösung war ein schmerzhafter Einstieg in verschiedene Projekte.

Ich habe die akzeptierte Antwort geändert, um Dummheiten bei Hardcode-Fenstern Rechnung zu tragen.

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

Hier ist eine Lösung, die die Antworten von Bae und Lunaryorn mithilfe einer dir-locals.elDatei im Stammverzeichnis des Projekts (oder genauer gesagt im Verzeichnis, das den node_modules/Ordner enthält, in dem sich die eslintBinärdatei befindet) kombiniert . Erstellen Sie die dir-locals.elDatei mit dem folgenden Inhalt.

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

Hier gehe ich davon aus, dass Sie den js2-modeEmacs Major-Modus verwenden, um Javascript-Dateien zu bearbeiten. Wenn dies nicht der Fall ist, ändern Sie diese Zeile entsprechend. In der zweiten Zeile der Datei wird die javascript-eslintSyntaxprüfung als einzige in diesem Projekt verwendet. Die dritte Zeile setzt die Variable flycheck-javascript-eslint-executableauf <root-dir>/node_modules/.bin/eslint. Auf diese Weise modifizieren wir keine Emacs exec-path.

Ricardo
quelle
0

Ich habe ein paar verschiedene Variationen davon ausprobiert und nie genau das gefunden, was ich wollte. In Emacs Lisp habe ich endlich genug Level erreicht, um es nach meinen Wünschen zu ändern. Meine Version sucht nach einer lokalen Eslint und wenn eine nicht gefunden wird, greift sie auf eine global installierte zurück:

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