Problem
In a (lsp & web-mode) buffer; "function", "if", "async" are all the same color, I tried to change "if" face with the following:
(defface xxx-font-lock-face
'((t (:foreground "yellow" :weight bold))))
(font-lock-add-keywords 'web-mode
'(("\\<\\(if\\)" . xxx-font-lock-face)))
But this doesn't work. When I M-x describe-face it describes "web-mode-keyword-face".
I tried diving in the web-mode.el file, defining a new face "web-mode-xxx-face" :
(defface web-mode-xxx-face
'((t (:foreground "red" :weight bold)))
:group 'web-mode-faces)
And then I tried to apply this to the "function" keyword by replacing web-mode-keywords-face at line 2016 in the file where it seemed to bind "function" to "web-mode-keyword-face". But it didn't had any effect and function is still described as "web-mode-keyword-face" in a js file.
Solution
EDIT: As stated by @roomworoof the solution was the following (you need to eval some parts of the code after 'web-mode has loaded like this:)
(defvar xxx-mode-js-keywords
(regexp-opt '("if")))
(defvar xxx-mode-js-font-lock-keywords
(cons (concat "\\([ \t}{(]\\|^\\)\\(" xxx-mode-js-keywords "\\)\\_>") '(2 'xxx-mode-keyword-face)))
(with-eval-after-load 'web-mode
(add-to-list 'web-mode-javascript-font-lock-keywords xxx-mode-js-font-lock-keywords)
)