fis3前端工程构建配置总结
憋了好久,还是决定写下这篇博客,fis3是自动化的构建工具而已,它的构建不会修改源码,而是会通过用户设置,将构建结果输出到指定的目录。下面我们来谈下怎么配置fis3的(怎么安装这里就不说了)
1.fis3工作流程
FIS3 是基于文件对象进行构建的,每个进入 FIS3 的文件都会实例化成一个 File 对象,整个构建过程都对这个对象进行操作完成构建任务。
整个 FIS3 的构建流程大体概括分为三个阶段。
1.扫描项目目录拿到文件并初始化出一个文件对象列表
2.对文件对象中每一个文件进行单文件编译
3.获取用户设置的 package 插件,进行打包处理(包括合并图片)
对于第2点,对每个单文件编译又包括以下过程:
1.初始化阶段lint:代码校验检查,比较特殊,所以需要 release 命令,命令行添加 -l 参数
2.预处理阶段parser:比如 less、sass、es6、react 前端模板等都在此处预编译处理(语言编译)
3.标准化前处理插件preprocessor:比如有些css3语法需要插件加上前缀
4.标准化插件standard:处理内置语法,比如HTML和css或者js中嵌入其他文件内容或者base64编码值inline的语法,还有一些声明依赖在HTML和css或者js中用的requie语法等
5.标准化后处理插件postprocessor:比如压缩工作等
对于第3点,也有下面几个过程:
1.prepackager 打包前处理插件扩展点
2.packager 打包插件扩展点,通过此插件收集文件依赖信息、合并信息产出静态资源映射表
3.spriter 图片合并扩展点,如 csssprites
4.postpackager 打包后处理插件扩展点
你了解这些流程你就会得心应手了!下面是工作流程图

2.配置API
fis.set(key,value)
fis.set('project.charset', 'gbk'); //指定项目编译后产出文件的编码
fis.set('project.md5Length', 8); //文件MD5戳长度。默认长度为7
fis.set('project.md5Connector ', '.');//设置md5与文件的连字符
fis.set('project.files', ['*.html']);//设置项目源码文件过滤器
fis.set('project.ignore', ['*.bak']); //排除某些文件,set 为覆盖不是叠加
fis.set('project.fileType.text', 'tpl, js, css');//加文本文件后缀列表
fis.set('project.fileType.image', 'swf, cur, ico'); //追加图片类二进制文件后缀列表
这里说下比较常用的语法 fis.set(‘project.files’, [’*.html’]),这个是我项目里面的过滤文件
fis.set('project.files', [//报错提示、浏览器js兼容'basepiece/**',//主要加载程序'bootstrap/**',//builder公用组件、服务'builder/**',// Site公共组件 'commonComponents/**',//测试数据,本地发布使用'mockObject/**',//产品builder'product/customSizeGameBox/**',// Site公共服务'services/**',//builder整体样式'totalStyles/**',//whiteLabelSite公共组件服务'whiteLabelSite/**','map.json',//builder 第三方引用配置'package.json'
]);
key为project.files,value是你需要发布的文件,目的是设置项目源码文件过滤器,发布的时候只会发布写的这些文件,其他的不会做处理!
2.常用配置语法
fis.match(selector, props);
//selector :FIS3 把匹配文件路径的路径作为selector,下面我会说下常用的匹配规则(fis3支持glob 规则)
//props :编译规则属性,包括文件属性和插件属性
常用的匹配规则:
1.*** 匹配0或多个除了 / 以外的字符
2.? 匹配单个除了 / 以外的字符
3.** 匹配多个字符包括 /
4.{} 可以让多个规则用 , 逗号分隔,起到或者的作用
5.! 出现在规则的开头,表示取反。即匹配不命中后面规则的文件
fis 中的文件路径都是以 / 开头的,所以编写规则时,请尽量严格的以 / 开头。
fis.match('a.js',{}) //它匹配的是所有目录下面的 a.js, 包括:/a.js、/a/a.js、/a/b/a.jsfis.match('/a.js',{}) //只命中根目录下面的 /a.jsfis.match('/foo/*.js',{}) // 只会命中 /foo 目录下面的所有 js 文件,不包含子目录fis.match('/foo/**.js',{}) //命中 foo 目录下面以及所有其子目录下面的 js 文件
捕获分组写法
我们可以用 $1, $2, $3 来代表相应的捕获分组。其中 $0 代表的是 match 到的整个字符串
fis.match('/a/(**.js)', {release: '/b/$1' // $1 代表 (**.js) 匹配的内容 release 匹配的文件设置文件的产出路径,默认是文件相对项目根目录的路径,以 / 开头。该值可以设置为 false ,表示为不产出文件
});
fis.match('/a/(**.js)', {release: '/b/$0' // $0 代表 /a/(**.js) 匹配的内容
});
isMod是否组件化
fis.match('/widget/**.js', {isMod: true //表示widget文件目录下所有的js文件启动组件化});
useHash(文件是否携带 md5 戳)
fis.match('*.css', {useHash: false});
指定文件的资源id
fis.match('/static/lib/jquery.js', {id: 'jquery',isMod: true //模块化的意思
});
var $ = require('jquery'); //相当于 var $ = require('/static/lib/jquery.js')
packTo(合并打包操作)
fis.match('/static/folderA/**.js', {packTo: '/static/pkg/folderA.js' //文件合并并打包到指定文件夹里,是最后的环节和release不一样
});
fis.match('/static/folderA/file1.js', {packOrder: -100 //有时候需要控制顺序。可以通过配置 packOrder 来控制,packOrder 越小越在前面
});
fis.media(接口提供多种状态功能,比如有些配置是仅供开发环境下使用,有些则是仅供生产环境使用的)
fis.match('*', {useHash: false
});fis.media('prod').match('*.js', {useHash:true,optimizer: fis.plugin('uglify-js')
});fis3 release dev
注意:如果发布使用了fis.media匹配的名称,那么所有代码都会执行,如果没有使用,就只会执行fis.media上面的代码,一般我们开发没有必要压缩啊,合并打包啊,要不然我们代码不好调试,所以这里提供了多次环境使用
2.插件
fis hook()
fis3.hook('relative').match('**', {relative: true //启用插件,所有文件使用相对路径});
// commonJS规范
fis.hook('commonjs'); //commonjs规范,这个需要配合mod.js一起使用
less转css插件
fis.match('**/*.less', {rExt: '.css', //后缀名为cssparser: fis.plugin('less-2.x')
}).match('*.{css,less,scss}', {preprocessor: fis.plugin('autoprefixer', {"browsers": ["Android >= 2.1", "iOS >= 4", "ie >= 8", "firefox >= 15"],"cascade": true})
});
optimizer启用优化处理插件,并配置其属性
fis.match('*.css', {optimizer: fis.plugin('clean-css')//css压缩
});fis.match('*.png', {optimizer: fis.plugin('png-compressor')//图片压缩
})fis.match('{*.js,*.vm:js,*.html:js}', {optimizer: fis.plugin('uglify-js')// js 压缩
})
打包阶段插件(打包阶段插件设置时必须分配给所有文件,设置时必须 match ::package,不然不做处理。)
fis3-postpackager-loader
fis.match('::package', {prepackager: fis.plugin('plugin-name')//打包预处理插件})
fis.match('::package', {packager: fis.plugin('map'),//打包插件
});
fis.match('::package', {spriter: fis.plugin('csssprites')//打包后处理csssprite的插件})
fis.match('::package', {postpackager: fis.plugin('loader', {//打包后处理单页面合并零散资源allInOne: true})})
最后附上我项目的配置
fis.set('project.files', [//报错提示、浏览器js兼容'basepiece/**',//主要加载程序'bootstrap/**',//builder公用组件、服务'builder/**',// Site公共组件 'commonComponents/**',//测试数据,本地发布使用'mockObject/**',//产品builder'product/customSizeGameBox/**',// Site公共服务'services/**',//builder整体样式'totalStyles/**',//whiteLabelSite公共组件服务'whiteLabelSite/**','map.json',//builder 第三方引用配置'package.json'
]);//启用插件
fis.hook('relative')//插件作用 让所有文件,都使用相对路径。.match('**', {relative: true});
//引入模块化开发插件,设置规范为 commonJs 规范。
fis.hook('commonjs');/*************************目录规范*****************************/
fis.match("**/*", {release: '$&',url: '$&',relative: '$&' //代表访问路径是相对与自己本身的。这样配置文件引用的文件路径会不发生改变}).match('{bootstrap,builder,commonComponents,product/customSizeGameBox,services,whiteLabelSite}/(**.js)', {isMod: true,id: '$1'}).match("product/customSizeGameBox/(*.html)", {release: '$1',relative: '/'});/****************异构语言编译*****************/
fis.match('totalStyles/**/*.less', {parser: fis.plugin('less'),rExt: '.css'}).match('totalStyles/**/*.{css,less}', {//fis3-postprocessor-autoprefixerpreprocessor: fis.plugin('autoprefixer', {"browsers": ["Android >= 2.1", "iOS >= 4", "ie >= 8", "firefox >= 15"],"cascade": true})});//打包与css sprite基础配置
fis.match('::packager', {// npm install [-g] fis3-postpackager-loader// 分析 __RESOURCE_MAP__ 结构,来解决资源加载问题postpackager: fis.plugin('loader', {resourceType: 'mod',useInlineMap: true // 资源映射表内嵌}),packager: fis.plugin('map'),spriter: fis.plugin('csssprites', {layout: 'matrix',margin: '10'})
});/**********************生产环境下CSS、JS压缩合并*****************/
//使用方法 fis3 release prod -d
fis.media('prod')//注意压缩时.async.js文件是异步加载的,不能直接用annotate解析.match('**.js', {preprocessor: fis.plugin('annotate'),//压缩JSoptimizer: fis.plugin('uglify-js')}).match('**.{css,less}', {//压缩CSSoptimizer: fis.plugin('clean-css')})//node_modules 中js文件打包.match("node_modules/**/*.js", {packTo: "/static/vendor.js"})//node_modules 中CSS文件打包.match("node_modules/**/*.css", {packTo: "/static/vendor.css"})//打包builder相关所有JS文件到一个文件中.match("{basepiece,bootstrap,builder,commonComponents,product/customSizeGameBox/,services,whiteLabelSite}/(**.js)", {packTo: "/static/builder.js"})//打包所有CSS文件到一个文件中.match("totalStyles/**/*.{less,css}", {packTo: "/static/builder.css"})//打包所有图片文件到一个文件夹中.match("totalStyles/**/*.{svg, png, bmp, gif, jpe, jpeg, jpg, webp}", {release: "totalStyles/images/$1"})//不输出组件中的HTML文件.match("{builder/builderCommonComponents,commonComponents,product/customSizeGameBox/privateComponents,whiteLabelSite/wlsCommonComponents}/(**.html)", {release: false})//不输出测试数据.match("mockObject/**", {release: false})//不输出fis3配置文件.match("map.json", {release: false}).match('*.{js,css}', {//添加md5戳useHash: true}).match('*.{svg, png, bmp, gif, jpe, jpeg, jpg, webp}', {//添加md5戳useHash: true
很晚了,写的比较匆忙,之后再来补充!
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
