NodeJS项目中如何优雅地使用ES6NodeJs最近的版本已经开始支持ES6(ES2015)的新特性,设置中已经支持async/await等更高级的特性。只是使用的时候需要在node后面加一个参数:--harmony。然而,即便如此,node仍然不支持所有ES6特性。所以这个时候就需要用到Babel了。项目地址:https://github.com/future-cha...现在启动Babel在开始使用Babel之前,假设你已经安装了nodejs并且已经熟悉了Js。您还可以使用npm安装各种依赖项。并且你对ES6(后来改为ES2015)也有一定程度的熟悉。它还假定您已经安装了yarn并且熟悉yarn。Yarn最大的优势就是比npm快很多,因为yarn只下载一次需要的库,后面使用的时候直接使用本地缓存的版本。npm每次都会下载这些库。这简直是??在浪费生命。如果你还没有安装yarn,没关系,下面也会有npm的使用方法。接下来,安装和配置Babel。安装babel-cliyarnaddbabel-cli--dev//npminstall--save-devbabel-cli安装babel预设。yarnaddbabel-preset-es2015--dev//npminstall--save-devbabel-preset-es2015此时就可以使用ES2015的特性了。然而,这还不够。例如,我不想使用Promise,我想使用更方便的async/await语法。只有es2015预设是不够的。Babel的插件和presetBabel本身不处理语言特性的转码。这些功能是通过plugin和preset(preset也是插件的集合)来实现的。上面说了,要使用es2015的内容,需要安装预设的babel-preset-es2015。使用async/await需要安装相应的preset或插件。为简单起见,我们安装预设:babel-preset-stage-0。presetstage-0包含async/await相关插件:babel-plugin-syntax-async-functions、babel-plugin-transform-regenerator。yarnaddbabel-preset-stage-0--dev//npminstall--save-devbabel-preset-stage-0还是不能在项目中使用es7的async/await。需要更多配置,有两种方法:使用babel-polyfill。有一个不好的地方,babel-polyfill会污染全局对象,所以不适合像library那样使用。仅适用于网络应用程序使用。使用babel运行时转码工具,即transform-runtime插件。使用这种方法正好弥补了上述方法的不足。特别适用于图书馆等项目。这两种方法分别介绍。安装babel-polyfill:yarnaddbabel-polyfill--dev//npminstall--save-devbabel-polyfill,在项目入口文件的顶部导入babel-polyfill。比如我现在有一个ExpressWebApp,那么入口文件就是打开app的index.js文件。在这个文件的顶部引入polyfill,require('babel-polyfill')。或者你的入口文件已经是ES2015写的,那就直接import吧,import'babel-polyfill'。使用transform-runtime也非常简单。安装:yarnaddbabel-plugin-transform-runtime--dev//npminstall--save-devbabel-plugin-transform-runtime还需要安装babel-runtime:yarnaddbabel-runtime//npminstall--savebabel-runtime之后,在.babelrc文件中添加如下配置,可以二选一://withoutoptions{"plugins":["transform-runtime"]}//withoptions{"plugins":[["transform-runtime",{"helpers":false,//默认为true"polyfill":false,//默认为true"regenerator":true,//默认为true"moduleName":"babel-runtime"//默认为"babel-runtime"}]]}剩下的就是愉快地使用async/await。另外,如果想使用Object.assing之类的方法,也可以使用一个插件:babel-plugin-transform-object-assign,如果想使用解构赋值,可以使用一个插件:babel-plugin-变换对象静止传播。当然,这些都包含在stage-0预设中。现在开始编写ES2015代码。在项目中安装ExpressJs并创建一个index.js文件。让我们尝试创建一个小型网络应用程序作为练习:importExpressfrom'express'letapp=Express()app.get('/',(req,res)=>{res.send('helloworld')})app.listen(8080,()=>console.log('serverisrunningathttp://localhost:8080'))runcommand:./node_modules/.bin/babel-nodeindex.js--presetes2015,stage-0使用命令babel-node*让代码跑起来,后面的参数指定了js代码转义时使用的preset和plugin。Babel官方推荐的方法是使用.babelrc文件,这样可以更加灵活。在项目目录下新建一个.babelrc文件,在里面添加你安装的preset和plugin的描述:{"presets":["es2015","stage-0"]}这样就可以直接使用babel了-node执行代码,或者使用命令babel来转义代码。例如:babel-wcode/-dbuild/babel命令会从配置文件中读取配置,对code/目录中的文件进行变异,并将转义后的JavaScript文件导出到build/目录中。命令行中还有参数-w。此命令参数指定手表。每次修改代码目录下的文件,都会触发babel命令的重新执行。在上面的文件中使用SourceMaps看起来很棒。但是还有一个问题。当你调试代码的时候,你调试的其实是babel命令转码后的js,而不是你写的原始源码所在的文件。调试不是源文件,会有些不方便。例如下面的文件会抛出异常:asyncfunctionerrorAsyncFunc(){try{thrownewError('Asyncfunctionerror')}catch(e){throwe}}errorAsyncFunc()添加一个--source-maps即可解决这个问题:babelcode/-dbuild/--source-maps最后在package.json中添加scripts节点:"scripts":{"build":"babelsrc-dbuild--source-maps","start":"nodebuild/index.js"},Next:npmrunbuildGulp登场以上介绍了如何使用Babel实现ES201x开发。但是在正式开发中,上面的配置还是有点不足,尤其是如果你的项目包含web端和server端,尤其是web端不仅处理ES201x代码还需要处理。所以Gulp需要发挥作用。这个东西看着复杂,你自己定义编译过程。其实掌握之后还是很有用的,尤其是可以自动处理很多东西,节省很多时间。要使用Gulp,必须先安装NodeJS。这基本上是标准的。然后您将使用它的命令行工具。安装Gulp最新版本的Gulp中有一些调整。gulp-cli从gulp中分离出来,作为一个单独的部分使用。所以,如果你已经安装了之前版本的gulp,你需要先将其删除:-devmode--dev//npminstall--save-devgulp创建一个gulp配置文件就像Babel使用.babelrc作为配置文件一样,gulp也需要一个配置文件。这个配置文件是gulpfile.js,但是和babel一起使用的时候,把gulpfile.js重命名为gulp.babel.js:mv"gulpfile.js""gulpfile.babel.js"gulp的使用还是很简单的,主要是就是在gulpfile.babel.js文件中添加各种任务。在这些任务中,必须添加一个名为default的任务,gulp命令的执行起点从这里开始。假设有这样一个场景:使用eslint检查代码,发现代码风格和潜在的错误。自动实现ES201x->ES5代码转码,并将转码后的代码放在指定目录下。转码时添加sourcemaps。以上所有的“任务”都是用gulp自动实现的。如何配置?当gulp和eslint想要在gulp中使用类似于eslint的各种功能时,需要使用gulp上相应的插件。没错,gulp的设计思路和gulp基本一致:插件机制。然后我们需要先下载eslint插件:yarnadd--devgulp-eslint//npminstall--save-devgulp-eslint在我们开始编写我们的第一个任务之前,做最后的准备工作。首先你需要配置.eslintrc文件。eslint会根据这个文件定义的规则来检查代码的风格。我们没有准备大量的配置规则,这样非常耗时,也没有照顾到我们项目保留的很多编码风格。所以,使用airbnb的一套规则,最好的办法就是使用。安装eslintyarnadd--deveslint//npminstall--save-deveslint然后就可以运行命令初始化配置:./node_modules/.bin/eslint--init。您也可以忽略此命令,直接创建.eslintrc文件。安装eslint的airbnb扩展要使用airbnb的一套规则,需要安装他们的eslint扩展:yarnaddeslint-config-airbnb--dev//npminstall--save-deveslint-config-airbnb命令会提示一些依赖项是未安装,即eslint-plugin-import@^2.2.0、eslint-plugin-import@^2.2.0、eslint-plugin-jsx-a11y@^3.0.2。只需一一安装这些依赖项即可。.eslintrc{"env":{"es6":true},"rules":{"semi":"off","import/no-extraneous-dependencies":["error",{"devDependencies":true,"optionalDependencies":false,"peerDependencies":false}],"quotes":["error","single",{"allowTemplateLiterals":true}]},"extends":"airbnb"}env指定环境支持在es6中,rules指定了一些补充内容,比如字符串是使用单引号还是双引号。这个根据个人喜好配置,你可以选择添加你需要的规则。最后是extends,这里配置airbnb使用airbnb的一套eslint编码检查规则。使用gulp-eslint插件importgulpfrom'gulp'importeslintfrom'gulp-eslint//配置待处理的文件目录和转码文件的存放目录constparamConfig={source:'src/**/*.js',dest:'build',}导入相关模块后开始编写任务:gulp.task('lint',()=>{//eslint配置,使用配置的文件目录。排除node_modules下的所有文件。returngulp.src([paramConfig.source,'!node_modules/**']).pipe(eslint()).pipe(eslint.result(result=>{console.log(`ESLint结果:${result.filePath}`);console.log(`#Messages:${result.messages.length}`);console.log(`#Warnings:${result.warningCount}`);console.log(`#Errors:${result.errorCount}`);})).pipe(eslint.format()).pipe(eslint.failOnError())})上面说了需要默认任务:gulp.task('default',['lint'],function(){//lint任务执行成功后执行该方法});跳转到项目目录并运行gulp命令。将获得以下输出:$gulp[21:43:01]Requiringexternalmodulebabel-register[21:43:01]Usinggulpfile~/Documents/test-polyfill/gulpfile.babel.js[21:43:01]开始'lint'...[21:43:02]开始'babel-sourcemaps'...ESLint结果:~/Documents/test-polyfill/src/index.js#消息:0#警告:0#错误:0ESLint结果:~/Documents/test-polyfill/src/test.js#消息:0#警告:0#错误:0[21:43:02]605毫秒后完成“lint”[21:43:02]在653毫秒后完成“babel-sourcemaps”[21:43:02]开始“默认”...gulp默认任务![21:43:02]在98μsgulp和babel处理babel和sourcemaps后完成“默认”时间问题。首先安装插件:yarnadd--devgulp-babel//npminstall--save-devgulp-babelimportgulp-babel插件:importbabelfrom'gulp-babel'importsourcemapsfrom'gulp-sourcemaps'添加任务:囫囵吞枣。task('babel-sourcemaps',()=>{returngulp.src(paramConfig.source).pipe(sourcemaps.init()).pipe(babel()).pipe(sourcemaps.write('.')).pipe(gulp.dest(paramConfig.dest))})修改默认任务:gulp.task('default',['lint','babel-sourcemaps'],()=>{console.log('gulp默认任务!')})如果你不想使用sourcemaps,你可以这样写:gulp.task('babel',()=>{returngulp.src(paramConfig.source).pipe(babel()).pipe(gulp.dest(paramConfig.dest))})把gulp放到npm命令系统下。babel早就配置好了,现在配置gulp。gulp每次输入命令时,基本上都是手动执行。是时候让这个命令半自动执行了。修改package.json文件,在里面添加scripts节点:"scripts":{"build":"gulp","start":"nodebuild/index.js"},这样很多命令就可以像gulp一样了同样在npm的脚本中执行。例如,现在可以在命令行中输入如下命令来实现lint和babel转码:npmrunbuild开始执行:npmstart总结使用bebel可以提前使用最新的JavaScript语言特性,这样写很多代码就会变得简洁高效。而且babel转码后生成的代码也是非常规范的ES5写法,同时是严格模式。因此,我们不需要添加'usestrict';编写ES201x代码时的标志。使用gulp可以自动处理很多小而耗时的事情。将两者结合起来,将大大提高您的项目开发效率。那么,看到这里,是不是觉得应该赶紧在自己的项目中使用这些技术,让开发进入快车道呢!!!???
