1. 程式人生 > >fis3前端工程構建配置入門教程

fis3前端工程構建配置入門教程

一、前言

fis3是百度推出的一款前端工程構建工具,類似的還有webpack,gulp等工具;無論大家有沒有使用過,從事前端行業應該都略知一二了,所以對於此類工具用幹嘛的我這裡就不做重複了。

其實對於這類構建工具,大部分人是不感興趣,或者說有些畏懼的,配置多賊麻煩,無法像js一樣除錯很恐怖,給人感覺很難;特別是fis3這種相對比較冷門的構建工具,出現問題百度一圈相關答案真的很少...

我也曾抱怨公司為啥不用webpack,但我畢竟不是抉擇者,已經決定了使用這個還不如沉下心去學習瞭解;本文會抽出我覺得常用的,好用的配置,並通過我的理解來加以描述,一定能看得懂,我也會在文章結尾貼上我的專案配置,希望看完基本教程你能看懂,那麼本文開始。

二、簡單配置入門(本文核心部分,不難,耐心點看)

fis3編譯流程都是通過配置完成的,我們的配置等於告訴fis3工具應該按怎樣的規則編譯我們的專案,這裡說下必用的配置API:

1.fis.set(key,value)

此方法提供了多種key欄位,不同的key作用不同,這裡只說下key為'project.files'的作用,它能幫我們過濾資料夾。

一個專案資料夾那麼多,肯定有一些檔案我們並不希望fis3幫我們編譯,比如三方庫node_modules這樣,舉個例子:

fis.set('project.files', ['commonLess/**', 'components/**', 'modules/**', 'pages/**']);

這段程式碼的意思是,我希望fis3後續配置只對commonLess,components等資料夾下的所有檔案起作用,沒新增的資料夾都被過濾掉了,所以這個方法請寫在配置的第一行,你可以點選這裡檢視完整的key說明。

2.fis.hook()

此方法能啟用模組化開發,為js檔案提供模組化開發的支援;我們可以下載fis3提供的外掛並利用hook方法啟用模組化,fis3提供了三種模組外掛。

我司選擇了commonjs規範,這個需要配合mod.js一起使用,先下載fis3提供的fis3-hook-commonjs外掛(mod.js這裡就不說怎麼用了)

npm install fis3-hook-commonjs

在fis3配置表中新增如下配置就啟用了commonjs規範:

fis.hook('commonjs');

當然單hook還不夠,我們還沒指定哪些檔案使用此規範,這個需要下面的match方法指定;這行程式碼也請加在fis3配置檔案頭部位置,先啟用模組化,後面再指定哪些檔案使用模組化。

2.fis.match(selector, props)

selector:表示匹配路徑,你希望哪個路徑下的檔案被編譯處理,就將此路徑寫在這裡,這是fis3提供的匹配語法:

  • * 匹配0或多個除了 / 以外的字元
  • ? 匹配單個除了 / 以外的字元
  • ** 匹配多個字元包括 /
  • {} 可以讓多個規則用 , 逗號分隔,起到或者的作用
  • ! 出現在規則的開頭,表示取反。即匹配不命中後面規則的檔案

props:編譯規則,你希望前面你選擇的路徑下的檔案被怎麼編譯,這個規則就寫在這裡。

fis3大部分配置都是通過match方法實現的,這段請耐心點看:

fis3建議路徑都是以/開頭,/代表根目錄,舉個例子:

fis.match('a.js', {});

這段程式碼表示匹配整個專案中的所有a.js檔案,包括/a.js     /a/a.js   /a/b/a.js

但如果我們加了斜線,意義就不同了:

fis.match('/a.js', {});

此時表示,只匹配根目錄下的a.js,並不會匹配所有路徑下的a.js。

除此之外,/a/*.js表示只匹配/a目錄下所有的js檔案,不包含/a目錄下子目錄中的js,不過我們可以通過這種寫法/a/**.js達到此目的。

說完match匹配路徑的規則,簡單說下match的props屬性,注意,所有的屬性都包裹在一個{}中,這裡就主要說下常用的幾個:

release:設定檔案的產出路徑

我們按路徑匹配了一些檔案,經過某些編譯之後輸出到哪裡,這個產出就是由release決定的,例如:

fis.match('*.{png,js,css}', {
  release: '/static/$0'
});

這段程式碼的意思是,匹配整個專案中所有的png,js,css型別的檔案,並輸出到根目錄下的static檔案中;

$0表示match方法的整個selector欄位,就像一個變數,匹配到什麼,$0就代表什麼,那麼在這裡的意思就是按照檔案原名輸出到static目錄下。

 順帶一體,除了$0還有一個$1也很常用,舉個例子:

fis.match('/pages/**/(*.html)', {
    release: '/$1'
});

這段程式碼的意思是,將pages目錄下所有html檔案按檔案原名輸出到根目錄下,前面說了/代表根目錄。此時$1代表(*.html)這一段匹配的所有欄位,也就是檔名了。如果是$0就代表/pages/**/(*.html) 這一段,應該不難理解。

isMod:是否啟用模組化

前面我們通過fis.hook()方法呼叫了模組化外掛,現在就可以利用isMod屬性指定哪些檔案模組化,比如:

fis.match('*.js', {
    isMod: true,
    release: '/static/$0'
});

這段程式碼的意思是,匹配所有的js檔案,模組化,並且輸出到根目錄下static檔案中,並按原名顯示。

useHash:檔案是否新增md5戳

這個做http快取會用,給檔案新增md5戳便於客戶端主動感知檔案變化,如果對於http快取感興趣,可以閱讀部落格這邊文章---http快取詳解,http快取推薦方案

fis.match('*.css', {
    useHash: true
});

這段程式碼的意思是,匹配所有的css檔案,在編譯時全部新增md5戳。

rExt:設定檔案編譯後的產出字尾

說直白點,改變檔案釋出後的檔案字尾,比如less,sass檔案轉義後我們希望是css格式,那麼就可以這樣:

fis.match('*.{less,sass}', {
    rExt: '.css'
});

packTo:設定檔案合併後的輸出路徑與檔案

這個屬性是合併檔案用的,比如我一個頁面用了三個js檔案,我想合併成一個js檔案,就可以利用這個屬性,舉個例子:

fis.match('/index/**.js', {
    packTo: '/static/pkg_index.js'
});

這段配置的意思是,找到根目錄下index檔案下所有js檔案,合併釋出到根目錄下static檔案下的pkg_index.js檔案中。

id:指定檔案的資源id

這麼解釋可能看不懂,直接上個例子:

fis.match('/static/jquery.js', {
    id: 'jquery',
    isMod: true
});
// 引用檔案時
var $ = require('jquery');

我們將根目錄下的static資料夾中的jquery.js檔案的id設定成了jquery欄位,在引用時直接require   id設定的欄位就可以了,如果不設定,我們require就是這樣:

var $ = require('/static/jquery.js');

所以id的作用就像指定了一個欄位作為key去儲存一段複雜的路徑,這樣做的好處是在require時能更加簡單。

其它match屬性暫時沒用到,點選這裡可以檢視完整的match屬性

三、釋出命令

知道了基本的配置,就要通過釋出指令,將我們的專案按照配置釋出出去,這裡簡單說下發布指令,很簡單:

fis3 release -d <path>

<path>代表任意釋出路徑

fis3 release -d ./output

釋出到當前專案目錄的outout目錄下

fis3 release -d ../dist

釋出到專案父級目錄的dist目錄下

fis3 release -d D:\output

釋出到D盤下的output目錄下

除此之外,我們還能在釋出指令目錄後新增屬性,比如:

fis3 release -d D:\output -w

-w啟用檔案監聽功能,釋出後此命令不會退出,而是一直顯示。

fis3 release -d D:\output -wL

-L一般與w一起使用,監聽檔案變化,只要修改任何東西,都會自動重新整理頁面

fis3 release -d D:\output -wLc

-c表示每次釋出清除編譯快取

關於釋出指令path與match屬性release的區別

不知道大家會不會把match release屬性指定輸出路徑和釋出指令中指定輸出路徑弄混;實際開發中,釋出指令的path決定的是大格局,整個專案要釋出到哪,而match release的路徑往往是基於專案路徑後決定個別檔案釋出到哪,這是有區別的。

四、fis3常用外掛與配置

前面聊的入門的配置規則與釋出命令其實只是為了讓你看懂下面這些配置,拷貝到配置中進行釋出,如果提示缺少外掛,請對應下載對應外掛即可:

1.轉義所有less檔案,併為css3屬性新增瀏覽器相容字首,如果有sass做法也一樣,請下載對應外掛:

fis.match('*.less', {
    rExt: '.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
    })
});

2.壓縮js與css檔案,需要下載對應外掛

fis.media('prod').match("**.js", {
    //壓縮js
    optimizer: fis.plugin('uglify-js')
});
fis.match('**.{css,less}', {
    //壓縮css
    optimizer: fis.plugin('clean-css')
});

3.單頁面零散資源合併,這個在生產環境需要使用

比如將index頁面的所有js合併成一個js,所有css檔案合併成一個css,也需要下載外掛

fis.match('::package', {
    postpackager: fis.plugin('loader', {
        //單頁面合併零散資源
        allInOne: true
    })
});

4.為css,js新增md5戳,http快取必備

fis.match('*.{js,css}', {
    //為js,css型別檔案新增md5戳
    useHash: true
})

5.為所有圖片新增md5戳

fis.match('::image', {
    //為所有的圖片型別新增md5戳
    useHash: true
});

五、我的前端專案完整配置

// 過濾檔案,只有陣列中的目錄才會被fis3編譯
fis.set('project.files', ['bootstrap/**', 'commonLess/**', 'components/**', 'modules/**', 'pages/**', 'partials/**']);

//啟用relative外掛,所有檔案使用相對路徑
fis.hook('relative')
    .match('**', {
        relative: true
    });

// commonJS規範
fis.hook('commonjs');

//將pages下所有html按原檔名釋出至根目錄
fis.match('/pages/**/(*.html)', {
    release: '/$1',
    isMod: true,
});

//為js檔案啟用模組化
fis.match('{modules,pages,partials,components}/(**.js)', {
    isMod: true
});

//less轉義css,並新增瀏覽器字首
fis.match('**/*.less', {
    rExt: '.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
    })
});

//使用postcss,並使用pxtoviewport外掛
var pxtoviewport = require('postcss-px-to-viewport');
fis.match('*.{css,less,scss}', {
    postprocessor: fis.plugin('postcss', {
        processConfig: {},
        plugins: [pxtoviewport],
        sourceMap: true,
        sourceMapRelative: false
    })
});

fis.match('::packager', {
    postpackager: fis.plugin('loader', {
        resourceType: 'mod',
        useInlineMap: true // 資源對映表內嵌
    })
});


//生產環境配置,相比測試環境,多了程式碼合併壓縮,新增時間戳等操作。
fis.media('prod').match("**.js", {
        //壓縮js
        optimizer: fis.plugin('uglify-js')
    }).match('**.{css,less}', {
        //壓縮css
        optimizer: fis.plugin('clean-css')
    }).match('::package', {
        postpackager: fis.plugin('loader', {
            //單頁面合併零散資源
            allInOne: true
        })
    }).match('*.{js,css}', {
        //為js,css型別檔案新增md5戳
        useHash: true
    })
    .match('::image', {
        //為所有的圖片型別新增md5戳
        useHash: true
    });
View Code

所以配置上半部分都屬於測試環境釋出配置,只處理less轉義,js模組化,檔案資源定位輸出等基本操作。

在程式碼最下方有一段屬於生產環境的配置,只有在生產環境下我們才需要程式碼合併,壓縮,新增md5戳,不然合併壓縮了我們也不好除錯功能。

這兩段配置是可以通過釋出指令區分發布的,比如我在測試環境釋出,指令應該是這樣:

fis3 release -d D:\output

如果你要在生產環境釋出,請在release後新增meaid中的欄位prod(這個欄位是隨便寫的),比如:

fis3 release prod -d D:\output

說直白點,我們前面的配置都是fis.match(),後面有一段配置是fis.media('隨便取名').match()這樣寫的。

在釋出時,如果你在釋出指令release後加了media自定義的欄位,整個配置都會執行,但如果你不加media欄位,那麼就只執行fis.match()相關配置,這樣我們就能在不同環境區分發布了。

那麼針對於fis3就聊這麼多了,琢磨著用這玩意的人真不多,估計也沒多少人願意看,那麼本文結