前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >fis3 新特性应用

fis3 新特性应用

作者头像
IMWeb前端团队
发布2018-01-08 15:59:12
6970
发布2018-01-08 15:59:12
举报
文章被收录于专栏:IMWeb前端团队IMWeb前端团队

本文作者:IMWeb 黎清龙 原文出处:IMWeb社区 未经同意,禁止转载

fis3 新特性应用

1 前言

fis3相比fis2,核心思路并没有改变

还是围绕3个核心做处理:

而整体构建流程也没有做过多的改动。

fis3相对于fis2来说,用户更容易使用,给插件开发者提供更多的能力

这主要体现于以下两点:

  1. 类似css的覆盖式配置方式,不需要用命令行参数来进行配置
  2. 提供许多事件锚点

这篇文章主要介绍的就是第2点,讲解fis3提供的特殊事件,及其作用。

2 lookup:file

fis3 在查找文件资源的时候,通过统一的接口【fis.project.lookup】查找

在该接口里面,会抛出lookup:file事件,看如下注释:

代码语言:javascript
复制
 /**
   * 当查找文件时派送, 可以扩展 fis 默认的查找文件功能。如:支持无后缀文件查找,支持 components 文件查找。
   * @event lookup:file
   * @property {Object} info 包含查找路径信息。
   * @property {File} file 文件对象。
   * @memberOf fis
   */
  fis.emit('lookup:file', info, file);

info参数是一个对象,因此,我们通过监听lookup:file事件来对文件资源的id进行额外处理

fis3-hook-lego是一个fis3 版本的 lego组件系统 包管理的模块查找插件

它的作用是让用户使用lego组件如同使用node组件一样,让系统能够智能的识别lego组件,感兴趣的读者可以深入了解该插件

实际上,fis3-hook-lego的核心原理就是利用了lookup:file事件,看如下源代码:

代码语言:javascript
复制
module.exports = function(fis, opts) {
    fis.on('lookup:file', function(info, file) {
        // 不处理相对路径的文件和已经处理了的文件
        if (file.isJsLike && info.rest && info.rest[0] !== '.' && !info.id) {
            var ret = lookup(info.rest, opts); // 尝试lego模块查找
            if (ret && ret.file) { // 如果找到,则修改id,定位到相应文件
                info.id = ret.file.getId();
                info.file = ret.file;
            }
        }
    });
};

3 proccess:start, proccess:end, release:start, release:end

这4个事件的用意非常明显,fis3的构建流程主要分为2步:每个文件的compile和所有文件的package

以上4个事件就是这两个过程的开始以及结束锚点

这4个关键节点的用处不言而喻,下面笔者举两个例子

3.1 检测构建时间

代码语言:javascript
复制
var timeMap = {};
fis.on('proccess:start', function(file) {
    timeMap[file.id] = +new Date();
});
fis.on('proccess:end', function(file) {
    console.log(file.id, 'compile use:', +new Date() - timeMap[file.id], 'ms');
});
fis.on('release:start', function(file) {
    timeMap['release:'] = +new Date();
});
fis.on('release:end', function(file) {
    console.log('release use:',  +new Date() - timeMap['release:'], 'ms');
});

结果如下:

3.2 缓存清理

在打包过程中,通常我们需要许多复杂的处理,为了提升构建效率,可能我们需要做一些缓存机制

但是,我们需要在构建结束的时候,把这些缓存清掉,否则就会影响下一次构建(在watch的情况下)

这个时候,release:end事件就可以很好的为我们工作:

代码语言:javascript
复制
fis.on('release:end', function() {
    // 每次处理完都需要重置cache
    readCache = {};
});

4 compile:parser, compile:preprocessor, compile:standard, compile:postprocessor, compile:optimizer

以上5个事件是文件compile阶段中5个关键节点的锚点

在每个阶段中,对file进行相应阶段的处理之前,fis3都会先抛出一个事件

这些节点的意义也非常深远,甚至可以改变fis3的compile流程,同样笔者也举两个例子

4.1 不需要两个插件!

因为fis3的构建流程固化了,有时候我们在进行某些处理的时候发现,我们需要在某个操作的前后分别进行处理,比如我要在资源inline替换的前后做某些操作,我们知道inline替换是standard步骤进行的,那么我们可能需要写两个插件,分别是:

fis3-preprocessor-xxx 和 fis3-postprocessor-xxx

我们真的需要吗?

No,通过事件,我们可以只需要一个插件!看如下代码:

代码语言:javascript
复制
// file: fis3-preprocessor-xxx
var conf;

fis.on('compile:postprocessor', function(file) {
    // some process after inline
});

module.exports = function(content, file, settings) {
    // some process before inline
    conf = settings; // save the settings which can be used on postprocessor
};

需要注意以下两点:

  1. 一般我们把插件定义为最开始需要处理的那个阶段插件,否则就无意义了
  2. 因为两个插件组合为一个插件了,所以我们只有一个地方配置参数了,两个插件的参数会组合在一起,这个时候就要好好的组织一下参数格式,并保存起来,以便其他插件使用

有5个事件,所以我们可以把5个插件何在一起!!!

4.2 你可以不孤单!

compile是单文件处理,在这个过程中是拿不到其他文件的,它不像package阶段插件那样,有一个ret参数可以使用

但是,有时候,我们在compile阶段真的需要其他一些文件资源的时候怎么办?

在fis2或者不知道有额外能力的情况下,往往我们会把我们的处理放到package阶段,在这里我们才能找到其他文件,然后做相应处理,然后,可能,你需要蛋疼的重新compile一次该文件(笔者是做过这种事情的)

解决方案是,你可以在compile阶段自己存储所有的文件资源!

请看如下代码:

代码语言:javascript
复制
// file: fis3-parser-xxx
// parse是最早的事件点,所以要定义这个点的插件,详见4.1

var fileMap = {};

fis.on('compile:postprocessor', function(file) {
    var deps = findDepsOfFile(file);

    if (deps.length) { // 需要依赖依赖其他文件
        if (hasAllDepsFile(deps)) {
            // 所有依赖的资源已经compile,现在可以进行处理了!
            process(file);

            // 然后需要看下其他文件是否依赖这个文件
            processIfOtherFileNeedThisFile(file);
        } else {
            // 资源还没到齐,先缓存起来
            fileMap[file.id].deps = deps;
        }
    } else {
        processIfOtherFileNeedThisFile(file);
    }
});

module.exports = function(content, file, settings) {
    // 收集file对象
    fileMap[file.id] = {
        file: file
    };
};

看起来很绕,也确实很绕,在这里只是想让读者知道,可以这样子处理

这样处理已经违背了fis3的核心理念,慎用!

后续

可以看到,fis3最重大的改进就是提供了更多的想象空间给插件开发者

合理利用这些特性,我们可以在fis3的环境下做许多事情

但就只有这些吗?

No!还有另外一些更加有趣更加开放的特性还没介绍。

敬请期待下一期!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • fis3 新特性应用
    • 1 前言
      • 2 lookup:file
        • 3 proccess:start, proccess:end, release:start, release:end
          • 3.1 检测构建时间
          • 3.2 缓存清理
        • 4 compile:parser, compile:preprocessor, compile:standard, compile:postprocessor, compile:optimizer
          • 4.1 不需要两个插件!
          • 4.2 你可以不孤单!
        • 后续
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档