티스토리 블로그 구독 버튼 추가 후 SyntaxHighlighter 가 작동하지 않는 증상 임시 해결
티스토리에 추가된 블로그 구독 기능
2019년 3월 20일, 티스토리에 블로그 구독이라는 기능이 추가되었다.
여타 사이트의 구독 or 팔로잉 기능과 비슷하게, 마음에 드는 블로그를 구독하여 글을 쉽고 빠르게 모아볼 수 있는 기능이다.
자세한 설명은 다음의 링크 참조. https://notice.tistory.com/2477?category=110385
블로그 구독 버튼은 티스토리 관리자 페이지의 [메뉴바/구독 설정] 에서 활성화 할 수 있다.
이 블로그는 해당 기능이 나오자 마자 바로 블로그 구독 버튼을 활성화 해주었다.
블로그 구독 버튼 활성화 후 SyntaxHighlighter 가 작동하지 않는 증상 발생
그런데 블로그 구독 버튼을 활성화 한 후 3일 만에 알게된 것인데,
SyntaxHighlighter 가 적용되지 않고 원본 텍스트로만 출력되는 증상이 발생하고 있었다.
내 환경에서만 이런 문제가 발생하는 것인지는 따로 테스트를 해보지 않아서 잘 모르겠다.
내 경우 CDN 을 통해 SyntaxHighlighter 3.0.83 을 불러와 <pre> 태그를 이용하는 방법으로 SyntaxHighlighter 를 사용하고 있고
블로그 스킨으로는 개인적으로 수정한 Custom 스킨을 사용하고 있다.
문제 원인 파악
Chrome의 개발자도구를 열어 문제를 확인했다.
SyntaxHighlighter 의 shCore.js 에서 재귀호출이 너무 많이 일어나 오류가 발생하고 있었다.
CDN 에서 불러오는 shCore.js 파일은 압축(minify)되어있어 분석이 쉽지 않으므로
minify되지 않은 XRegExp.js 파일과 shCore.js 을 로드했다. (CDN 에서 불러오는 shCore.js 는 두 파일이 합쳐진 형태이다.)
이후 다시 문제를 확인하자 아래의 그림과 같이
구독 버튼을 추가하기위해 로드된 menubar.min.js 에서 String.replace 함수를 호출하는 과정에서 에러가 시작되었다고 한다.
그리고 그 에러는 XRegExp.js 로 연결되어 있었다.
XRegExp 라이브러리는 정규표현식을 편하게 사용할 수 있도록 돕고,
브라우저와 상관없이 동일한 정규표현식 동작을 수행할 수 있도록 호환성을 제공하는 라이브러리 이다.
설명에 따르면 아래와 같이 정규표현식을 사용하는데 쓰이는 몇가지 함수들이 브라우저 간 차이를 보이는 부분이 있어
호환성을 유지할 수 있도록 이러한 함수들을 덮어씌우는 동작이 있다고 한다.
그래서 아래의 그림과 같이 몇가지 prototype 함수들을 real 이라는 Object 에 복사해두고
아래의 그림과 같이, 브라우저 간 호환성을 유지할 수 있도록 수정된 함수를 덮어씌운다.
함수 내에서는 real 에 복사된 함수를 다시 호출하고, 조건식에 따라 브라우저 간 호환성 유지를 위한 여러 동작을 수행한다(고한다).
그리고 menubar.min.js 에서는 String.prototype.replace 함수를 호출하는데,
이 때 SyntaxHighlighter 를 사용하는 경우라면 XRegExp 에서 덮어씌워진 수정된 함수를 불러오게 된다.
여기서 에러(재귀호출)가 발생한다.
여기까지만 보고 코드를 더 분석해보지는 않았지만 대충 원인을 추정해보자면,
모종의 이유로 real 에 복사된 함수가 한 번 더 덮어씌워지게 되는 경우
수정된 함수 내에서는 real 에 복사된 함수를 호출하고 있으므로 결국 자기 자신을 호출하는 것이 되어 재귀호출이 발생할 수 있을 것 같다.
아니면 그냥 그 외 라이브러리 충돌 문제로 재귀호출이 발생하게 되어 문제가 발생하게 된 것일 수도 있다.
자세하게 분석하지는 않아서 정확한 이유는 모르겠다.
이 외에도 비슷한 몇가지 문제가 있었다.
임시로 문제 해결하기
파일 업로드 버튼을 누른 뒤
추가 버튼을 눌러 위에서 다운받은 두 파일(regExp_new.js, shCore_new.js)을 업로드한다.
이후 HTML 버튼을 눌러 HTML 편집창으로 간 뒤
기존의 shCore.js 를 불러오는 부분을 아래와 같이 수정한다.
혹시 기존에도 shCore.js 와 XRegExp.js 를 모두 로드하고 있었던 경우 두 라인을 모두 주석처리 해주면 된다.
주의할 점은 regExp_new.js 를 불러오는 라인이 shCore_new.js 를 불러오는 라인보다 반드시 위에 있어야 한다.
수정을 완료하였으면 적용 버튼을 눌러 저장한다.
근본적인 원인을 찾아서 수정했다면 더 좋았겠지만, 짧은 시간을 들여 해결할 수 있는 수준에서 대충 해치웠다.
사실 이 포스트를 적는 시간이 더 오래 걸렸다.