Làm cách nào để cài đặt thư viện babel-polyfill?


140

Tôi mới bắt đầu sử dụng Babel để biên dịch mã javascript ES6 của mình thành ES5. Khi tôi bắt đầu sử dụng Promise, có vẻ như nó không hoạt động. Trang web Babel tuyên bố hỗ trợ cho những lời hứa thông qua các polyfill.

Không có may mắn, tôi đã cố gắng thêm:

require("babel/polyfill");

hoặc là

import * as p from "babel/polyfill";

Với điều đó, tôi sẽ gặp lỗi sau khi khởi động ứng dụng của mình:

Không thể tìm thấy mô-đun 'babel / polyfill'

Tôi đã tìm kiếm mô-đun nhưng có vẻ như tôi đang thiếu một số điều cơ bản ở đây. Tôi cũng đã cố gắng thêm NPM bluebird cũ và tốt nhưng có vẻ như nó không hoạt động.

Làm thế nào để sử dụng polyfill từ Babel?


1
npm install _name_
dandavis

1
LƯU Ý: Babel hiện có gói NPM riêng cho việc này: babel-polyfill
Stijn de Witt

1
@StijndeWitt chỉ để giúp bạn tiết kiệm một cú nhấp chuột, đây là tệp
README.md

1
@gurghet Vâng, họ có thể đã thêm một số thông tin ở đó Tôi đồng ý :) Nhưng tất cả những gì bạn thực sự cần biết là npm install --save babel-polyfillrequire('babel-polyfill).
Stijn de Witt

1
Vì bạn đang sử dụng ES6, bạn cũng có thể sử dụng nhập "babel-polyfill".
Yêu Hasija

Câu trả lời:


66

Điều này đã thay đổi một chút trong babel v6.

Từ các tài liệu:

Polyfill sẽ mô phỏng môi trường ES6 đầy đủ. Polyfill này được tự động tải khi sử dụng nút babel.

Cài đặt:
$ npm install babel-polyfill

Cách sử dụng trong Node / Browserify / Webpack:
Để bao gồm polyfill, bạn cần yêu cầu nó ở đầu điểm nhập vào ứng dụng của bạn.
require("babel-polyfill");

Sử dụng trong Trình duyệt:
Có sẵn từ dist/polyfill.jstệp trong babel-polyfillbản phát hành npm. Điều này cần phải được bao gồm trước khi tất cả mã Babel được biên dịch của bạn. Bạn có thể thêm nó vào mã được biên dịch của bạn hoặc đưa nó vào <script>trước mã đó.

LƯU Ý: Không được requirethông qua browserify, v.v., sử dụng babel-polyfill.


6
Tôi vẫn không hoàn toàn chắc chắn khi cần polyfill. Tại sao các mô-đun ES6 chỉ hoạt động với babel.js nhưng Array.protorype.findIndex()không hoạt động mà không có polyfill và babel sẽ không đưa ra một ngoại lệ khi nó được dịch mã? Đó có phải là bản chất của Polyfill ™ không?
RemEmber

5
Về cơ bản Babel polyfill chỉ là github.com/facebook/regeneratorgithub.com/zloirock/core-js kết hợp. Kiểm tra 2 repos đó để biết nếu bạn thực sự cần polyfill.
vdclouis

7
Tôi nghĩ rằng lý do người này làm việc và người kia không phải là vì Babel, khi dịch mã, nhắm vào một công cụ JS giả định với một mức hỗ trợ nhất định. Các trình duyệt thực có thể cuối cùng hỗ trợ nhiều hơn hoặc ít hơn công cụ giả định này. Trong thực tế tôi nghĩ rằng trình duyệt giả định mà họ nhắm đến nằm ở đâu đó ở cấp IE10, vì vậy các trình duyệt cũ hơn có thể có một số vấn đề. Bằng cách đặt các bản sửa lỗi cho điều này trong một polyfill riêng biệt, họ sẽ quyết định xem bạn có muốn hỗ trợ các trình duyệt cũ hơn cho bạn hay không. Một chút giống như jQuery với nhánh 1.0, và nhánh 2.0 không hỗ trợ IE8. @RemEmber
Stijn de Witt

2
@dougmacklin nếu find Index là polyfill duy nhất bạn cần, bạn chỉ có thể đưa cái đó vào đâu đó trong mã của mình. Kiểm tra MDN cho polyfills: developer.mozilla.org/en/docs/Web/JavaScript/Reference/
Kẻ

1
@vdclouis, làm thế nào bạn có thể bao gồm mã polyfill đó qua webpack để nó có sẵn ở mọi nơi trong dự án?
dougmacklin

48

Các tài liệu Babel mô tả điều này khá chính xác:

Babel bao gồm một polyfill bao gồm thời gian chạy bộ tái tạo tùy chỉnh và core.js.

Điều này sẽ mô phỏng một môi trường ES6 đầy đủ. Polyfill này được tự động tải khi sử dụng nút babel và babel / register.

Hãy chắc chắn rằng bạn yêu cầu nó tại điểm vào ứng dụng của bạn, trước khi bất cứ điều gì khác được gọi. Nếu bạn đang sử dụng một công cụ như webpack, điều đó trở nên khá đơn giản (bạn có thể yêu cầu webpack đưa nó vào gói).

Nếu bạn đang sử dụng một công cụ như gulp-babelhoặc babel-loader, bạn cũng cần cài đặt babelgói đó để sử dụng polyfill.

Cũng lưu ý rằng đối với các mô-đun ảnh hưởng đến phạm vi toàn cầu (polyfill và tương tự), bạn có thể sử dụng nhập ngắn gọn để tránh có các biến không sử dụng trong mô-đun của mình:

import 'babel/polyfill';

4
Chỉ cần thêm một ghi chú và tôi không chắc chắn 100% nếu điều này hoàn toàn chính xác, nhưng tôi đã cố gắng chỉ sử dụng import 'babel-core/polyfill'mà không cài đặt babelvà nó hoạt động tốt.
Nathan Lutterman

2
Zaemz , tôi đoán bạn đã cài đặt babel, vì vậy import 'babel-core/polifyll'hoạt động. Tôi đã thử nó mà không cài đặt babelvà nó không làm việc cho tôi. Nhân tiện: ssube khuyên làm việc.
WebBrother

4
Khi sử dụng webpack bạn bao gồm nó ở đâu?
theptrk

2
@theptrk Sử dụng webpack, bạn chỉ cần nhập nó dưới dạng mô-đun, vì webpack cho phép nhập các gói npm. Đối với Karma, bạn thiết lập nó dưới dạng một tệp để đưa vào trước khi kiểm tra.
ssube

3
Cảm ơn, có thể tôi đã có một phiên bản khác nhưng tôi phải sử dụng babel-core thay thế => "nhập 'babel-core / polyfill';
theptrk

22

Đối với Babel phiên bản 7, nếu bạn đang sử dụng @ babel / preset-env, để bao gồm polyfill, tất cả những gì bạn phải làm là thêm một cờ 'useBuiltIns' với giá trị 'cách sử dụng' trong cấu hình babel của bạn. Không cần phải yêu cầu hoặc nhập polyfill tại điểm vào của Ứng dụng của bạn.

Với cờ này được chỉ định, babel @ 7 sẽ tối ưu hóa và chỉ bao gồm các polyfill bạn cần.

Để sử dụng cờ này, sau khi cài đặt:

npm install --save-dev  @babel/core @babel/cli @babel/preset-env
npm install --save @babel/polyfill

Chỉ cần thêm cờ:

useBuiltIns: "usage" 

vào tệp cấu hình babel của bạn được gọi là "babel.config.js" (cũng mới đối với Babel @ 7), trong phần "@ babel / env":

// file: babel.config.js

module.exports = () => {
   const presets = [
      [
         "@babel/env", 
         { 
             targets: { /* your targeted browser */ },
             useBuiltIns: "usage"  // <-----------------*** add this
         }
      ]
   ];

   return { presets };
};

Tài liệu tham khảo:


Cập nhật tháng 8 năm 2019:

Với việc phát hành Babel 7.4.0 (ngày 19 tháng 3 năm 2019) @ babel / polyfill bị phản đối. Thay vì cài đặt @ babe / polyfill, bạn sẽ cài đặt core-js:

npm install --save core-js@3

Một mục mới corejsđược thêm vào babel.config.js của bạn

// file: babel.config.js

module.exports = () => {
   const presets = [
      [
         "@babel/env", 
         { 
             targets: { /* your targeted browser */ },
             useBuiltIns: "usage",
             corejs: 3  // <----- specify version of corejs used
         }
      ]
   ];

   return { presets };
};

xem ví dụ: https://github.com/ApolloTang/stackoverflow-eg--babel-v7.4.0-polyfill-w-core-v3

Tài liệu tham khảo:


1
Bạn có sử dụng điều này trong sản xuất env? Rủi ro nào?
Roy

useBuiltIns: "usage"không làm việc về phía tôi. Nó chỉ không bao gồm bất kỳ polyfils nào trong gói (ví dụ: Tôi sử dụng trình tạo và gặp lỗi "tái tạo không được xác định"). Có ý kiến ​​gì không?
WebBrother

@WebBrother, hoạt động với tôi ... xem ví dụ: github.com/ApolloTang/stackoverflow-eg--babel-polyfill
apoche

@Roy, tôi thực sự đang trong quá trình di chuyển một dự án doanh nghiệp từ babel @ 6 sang babel @ 7 để tôi có thể sử dụng @ babel / preset-typecript. Đây vẫn là một công việc đang tiến triển, nhưng tôi đang làm theo hướng dẫn từ tài liệu chính thức của babel (xem các liên kết tham khảo trong câu trả lời của tôi). Cho đến nay mọi thứ dường như đang hoạt động, nhưng tôi chưa gửi công việc di chuyển / nâng cấp của mình đến QA, tôi sẽ đăng ở đây nếu có vấn đề phát sinh.
apol

19

Nếu gói.json của bạn trông giống như sau:

  ...
  "devDependencies": {
    "babel": "^6.5.2",
    "babel-eslint": "^6.0.4",
    "babel-polyfill": "^6.8.0",
    "babel-preset-es2015": "^6.6.0",
    "babelify": "^7.3.0",
  ...

Và bạn nhận được thông Cannot find module 'babel/polyfill'báo lỗi, thì có lẽ bạn chỉ cần thay đổi câu lệnh nhập TỪ:

import "babel/polyfill";

ĐẾN:

import "babel-polyfill";

Và chắc chắn rằng nó xuất hiện trước bất kỳ importtuyên bố nào khác (không nhất thiết phải ở điểm vào của ứng dụng của bạn).

Tham khảo: https://babeljs.io/docs/usage/polyfill/


3
Trong câu trả lời này, gói babel-polyfill được liệt kê dưới 'devDependencies'. Làm điều này sẽ dẫn đến babel-polyfill không được bao gồm trong triển khai. Bạn không nên cài đặt babel-polyfill với cờ -D mà với cờ -S để nó được liệt kê dưới 'phụ thuộc', và do đó được bao gồm trong triển khai của bạn.
apol

9

Trước hết, câu trả lời rõ ràng mà không ai cung cấp, bạn cần cài đặt Babel vào ứng dụng của mình:

npm install babel --save

(hoặc babel-corenếu bạn muốn thay thế require('babel-core/polyfill')).

Ngoài ra, tôi có một nhiệm vụ khó khăn là dịch mã es6 và jsx của tôi dưới dạng bước xây dựng (nghĩa là tôi không muốn sử dụng babel/register, đó là lý do tại sao tôi đang cố gắng sử dụng babel/polyfilltrực tiếp ở nơi đầu tiên), vì vậy tôi muốn nhấn mạnh hơn vào phần này của câu trả lời của @ ssube:

Hãy chắc chắn rằng bạn yêu cầu nó tại điểm vào ứng dụng của bạn, trước khi mọi thứ khác được gọi

Tôi gặp phải một số vấn đề kỳ lạ khi tôi cố gắng yêu cầu babel/polyfilltừ một số tệp khởi động môi trường được chia sẻ và tôi đã gặp lỗi mà người dùng đã tham chiếu - Tôi nghĩ rằng nó có thể có liên quan đến cách nhập đơn hàng babel so với yêu cầu nhưng tôi không thể sao chép hiện nay. Dù sao, di chuyển import 'babel/polyfill'như là dòng đầu tiên trong cả kịch bản khởi động máy khách và máy chủ của tôi đã khắc phục vấn đề.

Lưu ý rằng nếu bạn muốn sử dụng thay vào đó, require('babel/polyfill')tôi sẽ đảm bảo tất cả các câu lệnh trình tải mô-đun khác của bạn cũng được yêu cầu và không sử dụng nhập khẩu - tránh trộn lẫn hai. Nói cách khác, nếu bạn có bất kỳ câu lệnh nhập nào trong tập lệnh khởi động, hãy tạo import babel/polyfilldòng đầu tiên trong tập lệnh của bạn chứ không phải require('babel/polyfill').


9

8

babel-polyfill cho phép bạn sử dụng bộ tính năng ES6 đầy đủ ngoài các thay đổi cú pháp. Điều này bao gồm các tính năng như các đối tượng tích hợp mới như Promise và WeakMap, cũng như các phương thức tĩnh mới như Array.from hoặc Object.assign.

Không có babel-polyfill, babel chỉ cho phép bạn sử dụng các tính năng như hàm mũi tên, phá hủy, đối số mặc định và các tính năng cụ thể theo cú pháp khác được giới thiệu trong ES6.

https://www.quora.com/What-does-babel-polyfill-do

https://hackernoon.com/polyfills-everything-you-ever-wocate-to-ledge-or-maybe-a-bit-less-7c8de164e423


0

Giống như Babel nói trong các tài liệu , đối với Babel> 7.4.0, mô-đun @ babel / polyfill không được chấp nhận , do đó, nên sử dụng các thư viện core-js và bộ tạo thời gian chạy trực tiếp mà trước đây được đưa vào @ babel / polyfill.

Vì vậy, điều này làm việc cho tôi:

npm install --save core-js@3.6.5
npm install regenerator-runtime

sau đó thêm vào đầu tập tin js ban đầu của bạn:

import 'core-js/stable';
import 'regenerator-runtime/runtime';
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.