나는 분명 inset을 사용한 적이 없는데
CSS 출력물에 inset이 들어있던 건에 대해서
이번 글은 이전에 작성했던 tsup 라이브러리에서 es5 타겟으로 사용 시 겪었던 문제와 연관되어 있어요. 이전 글을 읽으신 뒤에 이번 글을 읽어주시면 좀 더 이해하기 쉬울 거예요. (아마..)
문제 발생
화창하고 바람이 부는 어느 오후, 슬랙 채널에 한 개의 메시지가 등장했어요.
사용 중인 iOS 14 버전에서 라이브러리의 컴포넌트 스타일이 깨진다는 제보가 있었는데, 동료 개발자가 postion: absolute;
와 함께 지정된 inset: 0;
이 구형 브라우저에서 지원이 되지 않는다고 전해주셨어요.
처음에 제보를 듣고 저는 조금 의아해졌는데요. “이전에 라이브러리를 작성할 때 inset: 0;
에 대한 스타일링 코드를 넣은 적이 없었던 거 같은데?"라고 기억하고 있었으며, 실제로 확인해 봤을 때도 소스 코드에서는 inset
관련 스타일을 찾을 수 없었어요.
원인
우선 빌드 시 inset: 0;
으로 변경되기 전 스타일의 소스 코드는 다음과 같았어요.
import { style } from '@vanilla-extract/css';
const wrapper = style({
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
});
기존에 inset
속성이 top
right
, bottom
, left
의 약칭으로 쓰이는 건 어렴풋이 알고 있었지만, 갑자기 왜 바뀌었는지 의문이 들어서 우선 vanilla-extract의 저장소에서 inset
관련 키워드와 라이브러리 디펜던시에 걸린 패키지를 찾아봤지만 찾을 수 없었어요.
이다음으로 확인해 본 것이 tsup에서 사용 중인 esbuild 인데요, 결론적으로는 여기에 원인이 있었어요.
esbuild 공식 문서에서는 다음과 같이 설명하고 있는데요.
Note that by default, esbuild’s output will take advantage of modern CSS features. For example,
color: rgba(255, 0, 0, 0.4)
will becomecolor: #f006
when minifying is enabled which makes use of syntax from CSS Color Module Level 4. If this is undesired, you must specify esbuild's target setting to say in which browsers you need the output to work correctly. Then esbuild will avoid using CSS features that are too modern for those browsers.
이전에 작성했던 글처럼 tsup config에서 target
을 es5
로 설정하면 우선 esbuild에서 es2020
으로 빌드 하다보니 위에 문서에서 설명 중인 것처럼 CSS 최신 스펙인 inset
으로 교체가 되었던 것이었죠.
해결 방법
이후 추가로 확인해 본 결과, 문제를 해결할 수 있는 방법은 크게 두 가지가 있었어요. 먼저, esbuild의 target
을 구형 브라우저에 맞게 설정하기 위해 tsup config에서 esbuildOptions
를 통해 지정해 주거나, esbuild supported
옵션에서 inset-property
를 비활성화(false
) 처리하는 방법이에요.
처음에는 target
을 통해 변경할 때 빌드된 js 파일에 이슈가 발생하면 어떻게 처리해야 할지 걱정하면서, 일단은 inset-property
를 비활성화하는 방안으로 고려했어요. 그러나 이후에는 inset
뿐만 아니라 다른 최신 CSS 문법도 이슈가 될 가능성이 있어 보여서, 일단은 target
을 설정하고 js 파일에서 문제가 없는지 확인한 후에 다음과 같이 처리했어요.
// tsup.config.ts
export default defineConfig((options) => {
// ...etc,
target: 'es5',
esbuildOptions(options) {
options.target = ['chrome64', 'ios12'];
},
});
마치며
이전 글에 이어 tsup과 esbuild 사용 시 이슈를 두 번이나 겪다니 저랑 뭔가 있나 봅니다(?)
동료 개발자분의 제보 덕분에 나름 꽤 신선한(?) 경험을 했었던 것 같고, 이렇게 글로 정리해서 남겨볼 수 있어서 좋았어요. (감사합니다 😌)