You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Emacs初始化时web-mode变量未设置,React项目.js文件缩进异常

React项目Emacs web-mode配置问题:.js文件无法正确缩进

问题详情

  • .js文件在web-mode下无法正确缩进,尝试将.js强制识别为.jsx类型但未生效
  • 打开.js文件时,web-mode和prettier已正确配置,但执行web-mode-content-type返回值为"javascript"而非"jsx"
  • 排查发现.emacs执行期间web-mode-content-type变量未定义,导致hook中的if判断不生效

当前~/.emacs配置

(message "Loading init.el")

;; Adding MELPA                 
(require 'package)
(add-to-list 'package-archives
         '("melpa" . "https://melpa.org/packages/") t)

;; Dark theme mode 
(load-theme 'modus-vivendi t)

;; Use HELM instead of default
(global-set-key (kbd "M-x") 'helm-M-x)
(global-set-key (kbd "C-x C-f") 'helm-find-files)
(global-set-key (kbd "C-x b") 'helm-buffers-list)
;; Expressing that I don't want to see the startup by emacs

(require 'web-mode)
(add-to-list 'auto-mode-alist '("\\.js\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.jsx\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.ts\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.tsx\\'" . web-mode))

(add-hook 'web-mode-hook
      (lambda ()
        (if (equal web-mode-content-type "javascript")
        (web-mode-set-content-type "jsx")
          (message "now set to: %s" web-mode-content-type)
          )
        )
      )

(add-hook 'web-mode-hook 'prettier-js-mode)

(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(inhibit-startup-screen t)
 '(package-selected-packages '(prettier-js web-mode helm modus-themes)))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 )

解决方案

问题核心是web-mode-hook触发时,web-mode-content-type尚未完成初始化,导致判断逻辑失效。以下两种方法可修复:

方法1:直接为.js文件指定content-type

替换原有的.js文件关联配置,打开文件时直接设置content-type为jsx:

(add-to-list 'auto-mode-alist '("\\.js\\'" . (lambda ()
                                                (web-mode)
                                                (web-mode-set-content-type "jsx"))))

这种方式跳过hook判断,直接在文件打开阶段完成类型设置,避免变量未定义问题。

方法2:延迟hook中的判断逻辑

使用空闲定时器延迟执行判断,确保web-mode-content-type已初始化:

(add-hook 'web-mode-hook
          (lambda ()
            (run-with-idle-timer
             0.1 nil
             (lambda ()
               (when (equal web-mode-content-type "javascript")
                 (web-mode-set-content-type "jsx")
                 (message "now set to: %s" web-mode-content-type))))))

额外优化:适配prettier格式化

若prettier未正确处理jsx代码,可在hook中指定parser:

(add-hook 'web-mode-hook
          (lambda ()
            (when (equal web-mode-content-type "javascript")
              (web-mode-set-content-type "jsx"))
            (prettier-js-mode)
            (setq prettier-js-args '("--parser" "babel"))))

内容的提问来源于stack exchange,提问作者Gaston

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 16:40:55