Webpack 4+Babel 7+ES6 호 환 IE8 의 실현

6442 단어 Webpack4Babel7ES6IE8
얼마 전에 재 미 있 는 프로젝트 를 재 구성 하 였 는데 브 라 우 저 환경 을 바탕 으로 하 는 데이터 수집 sdk 입 니 다.회사 각 제품 의 전단 페이지 에 이 sdk 가 삽입 되 어 사용자 의 행위 데 이 터 를 수집 하고 회사 의 빅 데이터 플랫폼 에 업로드 하여 후속 적 인 운영 결정 분석 에 데이터 기반 을 마련 합 니 다.
필자 가 이 프로젝트 를 맡 았 을 때 전 개발 자 들 은 이미 기능 을 많이 다 쓰 지 못 했다.유일 하 게 해 야 할 일 은 후속 개발 과 유 지 를 위해 모듈 화 분할 과 코드 규범 을 하 는 것 이다.모듈 화 분할 용 웹 팩,코드 규범 용 eslint.재 구성 하려 면 에 스 6 로 다시 쓰 세 요.콜백 도 필요 없고,모두 promise 로 바 꾸 고,async,await 도 사용 합 니 다.어쨌든 시원 하 게 쓰 세 요.
PM 브 라 우 저 는 어느 버 전 으로 최소 호 환 되 는 지 물 었 고,PM 은 각 제품 이 호 환 되 는 최저 버 전 을 호 환 하면 된다 고 말 했다.회사 각 제품 의 전단 책임자 와 소통 한 결과 IE8 을 호 환 하 는 사람 이 있다 는 것 을 알 게 되 었 습 니 다.정말 저 는 fk 입 니 다.
구 글 은 웹 팩+바벨+ES6 호 환 IE8 을 살 펴 보 았 는데 역시 구덩이 가 많 았 다.여러 편의 블 로그 가 내 놓 은 방안 을 시험 해 보 았 지만 모두 통 하지 않 았 다.구체 적 으로 어디 에 문제 가 있 는 지 는 별로 연구 하지 않 았 다.왜냐하면 그 해결 방안 안의 웹 팩 과 바 벨 은 모두 구식 이기 때문에 뚫 려 도 사용 하기 싫 기 때문이다.필 자 는 블 로그 에서 제기 한 몇 가지 관건 적 인 문 제 를 분석 한 다음 에 웹 팩 과 babel 의 최신 공식 문 서 를 참고 하여 최신 웹 팩 4+Babel 7+ES6 호 환 IE8 방안 을 정리 했다.
ES6 호 환 IE8 은 네 가지 문 제 를 해결 해 야 합 니 다.
문법 지원
IE 브 라 우 저 는 ES6 의 문법 을 지원 하지 않 고 IE 10,IE 11 에서 만 ES6 의 API 를 일부 지원 하기 때문에 IE 브 라 우 저 에서 ES6 를 사용 하려 면 ES6 의 코드 를 ES5 로 컴 파일 해 야 실행 할 수 있다.방법 도 간단 하 다.바로 babel-loader 를 사용 하 는 것 이다.이 부분 은 아무런 구덩이 가 없 기 때문에 나 도 자세히 말 하지 않 겠 다.각 브 라 우 저 버 전에 서 ES5,ES6 의 지원 상황 을 스스로 볼 수 있 는 사 이 트 를 제공 합 니 다.
https://kangax.github.io/compat-table/es6/
ES3 보존 키워드
IE8 에서 object.property Name 을 통 해 ES3 의 보존 키워드(예 를 들 어 default,class,catch)를 사용 하면 오류 가 발생 합 니 다.

SCRIPT1048:      
웹 팩 에는 ES3 의 키워드 호 환 문 제 를 처리 하기 위해 loader 플러그 인 es3ify-loader 가 있 습 니 다.이 플러그 인의 역할 은 이 보존 자 들 을 따옴표 를 붙 이 고 문자열 형식 으로 참조 하 는 것 입 니 다.

//    
function(t) { return t.default; }

//    
function(t) { return t["default"]; }
그러나 필자 가 직접 실천 한 결과 UglifyJS 는 IE 브 라 우 저 에 대한 지원 을 제 공 했 기 때문에 es3ify-loader 를 추가 로 도입 할 필요 가 없다 는 것 을 알 게 되 었 다.웹 팩 의 기본 UglifyJS 설정 은 ie8 을 지원 하지 않 습 니 다.수 동 으로 설정 해 야 합 니 다.

{
 mode: 'production',
 optimization: {
  minimizer: [
   new UglifyJsPlugin({
    uglifyOptions: {
     ie8: true
    }
   })
  ]
 }
}
실행 환경
앞의 두 문 제 를 해결 하면 문법 적 으로 잘못 보고 하지 않 을 수 있 지만 ES6 의 API(예 를 들 어 Promise)를 사용 하면 잘못 보고 할 수 있 습 니 다.또한 IE8 은 ES5 에 대한 API 지원 도 매우 나 빠 소량의 API 만 지 원 했 고 일부 API 는 일부 기능(예 를 들 어 Object.defineProperty)만 지원 했다.따라서 IE8 에서 ES6 코드 를 완벽 하 게 실행 하려 면 ES6 API 뿐만 아니 라 ES5 API 도 채 워 야 한다.
babel 은 이 를 위해 두 가지 해결 방안 을 제공 했다.@babel/polyfill,@babel/runtime.구체 적 인 사용 방법 은 공식 문서 가 이미 상세 하 게 썼 으 니 필 자 는 군말 하지 않 겠 다.여기 서 묵 백 학생 의 글 중 하 나 를 바로 잡 습 니 다.즉,@babel/poly fill 은 현재 필요 에 따라 불 러 오 는 것 을 지원 하고 있 습 니 다.정확하게 말 하면 잘못 이 라 고 할 수 없습니다.묵 백 학생 이 이 글 을 쓸 때 필요 에 따라 불 러 오 는 것 을 지원 하지 않 기 때 문 입 니 다.구체 적 인 방법 은 자세히 말씀 드 리 지 않 겠 습 니 다.문서 에 있 습 니 다.browserlist와@babel/preset-env 의 useBuiltsIns 속성 을 설정 하면 됩 니 다.
나 는 단지 내 가 실제 개발 과정 에서 만난 구 덩이 를 말 할 뿐이다.
@babel/polyfill,@babel/runtime 은 필요 에 따라 불 러 오 는 것 을 지원 하지만 업무 코드 에 사용 되 는 부족 한 API 만 식별 할 수 있 습 니 다.만약 에 제3자 라 이브 러 리 가 이러한 부족 한 API 를 사용 하면 babel 이 식별 하지 못 하고 자 연 스 럽 게 채 울 수 없습니다.예 를 들 어 regenerator-runtime 에 사용 되 는 Object.create 와 Array.prototype.foreach.해결 방법 은 입구 파일 에 부족 한 API 를 수 동 으로 도입 하 는 것 이다.
모듈 화 로드
필 자 는 원래 ES6 의 모듈 화 로드 방안 을 사용 하려 고 했 습 니 다.웹 팩 의 tree shaking 을 이용 하여 불필요 한 코드 를 제거 하여 압축 된 파일 의 부 피 를 더욱 작 게 할 수 있 기 때 문 입 니 다.그러나 IE8 테스트 에서 Object.defineProperty 가'Accessors not supported!'를 잘못 보고 한 것 으로 나 타 났 다.오류 코드 는 아래 와 같다.

if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');
나 는@babel/plugin-transform-modules-commonjs을 comonjs 로 불 러 오 면 이 구 덩이 를 돌아 갈 수 있 지만 동시에 tree shaking 을 포기 했다 는 것 을 의미한다.
총결산
package.json

{
 "devDependencies": {
  "@babel/core": "^7.2.2",
  "@babel/plugin-transform-runtime": "^7.2.0",
  "@babel/preset-env": "^7.1.0",
  "@babel/runtime": "^7.3.4",
  "babel-loader": "^8.0.4",
  "core-js": "^3.0.1",
  "uglifyjs-webpack-plugin": "^2.0.1",
  "webpack": "^4.20.2",
  "webpack-cli": "^3.1.2",
  "webpack-dev-server": "^3.1.9",
  "webpack-merge": "^4.1.4"
 }
}
웹 팩 설정

{
 module: {
  rules: [
   {
    test: /\.js$/,
    exclude: /(node_modules|bower_components)/,
    use: {
     loader: 'babel-loader',
     options: {
      presets: [
       '@babel/preset-env'
      ],
      plugins: [
       [
        '@babel/plugin-transform-runtime'
       ],
       [
        //       IE8       ,     tree shaking
        //   IE8                
        '@babel/plugin-transform-modules-commonjs'
       ]
      ]
     }
    }
   }
  ]
 },
 optimization: {
  minimizer: [
   new UglifyJsPlugin({
    sourceMap: true,
    uglifyOptions: {
     ie8: true,
    }
   })
  ]
 }
}
입구 파일 은 필요 에 따라 부족 한 API 를 도입 합 니 다.

require('core-js/features/object/define-property')
require('core-js/features/object/create')
require('core-js/features/object/assign')
require('core-js/features/array/for-each')
require('core-js/features/array/index-of')
require('core-js/features/function/bind')
require('core-js/features/promise')
마지막 으로 글 에서 처음에 언급 한 sdk 소스 코드 를 동봉 합 니 다.필 자 는 회사 업무 관련 코드 를 제거 하고 유 니 버 설 부분 을 오픈 했 습 니 다.4567915)
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기