当前位置: 首页 > Web前端 > HTML5

前面写了Babel

时间:2023-04-05 01:05:59 HTML5

的使用说明,了解babel存在的意义。babel的出现是为了解决es语言不同运行环境的差异,主要包括2类,语法翻译和特性支持。本文主要介绍babel7,后续所有模块包均以@bable开头。主要思路举个栗子:你是餐厅老板,有位顾客来你店里点了一份外卖牛排,然后你做了,送到他住处。那么完成这件事需要几个步骤:客户下单的时候,你把生牛肉放上去,准备点缀品,准备调料刀,按照客户的要求添加点缀品和调味品,然后发货10分钟熟牛肉一次操作送到客人面前。大致是这样,先记住这个栗子,我们继续往下看。主模块包@babel/cli@babel/preset-env@babel/polyfill@babel/core@babel/plugin-transform-xxx(其他插件)@babel/runtime@babel/plugin-transform-runtime@babel/plugin-transform-arrow-functionsOthers@babel/cli@babel/cli是babel提供的内置命令行工具,主要提供babel命令编译js文件。这里要注意它和另一个命令行工具@babel/node的区别。首先我们要知道它们都是命令行工具,但是官方文档明确定义了它们各自的使用范围:@babel/cli是一个适合安装在本地项目中提供babel命令的,@babel/node是提供babel-node命令的全局安装。将这个包安装到开发依赖中,可以在当前项目中使用babel命令,可以添加参数,将翻译后的代码输出到目标文件中执行。/node_modules/.bin/babelsrc/testItems/babel--out-dirsrc/testItems/dist或npxbabelsrc/testItems/babel--out-dirsrc/testItems/dist会发现文件夹dist及其索引。testItems下会生成js文件,内容如下console.log([1,2,3].findIndex(x=>x==4));constalertMe=msg=>{console.log(msg);};呵呵,和我的源码一样,使用有问题!!!别着急,那是因为我们没有对源码做相应的处理,就像做牛肉一样,不能给客户一盘生牛肉,是时候备好材料开始拿刀了!@babel/preset-env先来看一个简单的例子,这里@babel/core会讲constbabel=require("@babel/core");babel.transform(`console.log([1,2,3].findIndex(x=>x==4))constalertMe=(msg)=>{console.log(msg)}`,{plugins:["@babel/plugin-transform-arrow-functions"]},函数(错误,结果){console.log(结果);});执行nodesrc/testItems/babel/index.js让我们运行看看输出\\我的项目\\bq-test',root:'d:\\myproject\\bq-test',plugins:[[Plugin]],presets:[],parserOpts:{sourceType:'module',sourceFileName:undefined,plugins:[]},generatorOpts:{文件名:undefined,auxiliaryCommentBefore:undefined,auxiliaryCommentAfter:undefined,retainLines:undefined,comments:true,shouldPrintComment:undefined,compact:'auto',minified:undefined,sourceMaps:false,sourceRoot:undefined,sourceFilenName:}unk}':null,代码:'console.log([1,2,3].findIndex(function(x){\nreturnx==4;\n}));\n\nconstalertMe=function(msg){\n控制台。log(msg);\n};',map:null,sourceType:'module'}可以看出这里的箭头函数已经翻译过了,就是@babel/plugin-transform-arrow-functions的效果但是在我们实际的开发中,会用到更多的新语法。我们不能一个一个添加插件。这里我们可以看一下@babel/preset-env这个插件,简单的说就是“preset”,是什么意思呢?大致意思是官方为我们准备的插件合集(包括@bable/preset-es2015、@bable/preset-es2016、@bable/preset-es2017),修改代码如下,得到相同的输出constbabel=要求(“@babel/核心”);babel.transform(`console.log([1,2,3].findIndex(x=>x==4))constalertMe=(msg)=>{console.log(msg)}`,{预设:[["@babel/preset-env",{targets:{node:"4"}}]]//plugins:["@babel/preset-env"]},function(err,result){console.log(result);});@babel/polyfill让我们仔细看看这里的代码:'console.log([1,2,3].findIndex(function(x){\nreturnx==4;\n}));\n\nconstalertMe=function(msg){\nconsole.log(msg);\n};',map:null,你会发现除了箭头之外,函数被翻译了,findIndex方法没有改变。为什么?这是对语法和功能之间差异的理解。语法指的是箭头函数等编码方式,特性指的是标准的API。后者需要@babel/polyfill来解析。请注意,使用--save参数而不是--save-dev,因为这是一个需要在源代码之前运行的polyfill。与@babel/preset-env一起使用时,如果在.babelrc中指定useBuiltIns:'usage',则不要在webpack.config.js的入口数组和源中包含@babel/polyfill。请注意,@babel/polyfill仍然需要安装。如果在.babelrc中指定了useBuiltIns:'entry',那么如上所述,通过require导入@babel/polyfill或在应用程序的入口文件顶部导入。如果在.babelrc中没有指定useBuiltIns的值或者设置useBuiltIns:false。可以直接在webpack.config.js的entry数组中添加@babel/polyfillmodule.exports={entry:['@babel/polyfill','./app']}如果没有使用@babel/preset-env,然后可以将@babel/polyfill添加到我们上面讨论的webpack的入口数组中。您也可以通过import或require将其直接添加到应用程序入口文件的顶部。但是我们不建议这样做@babel/core@babel/core是babel的核心包,起到翻译的作用,也就是我们前面说的那把刀。主要方法是transform等。简单尝试一下:将下面的配置文件添加到Compilewiththebabel命令。创建配置文件babel.config.js有几种方式在项目根目录(package.json文件所在目录)创建一个名为babel.config.js的文件,输入如下内容。module.exports=function(api){api.cache(true);常量预设=[...];const插件=[...];return{presets,plugins};}.babelrc在名为.babelrc的项目文件中创建,内容如下。{"presets":[...],"plugins":[...]}package.json或者,你也可以选择将.babelrc中的配置信息作为babel键(key)的值添加到package.json文件,像这样:{"name":"my-package","version":"1.0.0","babel":{"presets":[...],"plugins":[...],}}.babelrc.js和.babelrc是一样的配置,但是可以用JavaScript写。常量预设=[...];const插件=[...];module.exports={预设,插件};这里使用第一种配置方式module.exports=function(api){api.cache(true);constpresets=[["@babel/preset-env",{"targets":{"node":"2",},"corejs":"3","useBuiltIns":"usage"}]];返回{预设};};说明:targets指定了兼容的运行环境,即这里编译的代码可以运行在node版本为2的node环境中。使用"useBuiltIns":"usage"表示@bable/polyfill其他插件会使用@babel/插件转换运行时“预设”:[[“@babel/preset-env”,{“目标”:{“节点”:“4”}}}]],“插件”:[“@babel/插件转换-runtime"]}编译后的代码"usestrict";var_interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");require("core-js/modules/es.array.find-index");var_classCallCheck2=_interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));var_createClass2=_interopRequireDefault(require("@babel/运行时/助手/createClass"));vartestClass=/*#__PURE__*/function(){functiontestClass(msg){(0,_classCallCheck2.default)(this,testClass);this.message=msg;}(0,_createClass2.default)(testClass,[{key:"say",value:functionsay(){alertMe(this.message);}}]);返回testClass;}();console.log([1,2,3].findIndex(function(x){returnx==4;}));varalertMe=functionalertMe(msg){console.log(msg);};你会发现更通用的方法比如createClass有已经提出了当然还有其他的插件可以减少重复代码,这里就不一一列举了,最后我们回顾一下开头的栗子做个总结:@babel/cli是订单请求客户下发的,也是代码当前项目运行指令的来源,代码以生牛肉为输入@bable/preset-env(以及其他一些预设的包集合)是点缀项,改变了原来的表达形式代码@bable/polyfill是调味料,提供功能补充的源码@bable/core是不是很合适操作或者其他一些操作工具再结合一些其他插件如@babel/plugin-transform-runtime等插件生成10点兼容的编译代码。帮助自己理解和记忆不是很合适