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

很晚了,寫的比較匆忙,之後再來補充!

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