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.js
 fis.match('/a.js',{}) //只命中根目录下面的 /a.js
 fis.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', //后缀名为css
    parser: 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-autoprefixer
        preprocessor: 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'),
        //压缩JS
        optimizer: fis.plugin('uglify-js')
    })
    .match('**.{css,less}', {
        //压缩CSS
        optimizer: 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

很晚了,写的比较匆忙,之后再来补充!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章