tour 서비스에서 폴리필 관련 이슈.
defineIteratorMethods(AsyncIterator.prototype);
AsyncIterator.prototype[asyncIteratorSymbol] = function() {
return this;
};
exports.AsyncIterator = AsyncIterator;
오류 내용
Error: asyncIteratorSymbol이 문자열이 아닙니다. (IE 9~11에서)
tour_customview의 바벨 관련 패키지 버전
// 해당 이슈 이해를 돕는 패키지 외에 전부 생략
{
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-transform-regenerator": "^7.4.5",
"@babel/plugin-transform-runtime": "^7.4.4",
"@babel/preset-env": "^7.0.0"
},
"dependencies": {
"@babel/polyfill": "^7.0.0",
"@babel/runtime": "^7.4.5",
"core-js": "^2.4.1"
}
}
// babel.config.js, 해당 이슈 이해를 돕는 패키지 외에 전부 생략
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: '> 0.25%, not dead',
modules: false,
debug: true,
useBuiltIns: 'usage', // 'usage(experimental)',
},
],
['@babel/preset-react'],
],
plugins: ['@babel/plugin-transform-regenerator'],
};
해결방안 찾아가기
1. 바벨 폴리필 통째로 집어넣기
ES7의 asyncIterator를 지원하지 않는 거 같아 빠른 해결을 위해
useBuiltIns: 'entry'
로 변경하여 모든 polyfill 집어넣기
결론 : 똑같은 오류내용 보여주면서 안됨.
2. 근데 저 문법을 투어에서 쓰고 있나요..?
아니요.. 그렇다면 라이브러리에서 사용하는건데..
babel-loader가 권장한대로 node_modules은 제외하고 트랜스파일함. 권장 이유는 트랜스파일이 굉장히 느려질거고.. 대부분 라이브러리는 트랜스파일을 거쳐서 나오기때문..(대신 브라우저 지원 범위가 다름)
이 때, 모든 node_modules을 트랜스파일 하면 될 것 같았지만 시간 여유가 있어서 다른 방법 찾아봄
3. 시간도 많으니까 걍 바벨 설정 첨부터 다 까보자.
첨부터 다 까다가 생각해보니 문제되는 syntax에 대해 polyfill을 추가하면 되겠네 라고 생각해서 해결했다.
// in config/polyfill.js
import 'core-js/modules/es7.symbol.async-iterator';
이런 일이 없도록 하려면..?
babel/preset-env의 useBuiltIns를 entry로 하여 모든 폴리필을 집어넣자.
1번 해결책에서 봤듯이 모든 폴리필이 들어가는거 같지 않았다. 이유는..
entry 옵션만 넣었다고 polyfill이 전부 추가되지 않는다. entry 는 말 그대로 개발자가 import문을 작성한 폴리필만 transpile때 추가한다. (entry 옵션으로 해놓고, 폴리필을 import하지 않으면 어떠한 polyfill도 포함되지 않는다.)
이 때 아래와 같이 작성하면 3가지 polyfill만 추가된다. (투어 에서 아래와 같이 작성되있었다.) 4번째 라인만 import해야 모든 폴리필이 추가된다.
import 'core-js/es6/map';
import 'core-js/es6/set';
import 'core-js/fn/array';
// import "core-js/stable"
var promise = new Promise(resolve => {
resolve(5);
});
결론은 entry로 한다고 해서 모든 폴리필이 추가되는게 아닌, 개발자가 직접 모든 폴리필을 import하는 코드를 작성해줘야 한다.
하지만, 불필요한 폴리필이 포함되므로 좋지 않은 방법이다.
import 'core-js';
var promise = new Promise(resolve => {
resolve(parsed);
});
promise().then(val => console.log(val));
위 코드를 바벨로 트랜스파일 하면.. 아래와 같이 전부 import 된다.
왜냐하면 나는 promise만 필요한데, 아래와 같이 모든 폴리필이 불필요하게 추가되기 때문이다.
require('core-js/modules/es6.array.copy-within');
require('core-js/modules/es6.array.fill');
require('core-js/modules/es6.array.find');
require('core-js/modules/es6.array.find-index');
require('core-js/modules/es7.array.flat-map');
require('core-js/modules/es6.array.from');
require('core-js/modules/es7.array.includes');
require('core-js/modules/es6.array.iterator');
require('core-js/modules/es6.array.of');
require('core-js/modules/es6.array.species');
require('core-js/modules/es6.date.to-primitive');
require('core-js/modules/es6.function.has-instance');
require('core-js/modules/es6.function.name');
require('core-js/modules/es6.map');
require('core-js/modules/es6.math.acosh');
require('core-js/modules/es6.math.asinh');
require('core-js/modules/es6.math.atanh');
require('core-js/modules/es6.math.cbrt');
require('core-js/modules/es6.math.clz32');
require('core-js/modules/es6.math.cosh');
require('core-js/modules/es6.math.expm1');
require('core-js/modules/es6.math.fround');
require('core-js/modules/es6.math.hypot');
require('core-js/modules/es6.math.imul');
require('core-js/modules/es6.math.log1p');
require('core-js/modules/es6.math.log10');
require('core-js/modules/es6.math.log2');
require('core-js/modules/es6.math.sign');
require('core-js/modules/es6.math.sinh');
require('core-js/modules/es6.math.tanh');
require('core-js/modules/es6.math.trunc');
require('core-js/modules/es6.number.constructor');
require('core-js/modules/es6.number.epsilon');
require('core-js/modules/es6.number.is-finite');
require('core-js/modules/es6.number.is-integer');
require('core-js/modules/es6.number.is-nan');
require('core-js/modules/es6.number.is-safe-integer');
require('core-js/modules/es6.number.max-safe-integer');
require('core-js/modules/es6.number.min-safe-integer');
require('core-js/modules/es6.number.parse-float');
require('core-js/modules/es6.number.parse-int');
require('core-js/modules/es6.object.assign');
require('core-js/modules/es7.object.define-getter');
require('core-js/modules/es7.object.define-setter');
require('core-js/modules/es7.object.entries');
require('core-js/modules/es6.object.freeze');
require('core-js/modules/es6.object.get-own-property-descriptor');
require('core-js/modules/es7.object.get-own-property-descriptors');
require('core-js/modules/es6.object.get-own-property-names');
require('core-js/modules/es6.object.get-prototype-of');
require('core-js/modules/es7.object.lookup-getter');
require('core-js/modules/es7.object.lookup-setter');
require('core-js/modules/es6.object.prevent-extensions');
require('core-js/modules/es6.object.to-string');
require('core-js/modules/es6.object.is');
require('core-js/modules/es6.object.is-frozen');
require('core-js/modules/es6.object.is-sealed');
require('core-js/modules/es6.object.is-extensible');
require('core-js/modules/es6.object.keys');
require('core-js/modules/es6.object.seal');
require('core-js/modules/es7.object.values');
require('core-js/modules/es6.promise');
require('core-js/modules/es7.promise.finally');
require('core-js/modules/es6.reflect.apply');
require('core-js/modules/es6.reflect.construct');
require('core-js/modules/es6.reflect.define-property');
require('core-js/modules/es6.reflect.delete-property');
require('core-js/modules/es6.reflect.get');
require('core-js/modules/es6.reflect.get-own-property-descriptor');
require('core-js/modules/es6.reflect.get-prototype-of');
require('core-js/modules/es6.reflect.has');
require('core-js/modules/es6.reflect.is-extensible');
require('core-js/modules/es6.reflect.own-keys');
require('core-js/modules/es6.reflect.prevent-extensions');
require('core-js/modules/es6.reflect.set');
require('core-js/modules/es6.reflect.set-prototype-of');
require('core-js/modules/es6.regexp.constructor');
require('core-js/modules/es6.regexp.flags');
require('core-js/modules/es6.regexp.match');
require('core-js/modules/es6.regexp.replace');
require('core-js/modules/es6.regexp.split');
require('core-js/modules/es6.regexp.search');
require('core-js/modules/es6.regexp.to-string');
require('core-js/modules/es6.set');
require('core-js/modules/es6.symbol');
require('core-js/modules/es7.symbol.async-iterator');
require('core-js/modules/es6.string.anchor');
require('core-js/modules/es6.string.big');
require('core-js/modules/es6.string.blink');
require('core-js/modules/es6.string.bold');
require('core-js/modules/es6.string.code-point-at');
require('core-js/modules/es6.string.ends-with');
require('core-js/modules/es6.string.fixed');
require('core-js/modules/es6.string.fontcolor');
require('core-js/modules/es6.string.fontsize');
require('core-js/modules/es6.string.from-code-point');
require('core-js/modules/es6.string.includes');
require('core-js/modules/es6.string.italics');
require('core-js/modules/es6.string.iterator');
require('core-js/modules/es6.string.link');
require('core-js/modules/es7.string.pad-start');
require('core-js/modules/es7.string.pad-end');
require('core-js/modules/es6.string.raw');
require('core-js/modules/es6.string.repeat');
require('core-js/modules/es6.string.small');
require('core-js/modules/es6.string.starts-with');
require('core-js/modules/es6.string.strike');
require('core-js/modules/es6.string.sub');
require('core-js/modules/es6.string.sup');
require('core-js/modules/es7.string.trim-left');
require('core-js/modules/es7.string.trim-right');
require('core-js/modules/es6.typed.array-buffer');
require('core-js/modules/es6.typed.int8-array');
require('core-js/modules/es6.typed.uint8-array');
require('core-js/modules/es6.typed.uint8-clamped-array');
require('core-js/modules/es6.typed.int16-array');
require('core-js/modules/es6.typed.uint16-array');
require('core-js/modules/es6.typed.int32-array');
require('core-js/modules/es6.typed.uint32-array');
require('core-js/modules/es6.typed.float32-array');
require('core-js/modules/es6.typed.float64-array');
require('core-js/modules/es6.weak-map');
require('core-js/modules/es6.weak-set');
require('core-js/modules/web.timers');
require('core-js/modules/web.immediate');
require('core-js/modules/web.dom.iterable');
require('regenerator-runtime/runtime');
그래서 이건 좋지 않은 방법이다.
라이브러리를 사용하기 전에 어디까지 지원하는지 확인하자.
예를 들어 쿼리스트링 라이브러리을 보면, 친절하게 IE 는 지원하지 않는다고 알려줬다.
코드를 까보면 const, let을 사용하고 있다.
근데 지원 범위를 라이브러리에서 알려주지 않아요.. ㅂㄷㅂㄷ
개발자가 IE 에서 test를 해보거나,
QA 분이 IE에서 안된다고 할 때,
해당 syntax 에러와 관련된 패키지를 직접 추가해주는 방법밖에 없는 거 같다.
아래와 같이..
// in config/polyfill.js
import 'core-js/modules/es7.symbol.async-iterator';
의심되는 혹은 폴리필이 필요한 라이브러리는 뭔지 알겠어요
babel-loader의 include 옵션에 해당 모듈만 포함시켜서 같이 트랜스파일 시키자.
어떤 라이브러리가 문제인지도 모르겠고, 어떤 폴리필이 필요한지도 모르겠고.. 제가 시간이 없거든요..
// babel config를 entry 로 설정 후,
import 'core-js';
이외에 좋은 해결 방법이나 틀린 내용이 있다면 알려주세요.. 해결방법을 찾고 공식 문서 읽어가며 작성한 내용입니다.
Last updated
Was this helpful?