π£ ν΄λ¦¬ν(polyfill)μ κ³Όλνκ² μ¬μ©ν λ²λ€ λΉλν: μ΄κΈ° λ‘λ© μ§μ°κ³Ό μ¬μ©μ κ²½ν μ ν
Summary
λͺ¨λ λΈλΌμ°μ λ₯Ό μ§μνκΈ° μν΄ ν΄λ¦¬νμ 무λΆλ³νκ² μ μ©νλ©΄ λ²λ€ ν¬κΈ°κ° μ¦κ°νκ³ μ±λ₯μ΄ μ νλ©λλ€. Browserslist, λμ ν΄λ¦¬ν λ‘λ©, μ½λ λΆν μ ν΅ν΄ νμν ν΄λ¦¬νλ§ μ λ³μ μΌλ‘ μ μ©νμ¬ μ΅μ μ μ¬μ©μ κ²½νμ μ 곡ν΄μΌ ν©λλ€.
Why Wrong?
μ΅μ JavaScript κΈ°λ₯μ κ΄λ²μνκ² μ¬μ©νλ©΄μ ꡬν λΈλΌμ°μ λ₯Ό μ§μνκΈ° μν΄ λͺ¨λ κΈ°λ₯μ ν΄λ¦¬ννλ©΄ λ²λ€ ν¬κΈ°κ° κΈ°νκΈμμ μΌλ‘ μ¦κ°ν©λλ€. λΆνμν ν΄λ¦¬νμ μ΄κΈ° λ‘λ© μκ°μ μ§μ°μν€κ³ , μ¬μ©μ κ²½νμ μ νμν€λ©°, νΉν μ μ¬μ κΈ°κΈ°λ λλ¦° λ€νΈμν¬ νκ²½μμ λμ± μ¬κ°ν λ¬Έμ λ₯Ό μΌκΈ°ν©λλ€. ν΅μ¬μ νμν ν΄λ¦¬νλ§ μ λ³μ μΌλ‘ μ μ©νκ³ , μ΅μ λΈλΌμ°μ μμλ ν΄λ¦¬νμ μ κ±°νμ¬ μ΅μ μ μ±λ₯μ μ μ§νλ κ²μ λλ€.
How to Fix?
- Targeted Polyfilling: Babelμ
useBuiltIns
μ΅μ κ³Ό Browserslistλ₯Ό μ¬μ©νμ¬ μ€μ νμν ν΄λ¦¬νλ§ ν¬ν¨νλλ‘ μ€μ ν©λλ€. Browserslistλ νλ‘μ νΈμμ μ§μν΄μΌ νλ λΈλΌμ°μ λ²μλ₯Ό μ μνκ³ , Babelμ μ΄λ₯Ό κΈ°λ°μΌλ‘ νμν ν΄λ¦¬νλ§ μλμΌλ‘ μΆκ°ν©λλ€. - Dynamic Polyfill Loading:
Intersection Observer API
λUser-Agent
λ¬Έμμ΄μ μ¬μ©νμ¬ λΈλΌμ°μ κΈ°λ₯μ κ°μ§νκ³ , νμν κ²½μ°μλ§ ν΄λ¦¬νμ λμ μΌλ‘ λ‘λ©ν©λλ€.polyfill.io
μ κ°μ μλΉμ€λ₯Ό μ¬μ©νμ¬ CDNμ ν΅ν΄ ν΄λ¦¬νμ μ 곡νκ³ , λΈλΌμ°μ λ³λ‘ μ΅μ νλ ν΄λ¦¬ν μΈνΈλ₯Ό μ 곡ν μλ μμ΅λλ€. - Modern Syntax Transpilation: μ΅μ JavaScript λ¬Έλ²(μ: ES modules)μ μ¬μ©νμ¬ μ½λλ₯Ό μμ±νκ³ , Babelκ³Ό κ°μ νΈλμ€νμΌλ¬λ₯Ό μ¬μ©νμ¬ κ΅¬ν λΈλΌμ°μ μμ μ€ν κ°λ₯ν μ½λλ‘ λ³νν©λλ€. μ΄λ, μ΅μ λΈλΌμ°μ λ₯Ό μν μ½λλ κ°λ₯ν ν λ³νμ μ΅μννμ¬ μ±λ₯μ μ΅μ νν©λλ€.
- Code Splitting: μ½λλ₯Ό μ¬λ¬ μ²ν¬λ‘ λΆν νκ³ , μ΄κΈ° λ‘λ©μ νμν μ½λλ§ λ¨Όμ λ‘λ©ν©λλ€. ν΄λ¦¬ν κ΄λ ¨ μ½λλ₯Ό λ³λμ μ²ν¬λ‘ λΆλ¦¬νμ¬ νμν κ²½μ°μλ§ λ‘λ©νλ©΄ μ΄κΈ° λ‘λ© μκ°μ λ¨μΆν μ μμ΅λλ€.
Before Code (Bad)
// babel.config.js
module.exports = {
presets: [
['@babel/preset-env', {
useBuiltIns: 'usage', // λͺ¨λ ν΄λ¦¬ν ν¬ν¨
corejs: 3,
targets: '> 0.25%, not dead' // λͺ¨λ λΈλΌμ°μ μ§μ
}]
]
};
// index.js
const promise = Promise.resolve(123);
const array = [1, 2, 3].includes(2);
// ... λλ¨Έμ§ μ½λ
After Code (Good)
// babel.config.js
module.exports = {
presets: [
['@babel/preset-env', {
useBuiltIns: 'usage', // νμν ν΄λ¦¬νλ§ ν¬ν¨
corejs: 3,
targets: {
chrome: '79', // νΉμ λΈλΌμ°μ λ²μ λ§ μ§μ
firefox: '72',
safari: '13'
}
}]
]
};
// index.js
const promise = Promise.resolve(123);
const array = [1, 2, 3].includes(2);
// ... λλ¨Έμ§ μ½λ
```
```javascript
// λμ ν΄λ¦¬ν λ‘λ© μμ
if (!('IntersectionObserver' in window)) {
import('intersection-observer').then(() => {
// Intersection Observerλ₯Ό μ¬μ©νλ μ½λ
});
}