Skip to content

❗️지나치게 공격적인 최적화 수정 - FusionCharts 사용시 웹팩번들에러 (feat.Terser) #21

@seungyeub

Description

@seungyeub

FusionCharts를 포함한 프로젝트를 Webpack으로 번들링하는 경우에 생기는 에러

Terser를 사용하여 지나치게 공격적인 최적화 수정

합법적 인 라이브러리를 가져 오면 최근 "구문 오류"예외가 발생하여 프로덕션 번들이 손상되었습니다. 이 짧은 기사는 우리를 해결책으로 이끈 오류와 조사 과정을 설명합니다. 어느 시점에서 누군가 가이 게시물을 참조하여 소중한 시간을 절약 할 수 있기를 바랍니다.

TL; DR은 에 번들 때 웹팩 V4와 생산 모드 , TerserPlugin의 축소하고 제 3 자 번들을 종종 손상 이미 축소 된 수 번들. keep_fnames : /./ 옵션을 추가하면 번들 크기를 늘리지 않고도이 문제를 해결할 수 있습니다.

신비한 구문 오류 (Mysterious Syntax Error)

현재 프로젝트 중 하나에서 이상한 동작을 발견했습니다. 일부 테스트에서 번들이 손상되었음을 나타 냈습니다 ( "구문 오류"). 처음에는 구성 요소 ( Storybook 사용 )에 대한 스토리가 제대로 작동 했기 때문에 테스트 설정에 문제가 있다고 생각 했습니다. 그런 다음 "생산"번들도 동일한 오류를 일으킨다는 것을 깨달았습니다 (다행히 CI 빌드에서 테스트에 실패했기 때문에 프로덕션 환경에 손상된 번들이 없었습니다).

오류 자체 :

구문 에러 : 예기치 않은 토큰 (

다음 코드 조각으로 인해 발생합니다.

function (e, t) { if (“function”! = typeof t && null! == t) throw new TypeError ( "슈퍼 표현식은"+ typeof t가 아니라 null이거나 함수 여야합니다);
……

용의자 찾기 (Finding a suspect)

우리가 가장 먼저 한 일은 문제를 해결하는 것이 었습니다. 머지 않아 우리는 특정 의존성 ( FusionCharts , 멋진 차트 라이브러리) 을 가져 오는 것이 문제를 일으킨다 는 결론을 내 렸습니다 . FusionCharts를 가져 오지 않은 경우 번들이 손상되지 않았습니다.

FusionCharts가 널리 사용되며이 오류를 직접 발생시킬 수는 없습니다. FusionCharts 번들에서 흥미로운 점은 축소 된 것입니다. 예를 들어 함수 이름이 한 문자 길이라는 것을 알았습니다.

단일 문자 이름 함수의 예 :

function c (e, t) { if (“function”! = typeof t && null! == t) throw new TypeError ( "슈퍼 표현식은"+ typeof t가 아니라 null이거나 함수 여야합니다);

FusionCharts 코드가 Storybook에서 완벽하게 작동했기 때문에 FusionCharts에 문제가없는 것으로 결론을 내 렸습니다. 결국, 많은 FusionCharts 커뮤니티가 있습니다. FusionCharts의 기본 사용이 실제로 문제의 원인이라면, 이미 누군가가 그것에 대해 글을 썼을 것입니다.

이 시점에서 실패한 대부분의 테스트가 스토리 북 정적 빌드 에서 실행되고 있음을 알았습니다 . 처음에 우리는 정기적 인 스토리 북 실행과 스토리 북 정적 빌드 간의 차이점이 무엇인지 이해하지 못했습니다.

Storybook의 코드 를 파고 들어 정적 스토리 북 페이지가 “production-mode”로 구축 된 것을 발견했습니다 . 스토리 북을 비 프로덕션 모드에서 강제 실행 ( NODE_ENV = 'development'사용 )하면 번들이 더 이상 손상되지 않습니다.

웹팩 구성 검사 (Inspecting Webpack configurations)

프로덕션 모드에서 문제를 일으키는 구성을 찾아야했습니다. 우리의 Webpack 구성에는 일부 사용자 정의 로더 및 플러그인이 포함되어 있습니다. 그 중 하나는 프로덕션 빌드에서 문제를 일으켰을 것입니다.

우리는 로더, 플러그인 등 웹팩 구성을 테스트하기 시작했습니다. 우리는 아무것도 아끼지 않았습니다.

그러나 아쉽게도 웹 팩 구성의 사용자 정의 속성 이이 손상과 관련이없는 것처럼 보입니다. webpack.conf.js의 어떤 속성을 변경하더라도 문제는 항상 지속되었습니다. 이 문제의 원인은 무엇입니까?

좌절, 우리는 Webpack 공식 문서를 파고 시작했다 . 우리는 흥미로운 것을 발견했습니다.

webpack v4 +는 기본적으로 프로덕션 모드 에서 코드를 축소 합니다 .

TerserPlugin (프로덕션 모드의 기본 축소 기)이 우리에게 많은 문제를 일으킬 수 있습니까?

터서, 너야? (Terser, is that you?)

TerserPlugin 공식 문서 를 읽음 으로써 keep_fnamestrue로 설정하려고 시도했습니다 . 재미로.

그리고… 만세! 문제가 사라졌습니다. TerserPlugin이 너무 적극적으로 축소되어 1 자 길이 이름의 함수를 0 자 길이 이름으로 줄인 것 같습니다.

번들 크기 유지 (Maintaining the bundle size)

충분하지 않아서 번들을 가능한 한 많이 축소하기를 원했습니다. " keep_fnames : true "를 사용하면 함수 이름이 축소되지 않으므로 번들 크기가 증가합니다.

TerserPlugin은 정규 표현식을 keep_fnames 의 매개 변수로 허용 합니다. 정규식“keep_fnames : /./”을 사용했습니다. 즉, 함수의 이름이 1자인 경우 이름을 변경하지 마십시오 (어쨌든 어떻게 할 계획입니까?).

이 방법으로 번들 크기를 최소로 유지하면서 문제가 해결되었습니다.

핵심, 관심사 (Takeaways)

우리가 Terser에 대해 배운 것 외에도이 경험에서 벗어난 것은 프로덕션 번들 코드에서 테스트를 실행하는 것이 중요하다는 것입니다. 일반적으로 테스트되지 않은 상태입니다.

참고문헌
https://medium.com/@omril321/fixing-overly-aggressive-optimization-with-terser-f07309761b50

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions