零配置

不使用任何配置,fis将支持:

  • 使用 fis install 命令安装fis仓库提供的各种 组件、框架、示例、素材、配置等 开发资源。
  • 使用 fis server start 命令启动一个本地调试服务器,完美支持php后端程序
  • 使用 fis release –dest ./output –md5 命令为所有静态资源文件(js、css、图片、flash等)添加md5戳,并修改文件中的引用路径
  • 使用 fis release –dest ./output –optimize 命令对js、css、html、htm文件进行压缩(后续还会加上对图片的自动压缩)
  • 编译中对 js、 css 以及 类html ( html, htm, xhtml, tpl, php, jsp, asp ) 文件分别支持三种扩展语言能力:
    • 资源定位:获取任何开发中所使用资源的线上路径;
    • 内容嵌入:把一个文件的内容(文本)或者base64编码(图片)嵌入到另一个文件中;
    • 依赖声明:在一个文本文件内标记对其他文件的依赖关系;

以上功能可满足传统前端开发所需的基本要求

使用配置文件

在项目目录下新建一个 fis-conf.js 文件,我们可以对fis的编译系统做各种定制化配置。配置fis系统的接口是:

fis.config.set(key, value); 或者

fis.config.merge({...}); 由于fis自动化工具采用nodejs作为平台,因此其配置文件也是js书写的。fis变量是全局注册,config属性是fis系统的配置对象实例,merge或set方法用以合并配置数据。

内置的默认配置

由于fis系统是完全插件化的,因此fis.config对象会有一些内置配置用以为用户提供零配置下的基本功能,所以配置文件中使用fis.config.merge 或者 fis.config.set 接口来追加用户配置。而内部初始化的配置数是:

fis.config.init({
    project : {
        charset : 'utf8',
        md5Length : 7
    }
});

项目配置

配置项 project

fis.config.set('project.charset', 'gbk');
或者

fis.config.merge({
    project : { charset : 'gbk' }
});
fis.config.set('project.md5Length', 8);
或者

fis.config.merge({
    project : { md5Length : 8 }
});
fis.config.set('project.md5Connector ', '.');
或者

fis.config.merge({
    project : { md5Connector : '.' }
});
fis.config.set('project.include', 'src/**');
或者

fis.config.merge({
    project : { include : 'src/**' }
});
或者

fis.config.set('project.include', ['src/**', /^\/vendor\//i]);
fis.config.set('project.exclude', /^\/_build\//i);
或者

fis.config.merge({
    project : { exclude : /^\/_build\//i }
});
或者

fis.config.set('project.exclude', ["dist/**", /^\/_build\//i]);
fis.config.set('project.fileType.text', 'tpl, js, css');
或者

fis.config.merge({
    project : {
        fileType : {
            text : 'tpl, js, css'
        }
    }
});
fis.config.set('project.fileType.image', 'swf, cur, ico');
或者

fis.config.merge({
    project : {
        fileType : {
            image : 'swf, cur, ico'
        }
    }
});
fis.config.set('project.watch.exclude', 'node_modules');
或者

fis.config.set('project.watch.exclude', ['node_modules', /docs/]);
fis.config.set('project.watch.usePolling', true);

插件配置

配置项 modules

fis系统有非常灵活的插件扩展能力,详细内容请参看 运行原理插件调用机制插件扩展点列表等文档。 fis所有的插件配置都支持定义一个 数组或者逗号分隔的字符串序列 来依次处理文件内容。

//fis-conf.js
fis.config.merge({
    modules : {
        parser : {
            //coffee后缀的文件使用fis-parser-coffee-script插件编译
            coffee : 'coffee-script',
            //less后缀的文件使用fis-parser-less插件编译
            //处理器支持数组,或者逗号分隔的字符串配置
            less : ['less'],
            //md后缀的文件使用fis-parser-marked插件编译
            md : 'marked'
        }
    },
    roadmap : {
        ext : {
            //less后缀的文件将输出为css后缀
            //并且在parser之后的其他处理流程中被当做css文件处理
            less : 'css',
            //coffee后缀的文件将输出为js文件
            //并且在parser之后的其他处理流程中被当做js文件处理
            coffee : 'js',
            //md后缀的文件将输出为html文件
            //并且在parser之后的其他处理流程中被当做html文件处理
            md : 'html'
        }
    }
});
fis.config.set('modules.preprocessor.css', 'image-set');
或者

//fis-conf.js
fis.config.merge({
    modules : {
        preprocessor : {
            //css后缀文件会经过fis-preprocessor-image-set插件的预处理
            css : 'image-set'
        }
    }
});
类似 modules.preprocessor
fis.config.set('modules.lint.js', 'jshint');
或者

//fis-conf.js
fis.config.merge({
    modules : {
        lint : {
            //js后缀文件会经过fis-lint-jshint插件的代码校验检查
            js : 'jshint'
        }
    }
});
fis.config.set('modules.test.js', 'phantomjs');
或者

//fis-conf.js
fis.config.merge({
    modules : {
        test : {
            //js后缀文件会经过fis-test-phantomjs插件的测试
            js : 'phantomjs'
        }
    }
});
fis.config.set('modules.optimizer.js', 'uglify-js');
或者

//fis-conf.js
fis.config.merge({
    modules : {
        optimizer : {
            //js后缀文件会经过fis-optimizer-uglify-js插件的压缩优化
            js : 'uglify-js'
        }
    }
});
fis.config.set('modules.prepackager', 'oo, xx');
或者

//fis-conf.js
fis.config.merge({
    modules : {
        //打包前调用fis-prepackager-oo和fis-prepackager-xx插件进行处理
        prepackager : 'oo, xx'
    }
});
fis.config.set('modules.packager', 'your_packager');
或者

//fis-conf.js
fis.config.merge({
    modules : {
        //打包调用fis-packager-your_packager插件进行处理
        packager : 'your_packager'
    }
});
fis.config.set('modules.spriter', 'your_spriter');
或者

//fis-conf.js
fis.config.merge({
    modules : {
        //打包后调用fis-spriter-your_spriter插件进行css sprites化处理
        spriter : 'your_spriter'
    }
});
fis.config.set('modules.postpackager', 'your_postpackager');
或者

//fis-conf.js
fis.config.merge({
    modules : {
        //打包后调用fis-postpackager-your_postpackager插件进行处理
        postpackager : 'your_postpackager'
    }
});

插件运行配置

fis.config.set('settings.optimizer.uglify-js.output.max_line_len', 500);
fis.config.set('settings.optimizer.clean-css.keepBreaks', true);
或者

//fis-conf.js
fis.config.merge({
    settings : {
        optimizer : {
            //fis-optimizer-uglify-js插件的配置数据
            'uglify-js' : {
                output : {
                    max_line_len : 500
                }
            },
            //fis-optimizer-clean-css插件的配置数据
            'clean-css' : {
                keepBreaks : true
            }
        }
    }
});

内置插件运行配置

fis.config.set('settings.postprocessor.jswrapper.template', 'try{ ${content} }catch(e){e.message+="${id}";throw e;}');
或者

fis.config.merge({
    settings : {
        postprocessor : {
            jswrapper : {
                template : 'try{ ${content} }catch(e){ e.message += "${id}"; throw e; }'
            }
        }
    }
});
//配置字符串全部转换为ascii字符
fis.config.set('settings.optimizer.uglify-js.output.ascii_only', true);
或者

//配置字符串全部转换为ascii字符
fis.config.merge({
    settings : {
        optimizer : {
            'uglify-js' : {
                output : {
                    ascii_only : true
                }
            }
        }
    }
});
//配置压缩css时保留换行
fis.config.set('settings.optimizer.clean-css.keepBreaks', true);
或者

//配置压缩css时保留换行
fis.config.merge({
    settings : {
        optimizer : {
            'clean-css' : {
                keepBreaks : true
            }
        }
    }
});
//使用pngquant进行压缩,png图片压缩后均为png8
fis.config.set('settings.optimizer.png-compressor.type', 'pngquant');
或者

//使用pngquant进行压缩,png图片压缩后均为png8
fis.config.merge({
    settings : {
        optimizer : {
            'png-compressor' : {
                type : 'pngquant'
            }
        }
    }
});
//使用矩阵布局
fis.config.set('settings.spriter.csssprites.layout', 'matrix');
或者

//使用矩阵布局
fis.config.merge({
    settings : {
        spriter : {
            csssprites : {
                layout : 'matrix'
            }
        }
    }
});

目录规范与域名配置

配置项 roadmap

fis.config.merge({
    roadmap : {
        path : [
            {
                //所有widget目录下的js文件
                reg : 'widget/**.js',
                //是模块化的js文件(标记为这种值的文件,会进行amd或者闭包包装)
                isMod : true,
                //默认依赖lib.js
                requires : [ 'lib.js' ],
                //向产出的map.json文件里附加一些信息
                extras : { say : '123' },
                //编译后产出到 /static/widget/xxx 目录下
                release : '/static$&'
            },
            {
                //所有的js文件
                reg : '**.js',
                //发布到/static/js/xxx目录下
                release : '/static/js$&'
            },
            {
                //所有的ico文件
                reg : '**.ico',
                //发布的时候即使加了--md5参数也不要生成带md5戳的文件
                useHash : false,
                //发布到/static/xxx目录下
                release : '/static$&'
            },
            {
                //所有image目录下的.png,.gif文件
                reg : /^\/images\/(.*\.(?:png|gif))/i,
                //访问这些图片的url是 '/m/xxxx?log_id=123'
                url : '/m/$1?log_id=123',
                //发布到/static/pic/xxx目录下
                release : '/static/pic/$1'
            },
            {
                //所有template目录下的.php文件
                reg : /^\/template\/(.*\.php)/i,
                //是类html文件,会进行html语言能力扩展
                isHtmlLike : true,
                //发布为gbk编码文件
                charset : 'gbk',
                //发布到/php/template/xxx目录下
                release : '/php/template/$1'
            },
            {
                //前面规则未匹配到的其他文件
                reg : /.*/,
                //编译的时候不要产出了
                release : false
            }
        ]
    }
});
//fis-conf.js
fis.config.merge({
    roadmap : {
        ext : {
            //less后缀的文件将输出为css后缀
            //并且在parser之后的其他处理流程中被当做css文件处理
            less : 'css',
            //coffee后缀的文件将输出为js文件
            //并且在parser之后的其他处理流程中被当做js文件处理
            coffee : 'js',
            //md后缀的文件将输出为html文件
            //并且在parser之后的其他处理流程中被当做html文件处理
            md : 'html'
        }
    }
});
//fis-conf.js
//用法一
fis.config.merge({
    roadmap : {
        //所有静态资源文件都使用 http://s1.example.com 或者 http://s2.example.com 作为域名
        domain : 'http://s1.example.com, http://s2.example.com'
    }
});
//用法二
fis.config.merge({
    roadmap : {
        domain : {
            //widget目录下的所有css文件使用 http://css1.example.com 作为域名
            'widget/**.css' : 'http://css1.example.com',
            //所有的js文件使用 http://js1.example.com 或者  http://js2.example.com 作为域名
            '**.js' : ['http://js1.example.com', 'http://js2.example.com']
        }
    }
});
编译时使用fis release的 --domains 参数来控制是否添加domain
fis release --domains --dest ../output
//fis-conf.js
fis.config.merge({
    roadmap : {
        domain : {
            //所有图片文件,使用 http://img.example.com 作为域名
            'image' : ['http://img.example.com']
        }
    }
});
编译时使用fis release的 --domains 参数来控制是否添加domain
fis release --domains --dest ../output

部署配置

//fis-conf.js
fis.config.merge({
    deploy : {
        //使用fis release --dest remote来使用这个配置
        remote : {
            //如果配置了receiver,fis会把文件逐个post到接收端上
            receiver : 'http://www.example.com/path/to/receiver.php',
            //从产出的结果的static目录下找文件
            from : '/static',
            //保存到远端机器的/home/fis/www/static目录下
            //这个参数会跟随post请求一起发送
            to : '/home/fis/www/',
            //通配或正则过滤文件,表示只上传所有的js文件
            include : '**.js',
            //widget目录下的那些文件就不要发布了
            exclude : /\/widget\//i,
            //支持对文件进行字符串替换
            replace : {
                from : 'http://www.online.com',
                to : 'http://www.offline.com'
            }
        },
        //名字随便取的,没有特殊含义
        local : {
            //from参数省略,表示从发布后的根目录开始上传
            //发布到当前项目的上一级的output目录中
            to : '../output'
        },
        //也可以是一个数组
        remote2 : [
            {
                //将static目录上传到/home/fis/www/webroot下
                //上传文件路径为/home/fis/www/webroot/static/xxxx
                receiver : 'http://www.example.com/path/to/receiver.php',
                from : '/static',
                to : '/home/fis/www/webroot'
            },
            {
                //将template目录内的文件(不包括template一级)
                //上传到/home/fis/www/tpl下
                //上传文件路径为/home/fis/www/tpl/xxxx
                receiver : 'http://www.example.com/path/to/receiver.php',
                from : '/template',
                to : '/home/fis/www/tpl',
                subOnly : true
            }
        ]
    }
});
  • 小贴士:
  • --dest参数 支持使用逗号(,)分割多个发布配置,比如上面的例子,我们可以使用fis release --dest remote,plugin 命令在一次编译中同时发布多个目标。
  • subOnly参数 默认上传from整个目录到测试机。添加subOnly参数仅上传from目录下文件。
  • replace替换多个字符串 需要replace替换多个字符串,可以使用正则的方式。例如:

replace : {
    from : /www\.a\.com|www\.b\.com/,
    to : function(m){
        if(m === 'www.a.com') return 'www.x.com';
        if(m === 'www.b.com') return 'www.y.com';
    }
}

deploy 扩展

通过 deploy扩展 能力,用户可以自定义 fis 的产出功能,更方便的实现自动化部署功能。目前官方提供的 deploy扩展 有

tar git bcs

此外还有社区贡献的如

aliyun zip ftp

使用 deploy扩展 的方法与使用 fis 插件的方法类似

用法:

// 设置开启deploy扩展,可以输入数组来开启多个扩展
fis.config.set('modules.deploy', 'tar');

// 为指定扩展设置发布配置
fis.config.set('settings.deploy.tar', {
    publish : {
        from : '/',
        to: '/',
        gzip: true,
        level: 0, //压缩质量 0-9,越大压缩比越高
        memLevel: 6, //压缩使用的内存量 1-9, 越大占用内存越多,执行速度越快
        file: './output/output.tar.gz'
    }
});
# 发布至output/output.tar.gz
fis release -d publish

打包配置

//fis-conf.js
fis.config.merge({
    pack : {
        //打包所有的demo.js, script.js文件
        //将内容输出为static/pkg/aio.js文件
        'pkg/aio.js' : ['**/demo.js', /\/script\.js$/i],
        //打包所有的css文件
        //将内容输出为static/pkg/aio.css文件
        'pkg/aio.css' : '**.css'
    }
});
输出结果:使用命令

    fis release --pack --md5 --dest ./output 
编译项目,然后到output目录下查看产出的map.json内容得到:
{
    "res": {
        "demo.css": {
            "uri": "/static/css/demo_7defa41.css",
            "type": "css",
            "pkg": "p1"
        },
        "demo.js": {
            "uri": "/static/js/demo_33c5143.js",
            "type": "js",
            "deps": [
                "demo.css"
            ],
            "pkg": "p0"
        },
        "index.html": {
            "uri": "/index.html",
            "type": "html",
            "deps": [
                "demo.js",
                "demo.css"
            ]
        },
        "script.js": {
            "uri": "/static/js/script_32300bf.js",
            "type": "js",
            "pkg": "p0"
        },
        "style.css": {
            "uri": "/static/css/style_837b297.css",
            "type": "css",
            "pkg": "p1"
        }
    },
    "pkg": {
        "p0": {
            "uri": "/static/pkg/aio_5bb04ef.js",
            "type": "js",
            "has": [
                "demo.js",
                "script.js"
            ],
            "deps": [
                "demo.css"
            ]
        },
        "p1": {
            "uri": "/static/pkg/aio_cdf8bd3.css",
            "type": "css",
            "has": [
                "demo.css",
                "style.css"
            ]
        }
    }
}