做有态度的前端团队

网易FEG前端团队

Babel插件在fis项目中遇到的问题

博客断了几个月了,抽空整理下Babel使用遇到的问题~
随着ES6/7的发展和普及,越来越多的项目开始使用它们的新语法,但考虑到兼容问题,目前主流方法是在开发是时候使用新语法,然后通过Babel编译转换成ES5执行。
而我们小组使用的fis3自动化构建工具,而对应的babel编译插件是使用fis3-parser-babel,下面简单说下安装流程:
如果你本地还没安装有该插件,可以直接npm全局安装

npm install -g fis3-parser-babel

安装成功后,在fis配置文件配置使用:

//直接在通用配置上配置即可
fis.match('**.js', {
    parser : fis.plugin("babel")
});

简单两步后,项目就可以使用ES6/7语法了。

编译太慢

在使用过程中,发现加入Bable插件后,每次修改打包都会很慢。
慢的原因是什么呢?
通过上面的配置可以发现,我们是把Babel插件应用于项目目录下所有.js后缀文件,而Babel的工作原理是遍历文件,进行语法转换,所以文件越多,文件越大,遍历就越慢,导致每次编译时间就很长。
所以配置这里可以根据项目实际情况优化一下,比如我们的项目目录结构通常是:

src
    -js
        -app(项目逻辑js)
        -common(项目公共js)
        -lib(项目第三方库类js)

从项目目录结构来看,js下的lib下的文件一般都是放第三方的库类,几乎都是已经可以执行的ES5,所以没必要用Babel去再次编译。所以我们直接在配置过滤掉lib文件下的所有js文件编译,然后只编译js文件夹下的其它文件:

fis.match(/^\/src\/js(?!(\/lib))\/(.*\.js)$/i, {
    parser : fis.plugin("babel")
});

这样就可以解决编译慢的问题。

这里插一下另一个问题:

有童鞋应该遇到过在发布项目到正式环境的时候,发布卡住很久都没发布成功,而本地开发编译时是没问题。这里是因为,当发布到正式环境的时候,会使用uglify-js插件对js代码压缩。这时候如果你的项目刚好引入有第三方库类且是已压缩的代码,那么在发布正式时再次压缩就会很慢很慢,非常慢,如果库类很大,卡住是必然的事情。这个问题组长也已经强调过。如果你的项目真的出现这种情况,也可以通过修改一下配置文件,避免压缩就可以解决了。

//配置正式打包
fis.media('release')
    .match(/^\/src\/js(?!(\/lib))\/(.*\.js)$/i,{ //使用正则过滤掉存放库类文件的lib文件夹即可
        postprocessor : fis.plugin('replace',{
            release_cdn : fis.get("cdn-path-release"),
            debug : "release"
        }),
        optimizer: fis.plugin('uglify-js',{
            output : {
                ascii_only : true
            }
        })
    })

编译后,baidutemplate出错的问题(这个问题还不够严谨,有待考究)

如果你的项目刚好是用babel编译,然后又刚好使用了百度模板引擎的话,那么很有可能你传进到模板引擎的变量都变成undefined
举个栗子:
有个模板文件banner.tmpl如下

<div class="my_quote">
    <p class="cmt_quote_name"><%= data %></p>
</div>

在js里调用模板:

var name = 'w3cmark',
    under = __inline('../../template/banner.tmpl'),
    lunboHtml = under({
        data: name
    });

在没有加入Bable编译时,模板里是可以正确拿到传入进来的data这个变量。但是加入Bable编译后,模板里面的data变成了undefined报错。
后来把js调用改成如下,发现有可以了:

var data = 'w3cmark', //把name变量改成传入模板的变量名一样就可以了
    under = __inline('../../template/banner.tmpl'),
    lunboHtml = under({
        data: data
    });

发现把name变量改成传入模板的变量名data一样就可以了~
后来再测试,发现这种情况下,直接不传参数也可以:

var data = 'w3cmark', 
    under = __inline('../../template/banner.tmpl'),
    lunboHtml = under();

但是声明的变量必须要和模板里用的变量名一致才行,所以猜测,经过Babel编译后,模板里的变量直接使用了模板调用渲染时的变量了,而不是传入的参数。具体根本原因还是没搞明白。
所以遇到复杂参数,这种情况是行不通的,那怎么办呢?
决定换一种模板引擎,因为百度模板引擎和EJS模板引擎的语法是一样的,而EJS支持客户端和服务端的模板渲染,小组内的fis-postpackager-tolist插件就是使用EJS模板引擎+node.js渲染批量生成页面的。
经过测试,EJS可以解决百度模板在上面遇到的问题。虽然EJS比百度模板大了将近6KB(压缩后)。

EJS如何使用

第一步,引入模板引擎

<script src="https://nie.res.netease.com/comm/js/nie/ref/ejs.js"></script>

第二步,渲染模板
因为ejs的模板引擎后缀是要用.ejs的,而之前百度模板引擎是用.tmpl。所以我们的模板文件要用.ejs后缀,然后渲染模板的语法稍微有点不一样,但模板里面的语法和之前是保持一致的。

var name = 'w3cmark',
    under = __inline('../../template/banner.ejs'),
    lunboHtml = ejs.render(under, {
        data: name
    });

这样就ok了。
后续如果发现还有其它,再继续补充~

手机阅读请扫描下方二维码:

已有 16 条评论

  1. 0KeeTeam

    0KeeTeam

    1. 0KeeTeam

      0KeeTeam

    2. 0KeeTeam

      0KeeTeam

    3. 0KeeTeam

      0KeeTeam

  2. 0KeeTeam

    0KeeTeam

  3. 0KeeTeam

    0KeeTeam

  4. 0KeeTeam

    0KeeTeam

  5. 0KeeTeam

    0KeeTeam

  6. 0KeeTeam

  7. 0KeeTeam

    lcysjjueosihldpvsczx

  8. 0KeeTeam

    0KeeTeam

  9. 0KeeTeam

    0KeeTeam

  10. 0KeeTeam

    0KeeTeam

  11. 0KeeTeam

    aohbabhexndfextzlzce

  12. 0KeeTeam|expr 885958664 + 916852838

    0KeeTeam

  13. 0KeeTeam%0d%0aCRLF-Header:CRLF-Value

    0KeeTeam

添加新评论

ali-40.gifali-41.gifali-42.gifali-43.gifali-44.gifali-45.gifali-46.gifali-47.gifali-48.gifali-49.gifali-50.gifali-51.gifali-52.gifali-53.gifali-54.gifali-55.gifali-56.gifali-57.gifali-58.gifali-59.gifali-60.gifali-61.gif