Gulp打包支持Await/Async语法

开发 前端
在项目中,最近需要对node代码进行混淆编译,原来曾经解决过ES6打包混淆的问题,在使用的是gulp打包,为了提升代码质量还有异步操作顺序问题,使用了async/await语法,原来的gulpfile混淆又出问题了。

 [[407602]]

本文转载自微信公众号「前端学苑」,作者前端小贾。转载本文请联系前端学苑公众号。

简短的概括:

1使用 ES7 的 async/await 时报错

在项目中,最近需要对node代码进行混淆编译,原来曾经解决过ES6打包混淆的问题,在使用的是gulp打包,为了提升代码质量还有异步操作顺序问题,使用了async/await语法,原来的gulpfile混淆又出问题了。

出现问题:

打包完后浏览器报错gulp

  1. Uncaught ReferenceError: regeneratorRuntime is not defined 

对 babel polyfill 的一些理解

一、babel 和 babel ployfill 的关系

1、先来理解下 babel 到底是做什么的?

简单来讲,babel解决语法层面的问题。用于将ES6+的高级语法转为ES5。

2、babel polyfill 又是做什么的?

如果要解决API层面的问题,需要使用垫片。比如常见的有babel-polyfill、babel-runtime 和 babel-plugin-transform-runtime。

理清了他们之间的关系,那么再正式来讲讲有关polyfill的二三事。

二、polyfill 种类

babel polyfill 有三种

  1. * babel-polyfill 
  2. * babel-runtime 
  3. * babel-plugin-transform-runtime 

1babel-polyfill

babel-polyfill通过向全局对象和内置对象的prototype上添加方法来实现的。所以这会造成全局空间污染。

babel-polyfill使用的两种方式

1) webpack.config.js 中:

配置webpack.config.js里的entry设置为entry: ['babel-polyfill',path.join(__dirname, 'index.js')]

2) 业务 js 中:

在webpack.config.js配置的主入口index.js文件的最顶层键入

  1. import 'babel-polyfill' 

两者打印出来的大小都是一样的,打包后大小是280KB,如果没有使用babel-polyfill,大小是3.43kb。两则相差大概81.6倍。原因是webpack把babel-polyfill整体全部都打包进去了。而babel-polyfill肯定也实现了所有ES6新API,文件一定不会小。

那么有没有一种办法,根据实际代码中用到的ES6新增API ,来使用对应的垫片,而不是全部加载进去呢?

是的,有的。那就是 babel-runtime & babel-plugin-transform-runtime,他们可以实现按需加载。

2babel-runtime

简单说 babel-runtime 更像是一种按需加载的实现,比如你哪里需要使用 Promise,只要在这个文件头部

  1. import Promise from 'babel-runtime/core-js/promise' 

不过如果你许多文件都要使用 Promise,难道每个文件都要 import 一下吗?当然不是,Babel 官方已考虑这种情况,只需要使用 babel-plugin-transform-runtime 就可以解决手动 import 的苦恼了。

3babel-plugin-transform-runtime

babel-plugin-transform-runtime 装了就不需要装 babel-runtime了,因为前者依赖后者。

总的来说,babel-plugin-transform-runtime 就是可以在我们使用新 API 时 自动 import babel-runtime 里面的 polyfill,具体插件做了以下三件事情:

1) 当我们使用 async/await 时,自动引入 babel-runtime/regenerator;

2) 当我们使用 ES6 的静态事件或内置对象时,自动引入 babel-runtime/core-js;

3) 移除内联 babel helpers 并替换使用 babel-runtime/helpers 来替换;

babel-plugin-transform-runtime 优点:

1) 不会污染全局变量;

2) 多次使用只会打包一次;

3) 依赖统一按需引入,无重复引入,无多余引入;

4) 避免 babel 编译的工具函数在每个模块里重复出现,减小库和工具包的体积;

使用方式

在 .babelrc 中配置:

  1. plugins:\["tranform-runtime"\] 

打包后大小为 17.4kb,比之前的280kb要小很多。

gulp打包报错 - 问题分析与解决方案

页面 是用gulp起的服务,然后写的代码,这次是在js里用了es7的async/await,导致打包完之后报错:

Uncaught ReferenceError: regeneratorRuntime is not defined

一、原因分析(regeneratorRuntime函数)

在程序中使用了 async/await ,经过@babel/preset-env 解析后会将代码转换为一个名为regeneratorRuntime的函数,但是转换后的代码仅仅存在这个函数的调用,并没有具体的定义体现。

通过百度,好多人会告诉你让你去装一个叫做

  1. 'transform-runtime' 

transform-runtime插件是运行在node服务器上的,所以即使你装了,浏览器照样不认识。

二、解决方案(babel-polyfill编译)

需要的在gulp-babel给你编译的时候,把regeneratorRuntime再转换一次,这就用到了babel的babel-polyfill。

安装完成以后,在node_modules里边找到这个包,然后把dist下的polyfill.min.js这个js引入到页面的head里边去,这样再一次打包的时候,_asyncToGenerator 这个东西就会返回一个函数了,函数浏览器是认识的,再运行一下项目就没问题了。

 

责任编辑:武晓燕 来源: 前端学苑
相关推荐

2021-06-15 05:36:45

Gulpawaitasync

2022-06-13 07:36:47

useEffectHooks

2021-08-18 07:05:57

ES6Asyncawait

2016-10-27 17:05:32

Chrome浏览器

2014-07-15 10:31:07

asyncawait

2016-11-22 11:08:34

asyncjavascript

2021-07-20 10:26:12

JavaScriptasyncawait

2023-10-08 10:21:11

JavaScriptAsync

2012-07-22 15:59:42

Silverlight

2022-08-27 13:49:36

ES7promiseresolve

2023-07-28 07:31:52

JavaScriptasyncawait

2017-11-02 15:26:10

JavaScriptasync错误

2017-04-10 15:57:10

AsyncAwaitPromise

2022-06-16 10:37:09

asyncawait

2017-08-02 14:17:08

前端asyncawait

2014-07-15 10:08:42

异步编程In .NET

2022-11-21 09:01:00

Swift并发结构

2020-03-11 09:15:25

微信asyncawait

2021-06-28 08:10:59

JavaScript异步编程

2024-03-12 08:37:32

asyncawaitJavaScript
点赞
收藏

51CTO技术栈公众号