Babel 打包后的代码运行出现‘_classCallCheck is not defined’错误的解决方案

前端开发中,我们经常会使用 Babel 来将 ES6/ES7 的代码转译成 ES5 代码,以保证代码能够在低版本浏览器中正常运行。但是,在打包后的代码中,有时会出现类似‘_classCallCheck is not defined’的错误,这主要是由于 Babel 编译后的代码中缺少了一些运行时的辅助函数导致的。本文将介绍如何解决这个问题。

问题背景

在使用 Babel 将 ES6 代码编译成 ES5 代码后,有些新的语法会被转换成旧的语法,比如使用 class 定义类的语法,就会被转换成使用函数定义类,如下所示:

----- ------ -
  ----------------- ---- -
    --------- - -----
    -------- - ----
  -

  ------- -
    ---------------- -- ---- -- ------------- --- ----------- ----- -------
  -
-

转换成

-------- ------------ ---- -
  --------- - -----
  -------- - ----
-

---------------------- - ---------- -
  ---------------- -- ---- -- ------------- --- ----------- ----- -------
--

如果我们不引入 @babel/polyfill 等运行时附加库,就会产生‘_classCallCheck is not defined’的错误,因为编译后的代码中,使用到 ES6 的 class 语法,会依赖 _classCallCheck 函数,但是这个函数在编译后的代码中没有定义。

解决方案

我们可以通过引入 @babel/runtime 中的 helpers 来解决这个问题。@babel/runtime 是一个为 Babel 打包后的代码提供运行时辅助的库,它提供了一组有用的辅助函数,这些函数可以被 Babel 自动生成到打包后的代码中,以帮助代码正确地运行。

安装

在使用 @babel/runtime 之前,需要先安装它:

--- ------- ---------- --------------
- --
---- --- -------------- -----

配置

然后,在 Babel 的配置文件中添加如下配置:

-
  ---------- ----------------------
  ---------- -
    ----------------------------------- -
      --------- ------ -- --- ---------- --------- -----
      ---------- -----
      -------------- -----
      --------------- -----
    --
  -
-

其中,@babel/plugin-transform-runtime 是一个 Babel 插件,可以将 Babel 打包后的代码中的公共辅助函数单独提取出来,防止代码重复,减小代码体积。

示例

有了上述配置之后,我们可以测试一下打包后的代码是否可以正常运行:

---- ---------- ---
--------- -----
------
  ------
    ----- ----------------
    ------------ ------------
  -------
  ------
    ------- --------------------------------
  -------
-------
-- ------------
----- ------ -
  ----------------- ---- -
    --------- - -----
    -------- - ----
  -

  ------- -
    ---------------- -- ---- -- ------------- --- ----------- ----- -------
  -
-

----- -- - --- ------------- ----
-----------

打包后的代码:

-- --------------
---- --------

------------------------------ ------------- -
  ------ ----
---
--------------- - ---- --

-------- ------------------------- ------------ - -- ----------- ---------- ------------- - ----- --- ----------------- ---- - ----- -- - ----------- - -

--- ------ - -------- ------------ ---- -
  --------------------- --------

  --------- - -----
  -------- - ----
--

---------------------- - -------- -- -
  ---------------- -- ---- -- ------------------- -- --- ------------------- - ----- --------
--

--- -------- - -------
--------------- - ---------

--- -- - --- ------------- ----
-----------

我们可以看到,打包后的代码中,会导入 @babel/runtime 中的 helpers,并将其定义的函数插入到打包后的代码中。

输出结果如下:

--- -- ---- -- ---- --- -- ----- ----

结论

通过上述方法,我们可以很方便地解决 Babel 打包后出现‘_classCallCheck is not defined’的错误。同时,在使用 @babel/plugin-transform-runtime 插件时,要注意设置 useESModules 选项的值,该选项决定了生成的辅助函数形式,为 false 表示生成 commonjs 模块形式,为 true 表示生成 ES modules 形式。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/672035492e7021665e012b40