SmooshGate FAQ

스무시가 어떻게 된 걸까요?

Array.prototype.flatten라는 자바스크립트 언어 기능에 대한 제안은 웹과 호환되지 않는 것으로 확인되었습니다. Firefox Nightly에서 이 기능을 제공하면 하나 이상의 인기 웹사이트에 오류가 발생했습니다. 문제가 있는 코드가 널리 사용되는 MooTools 라이브러리의 일부라는 점을 고려하면 더 많은 웹사이트가 영향을 받을 수 있습니다. (2018년에는 MooTools가 새로운 웹사이트에 흔히 사용되지는 않았지만, MooTools가 많이 사용되어 여전히 많은 프로덕션 웹사이트에 사용되고 있습니다.)

제안서 작성자가 호환성 문제를 피하기 위해 flatten의 이름을 smoosh로 바꾸도록 제안했습니다. 이 농담은 모두에게 명확하지 않았고, 일부 사람들은 새 이름이 이미 결정되었다고 잘못 믿기 시작했으며 상황은 빠르게 상승했습니다.

Array.prototype.flatten의 기능은 무엇인가요?

원래 Array.prototype.flatten로 제안된 Array.prototype.flat는 지정된 depth(기본값 1)까지 배열을 재귀적으로 평면화합니다.

// Flatten one level:
const array = [1, [2, [3]]];
array.flat();
// → [1, 2, [3]]

// Flatten recursively until the array contains no more nested arrays:
array.flat(Infinity);
// → [1, 2, 3]

동일한 제안서에는 결과를 새 배열로 평면화한다는 점을 제외하면 Array.prototype.map와 같은 Array.prototype.flatMap가 포함됩니다.

[2, 3, 4].flatMap((x) => [x, x * 2]);
// → [2, 4, 3, 6, 4, 8]

이 문제를 일으키는 MooTools는 무엇인가요?

MooTools에서는 자체 비표준 버전의 Array.prototype.flatten를 정의합니다.

Array.prototype.flatten = /* non-standard implementation */;

MooTools의 flatten 구현은 제안된 표준과 다릅니다. 하지만 이는 문제가 되지 않습니다. 브라우저가 기본적으로 Array.prototype.flatten를 제공하면 MooTools가 네이티브 구현을 재정의합니다. 이렇게 하면 MooTools 동작에 의존하는 코드가 네이티브 flatten의 사용 가능 여부와 관계없이 의도한 대로 작동합니다. 지금까지 잘 진행되었습니다.

안타깝지만 이렇게 되면 다른 상황이 발생합니다. MooTools는 모든 맞춤 배열 메서드를 Elements.prototype (여기서 Elements는 MooTools 전용 API)에 복사합니다.

for (var key in Array.prototype) {
  Elements.prototype[key] = Array.prototype[key];
}

for-inArray.prototype.sort와 같은 네이티브 메서드는 포함되지 않는 'enumerable' 속성에 대해 반복되지만 Array.prototype.foo = whatever와 같이 정기적으로 할당되는 속성은 포함합니다. 단, 키커를 살펴보겠습니다. 열거 불가능한 속성(예: Array.prototype.sort = whatever)을 덮어쓰면 이 속성은 열거 불가능한 상태로 유지됩니다.

현재 Array.prototype.flatten = mooToolsFlattenImplementation는 enumerable flatten 속성을 생성하므로 나중에 Elements에 복사됩니다. 하지만 브라우저에서 flatten의 네이티브 버전을 제공하면 열거 불가능 상태가 되며 Elements에 복사되지 않습니다. MooTools의 Elements.prototype.flatten를 사용하는 모든 코드가 이제 손상되었습니다.

네이티브 Array.prototype.flatten를 열거 가능으로 변경하면 문제가 해결될 것으로 보이지만, 이 경우 더 많은 호환성 문제가 발생할 수 있습니다. for-in를 사용하여 배열을 반복하는 모든 웹사이트에서는 갑자기 flatten 속성에 관한 추가 루프 반복이 발생합니다. 이는 좋지 않은 방법이지만 그럴 수 있습니다.

여기서 더 큰 근본적인 문제는 내장 객체를 수정하는 것입니다. 네이티브 프로토타입 확장은 오늘날 다른 라이브러리 및 서드 파티 코드와 원활하게 구성되지 않기 때문에 일반적으로 좋지 않은 관행으로 받아들여집니다. 소유하지 않은 객체는 수정하지 마세요.

기존 이름을 그대로 두고 웹을 개편하지 않는 이유는 무엇인가요?

CSS가 널리 퍼지기 전인 1996년, 'HTML5'가 대세가 되기 훨씬 전인 1996년에 스페이스 잼 웹사이트가 문을 열었습니다. 지금도 웹사이트는 22년 전과 동일한 방식으로 작동합니다.

어떻게 이런 일이 발생했는가? 브라우저 공급업체가 새 기능을 출시할 때마다 웹사이트를 업데이트하면서 이 기간 동안 웹사이트를 유지한 사람이 있을까요?

'웹을 망가뜨리지 마세요'는 HTML, CSS, 자바스크립트 및 웹에서 널리 사용되는 기타 모든 표준에 대한 가장 중요한 디자인 원칙입니다. 새로운 브라우저 기능이 출시되어 기존 웹사이트가 작동하지 않게 되면 모두에게 좋지 않습니다.

  • 문제가 발생한 웹사이트의 방문자에게 갑자기 손상된 사용자 환경을 경험하는 경우
  • 웹사이트 소유자가 완벽하게 작동하는 웹사이트를 아무것도 바꾸지 않고 작동하지 않는 웹사이트로 전환했습니다.
  • 새로운 기능을 제공하는 브라우저 공급업체는 사용자가 '브라우저 X에서 작동함'을 감지한 후 브라우저를 전환하여 시장점유율을 놓치고 있습니다.
  • 호환성 문제가 알려진 뒤에는 다른 브라우저 공급업체에서 문제 제공을 거부합니다. 기능 사양이 현실 ('아무것도 아니고 허구')과 일치하지 않아 표준화 프로세스에 좋지 않습니다.

물론 과거를 돌아보면 MooTools는 잘못된 일을 했습니다. 하지만 웹을 망가뜨린다고 해서 사용자가 처벌을 받는 것은 아닙니다. 이러한 사용자는 Moo 도구가 무엇인지 모릅니다. 또는 다른 솔루션을 찾아 웹을 계속 사용할 수 있습니다. 쉽게 선택할 수 있습니다.

그렇다면 웹 플랫폼에서 악성 API를 절대 제거할 수 없나요?

경우에 따라 다릅니다. 드물지만 잘못된 기능이 웹에서 삭제되는 경우도 있습니다. 특성을 삭제할 가능성이 있는지 여부 자체만 판단하기는 매우 까다롭습니다. 동작이 변경된 웹 페이지 수를 정량화하기 위해 광범위한 원격 측정이 필요하기 때문입니다. 하지만 기능이 충분히 안전하지 않거나, 사용자에게 유해하거나, 매우 드물게 사용되는 경우 이 방법을 사용할 수 있습니다.

<applet>, <keygen>, showModalDialog()는 모두 웹 플랫폼에서 삭제된 잘못된 API의 예입니다.

MooTools만 수정하면 안 되나요?

기본 제공 객체를 더 이상 확장하지 않도록 MooTools를 패치하는 것이 좋습니다. 그러나 당면한 문제는 해결되지 않습니다. MooTools에서 패치 버전을 출시하더라도 이를 사용하는 모든 기존 웹사이트는 호환성 문제를 해결하기 위해 업데이트해야 합니다.

MooTools만 업데이트할 수는 없나요?

완벽한 환경이라면 MooTools에서 패치를 출시하면 MooTools를 사용하는 모든 웹사이트가 다음날 마술처럼 업데이트됩니다. 문제가 해결되었습니다.

하지만 이는 현실적이지 않습니다. 누군가가 어떤 식으로든 영향을 받은 웹사이트 전체를 식별하고 각각의 연락처 정보를 찾고 모든 웹사이트 소유자에게 성공적으로 연락하여 업데이트를 수행하도록 설득하더라도 (전체 코드베이스를 리팩터링해야 할 수 있음) 전체 프로세스에는 기껏해야 몇 년이 걸릴 것입니다.

이러한 웹사이트 중 다수는 오래되어 유지되지 않는 경우가 많습니다. 유지관리 담당자가 계속 대기하고 있더라도 여러분처럼 숙련된 웹 개발자가 아닐 수도 있습니다. 웹 호환성 문제로 인해 모든 사용자가 8년 된 웹사이트를 변경하기를 기대할 수는 없습니다.

TC39 절차는 어떻게 진행되나요?

TC39는 ECMAScript 표준을 통해 JavaScript 언어를 발전시키는 위원회입니다.

#SmooshGate는 'TC39가 flatten의 이름을 smoosh'로 바꾸려고 한다고 믿게 만들었지만 대외비로 잘 전달되지 않은 농담이었습니다. 제안서 이름 변경과 같은 주요 결정은 가볍게 내린 결정이 아니며, 한 사람이 내린 결정이 아니며, GitHub 댓글 하나를 기준으로 하룻밤 사이에 내린 결정도 아닙니다.

TC39는 기능 제안을 위한 명확한 스테이징 프로세스를 운영합니다. ECMAScript 제안과 이에 대한 주요 변경사항 (메서드 이름 변경 포함)은 TC39 회의 중에 논의되며 공식화되기 전에 전체 위원회의 승인을 받아야 합니다. Array.prototype.flatten의 경우 제안서는 3단계까지 이미 여러 단계의 계약 단계를 거쳤으며 이는 웹브라우저에서 기능을 구현할 준비가 되었음을 나타냅니다. 구현 중에 추가적인 사양 문제가 발생하는 경우가 많습니다. 이 경우 가장 중요한 의견은 이 기능을 제공하려는 후에 나왔습니다. 이 기능은 현재 상태로는 웹을 망가뜨립니다. 이와 같은 예측하기 어려운 문제는 브라우저가 기능을 제공한다고 해서 TC39 프로세스가 끝나지 않는 이유 중 하나입니다.

TC39는 합의에 따라 운영되므로 위원회가 새로운 변경사항에 합의해야 합니다. smoosh가 진지한 제안이었더라도 위원회 위원은 이에 반대할 가능성이 있으며 compact 또는 chain와 같은 보다 일반적인 이름을 선호할 것으로 보입니다.

flatten에서 smoosh로의 이름 변경은 농담이 아니더라도 TC39 회의에서 논의된 적이 없습니다. 따라서 이 주제에 대한 공식적인 TC39 입장은 현재 알 수 없습니다. 다음 회의에서 합의가 도출될 때까지는 한 사람이 TC39 전체를 대표하여 발언할 수 없습니다.

일반적으로 TC39 회의는 매우 다양한 배경을 가진 사람들이 참여합니다. 이 가운데 일부는 프로그래밍 언어 설계 경력이 있는 사람도 있고, 브라우저 또는 JavaScript 엔진에서 일하는 사람도 있고, JavaScript 개발자 커뮤니티를 대표하는 참석자 수가 점점 더 많아지고 있습니다.

SmooshGate는 어떻게 해결되었나요?

2018년 5월 TC39 회의에서 #SmooshGate는 flatten의 이름을 flat로 바꾸어 공식적으로 해결되었습니다.

Array.prototype.flatArray.prototype.flatMap는 V8 v6.9 및 Chrome 69에서 출시되었습니다.