FIS3簡單應用小型項目配置

前言

以前花了篇文章講述怎麼從零開始搭建起一個基礎的webpack4+React的腳手架,而後由於有些小項目不須要用到這麼複雜的打包器去構建,這裏分享一款項目中使用的簡單配置的腳手架.javascript

webpack系列文章

webpack4從零開始構建(一)
webpack4+React16項目構建(二)
webpack4功能配置劃分細化(三)
webpack4引入Ant Design和Typescript(四)
webpack4代碼去重,簡化信息和構建優化(五)
webpack4配置Vue版腳手架(六)php

FIS3 是什麼?

FIS3 是面向前端的工程構建工具。解決前端工程中性能優化、資源加載(異步、同步、按需、預加載、依賴管理、合併、內嵌)、模塊化開發、自動化工具、開發規範、代碼部署等問題。css

可是好像開發團隊都散了,如今已是棄置的樣子,好幾年沒有消息,特別是Nodejs支持版本只到@6,因此若是對這方面有要求的話不建議使用,簡單瞭解下便可.html

由於這裏摘抄了fis3構建流程和官網一些經常使用語法,更詳細能夠直接看官網,知道的就直接往下拉到配置部分前端

FIS3 , 爲你定製的前端工程構建工具java

Node 版本管理

由於Fis3的Node版本要求 0.8.x,0.10.x, 0.12.x,4.x,6.x,不在此列表中的版本不予支持node

咱們能夠安裝一個版本管理器,根據需求切換.
nvm-windowsreact

安裝版本jquery

nvm install <version> [arch]

移除版本webpack

nvm uninstall <version>

查看已安裝版本

nvm ls

切換版本

nvm use [version] [arch]

咱們選擇系列最新的@6.14.4版本安裝

一些具體的包管理器等能夠參考我以前的章節,這裏不復述了.

webpack4從零開始構建(一)

安裝 FIS3

npm install -g fis3
  • -g 安裝到全局目錄,必須使用全局安裝,當全局安裝後才能在命令行(cmd或者終端)找到 fis3 命令
  • 安裝過程當中遇到問題具體請參考 fis#565 解決

安裝完成後執行 fis3 -v 判斷是否安裝成功

fis3 -v

命令行提供瞭如下功能

[INFO] Currently running fis3 (C:\Users\msi\AppData\Roaming\npm\node_modules\.fis3_npminstall\node_modules\.3.4.40@fis3\)

 Usage: fis3 <command>

 Commands:

   init                           scaffold with specifed template.
   install                        install components
   release [media name]           build and deploy your project
   server <command> [options]     launch a server
   inspect [media name]           inspect the result of fis.match

 Options:

   -h, --help                print this help message
   -v, --version             print product version and exit
   -r, --root <path>         specify project root
   -f, --file <filename>     specify the file path of `fis-conf.js`
   --no-color                disable colored output
   --verbose                 enable verbose mode

聲明依賴

FIS3 在執行編譯的過程當中,會掃描這些編譯標記,從而創建一張 靜態資源關係表,資源關係表詳細記錄了項目內的靜態資源id、發佈後的線上路徑、資源類型以及 依賴關係 和 資源打包 等信息。使用 FIS3 做爲編譯工具的項目,能夠將這張表提交給後端或者前端框架去運行時,根據組件使用狀況來 按需加載資源或者資源所在的包,從而提高前端頁面運行性能。

工做原理

FIS3 是基於文件對象進行構建的,每一個進入 FIS3 的文件都會實例化成一個 File 對象,整個構建過程都對這個對象進行操做完成構建任務。

整個 FIS3 的構建流程大致歸納分爲三個階段。
1, 掃描項目目錄拿到文件並初始化出一個文件對象列表
2, 對文件對象中每個文件進行單文件編譯
3, 獲取用戶設置的 package 插件,進行打包處理(包括合併圖片)

單文件編譯流程

lint:代碼校驗檢查,比較特殊,因此須要 release 命令命令行添加 -l 參數
parser:預處理階段,好比 less、sass、es六、react 前端模板等都在此處預編譯處理
preprocessor:標準化前處理插件
standard:標準化插件,處理內置語法
postprocessor:標準化後處理插件

打包處理

prepackager 打包前處理插件擴展點
packager 打包插件擴展點,經過此插件收集文件依賴信息、合併信息產出靜態資源映射表
spriter 圖片合併擴展點,如 csssprites
postpackager 打包後處理插件擴展點

文件指紋

文件指紋,惟一標識一個文件。在開啓強緩存的狀況下,若是文件的 URL 不發生變化,沒法刷新瀏覽器緩存。通常都須要經過一些手段來強刷緩存,一種方式是添加時間戳,每次上線更新文件,給這個資源文件的 URL 添加上時間戳。

而 FIS3 選擇的是添加 MD5 戳,直接修改文件的 URL,而不是在其後添加 query

<!--源碼:
<img title="百度logo" src="images/logo.gif"/>
編譯後-->
<img title="百度logo" src="/static/pic/logo_74e5229.gif"/>

資源定位

定位資源能力,能夠有效地分離開發路徑與部署路徑之間的關係,工程師再也不關心資源部署到線上以後去了哪裏,變成了什麼名字,這些均可以經過配置來指定。而工程師只須要使用相對路徑來定位本身的開發資源便可。這樣的好處是:資源能夠發佈到任何靜態資源服務器的任何路徑上而不用擔憂線上運行時找不到它們,並且代碼具備很強的可移植性,甚至能夠從一個產品線移植到另外一個產品線而不用擔憂線上部署不一致的問題。

在html中定位資源

FIS3 支持對html中的script、link、style、video、audio、embed等標籤的srchref屬性進行分析,一旦這些標籤的資源定位屬性能夠命中已存在文件,則把命中文件的url路徑替換到屬性中,同時可保留原來url中的query查詢信息。

相關配置

fis.match('*.{js,css,png,gif}', {
    useHash: true // 開啓 md5 戳
});

// 全部的 js
fis.match('**.js', {
    //發佈到/static/js/xxx目錄下
    release : '/static/js$0'
});

// 全部的 css
fis.match('**.css', {
    //發佈到/static/css/xxx目錄下
    release : '/static/css$0'
});

// 全部image目錄下的.png,.gif文件
fis.match('/images/(*.{png,gif})', {
    //發佈到/static/pic/xxx目錄下
    release: '/static/pic/$1$2'
});

實際結果

<!--源碼:
<img title="百度logo" src="images/logo.gif"/>
編譯後-->
<img title="百度logo" src="/static/pic/logo_74e5229.gif"/>

<!--源碼:
<link rel="stylesheet" type="text/css" href="demo.css">
編譯後-->
<link rel="stylesheet" type="text/css" href="/static/css/demo_7defa41.css">

<!--源碼:
<script type="text/javascript" src="demo.js"></script>
編譯後-->
<script type="text/javascript" src="/static/js/demo_33c5143.js"></script>

在js中定位資源

js語言中,可使用編譯函數 __uri(path) 來定位資源,fis分析js文件或 html中的script標籤內內容 時會替換該函數所指向文件的線上url路徑。

<!--源碼:
var img = __uri('images/logo.gif');
編譯後-->
var img = '/images/logo_74e5229.gif';

<!--源碼:
var css = __uri('demo.css');
編譯後-->
var css = '/demo_7defa41.css';

<!--源碼:
var js = __uri('demo.js');
編譯後-->
var js = '/demo_33c5143.js';

在css中定位資源

<!--源碼:
@import url('demo.css');
編譯後-->
@import url('/demo_7defa41.css');

<!--源碼:
.style {
    background: url('images/body-bg.png');
}
編譯後-->
.style {
    background: url('/images/body-bg_1b8c3e0.png');
}

<!--源碼:
.style {
    _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/body-bg.png');
}
編譯後-->
.style {
    _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/images/body-bg_1b8c3e0.png');
}

內容嵌入

嵌入資源即內容嵌入,能夠爲工程師提供諸如圖片base64嵌入到css、js裏,前端模板編譯到js文件中,將js、css、html拆分紅幾個文件最後合併到一塊兒的能力。有了這項能力,能夠有效的減小http請求數,提高工程的可維護性。

html

在html中能夠嵌入其餘文件內容或者base64編碼值,能夠在資源定位的基礎上,給資源加 ?__inline 參數來標記資源嵌入需求。
html中嵌入圖片base64

<img title="百度logo" src="images/logo.gif?__inline"/>
-----------------------------輸出--------------------------------
<img title="百度logo" src="data:image/gif;base64,R0lGODlhDgGBALMAAGBn6eYxLvvy9PnKyfO...Jzna6853wjKc850nPeoYgAgA7"/>

html中嵌入樣式文件

<link rel="stylesheet" type="text/css" href="demo.css?__inline">
-----------------------------輸出--------------------------------
<style>img { border: 5px solid #ccc; }</style>

html中嵌入腳本資源

<script type="text/javascript" src="demo.js?__inline"></script>
-----------------------------輸出--------------------------------
<script type="text/javascript">console.log('inline file');</script>

html中嵌入頁面文件

<link rel="import" href="demo.html?__inline">
-----------------------------輸出--------------------------------
<h1>demo.html content</h1>

在js中嵌入資源

在js中,使用編譯函數 __inline() 來提供內容嵌入能力。能夠利用這個函數嵌入圖片的base64編碼、嵌入其餘js或者前端模板文件的編譯內容, 這些處理對html中script標籤裏的內容一樣有效。

在js中嵌入js文件

__inline('demo.js');
-----------------------------輸出--------------------------------
console.log('demo.js content');

在js中嵌入圖片base64

var img = __inline('images/logo.gif');
-----------------------------輸出--------------------------------
var img = 'data:image/gif;base64,R0lGODlhDgGBALMAAGBn6eYxLvvy9PnKyfO...Jzna6853wjKc850nPeoYgAgA7';

在js中嵌入其餘文本文件

var css = __inline('a.css');
-----------------------------輸出--------------------------------
var css = "body \n{    color: red;\n}";

在css中嵌入資源

與html相似,凡是命中了資源定位能力的編譯標記, 除了src="xxx"以外,均可以經過添加 ?__inline 編譯標記均可以把文件內容嵌入進來。src="xxx"被用在ie瀏覽器支持的filter內,該屬性不支持base64字符串,所以未作處理。

在css文件中嵌入其餘css文件

@import url('demo.css?__inline');
-----------------------------輸出--------------------------------
img { border: 5px solid #ccc; };

在css中嵌入圖片的base64

.style {
    background: url(images/logo.gif?__inline);
}
-----------------------------輸出--------------------------------
.style {
    background: url(data:image/gif;base64,R0lGODlhDgGBALMAAGBn6eYxLvvy9PnKyfO...Jzna6853wjKc850nPeoYgAgA7);
}

發佈到遠端機器

當咱們開發項目後,須要發佈到測試機(聯調機),通常能夠經過如 SMB、FTP 等上傳代碼。FIS3 默認支持使用 HTTP 上傳代碼,首先須要在測試機部署上傳接收腳本(或者服務),這個腳本很是簡單,如今給出了 php 的實現版本,能夠把它放到測試機上某個 Web 服務根目錄,而且配置一個 url 能訪問到便可。

假定這個 URL 是:http://cq.01.p.p.baidu.com:8888/receiver.php

那麼咱們只須要在配置文件配置

fis.match('*', {
  deploy: fis.plugin('http-push', {
    receiver: 'http://cq.01.p.p.baidu.com:8888/receiver.php',
    to: '/home/work/htdocs' // 注意這個是指的是測試機器的路徑,而非本地機器
  })
})

文件目錄結構

從上面就知道FIS3 是基於文件對象進行構建的,首先咱們要定義好文件目錄

.
│───README.md        // 說明
│───node_modules   // 依賴
│───dist           // 打包目錄
│───.editorconfig  // 格式化代碼設置   
│───.eslintrc.json // 代碼風格設置
│───.gitignore     // 提交文件過濾
│───package.json   // 說明
│───fis-conf.js    // fis3配置文件
│───dev.cmd        // 執行開發命令
│───prod.cmd       // 執行生產命令
└───assets
│   │───style      // 公用scss和css
│   │───img        // 公用圖片
│   └───utils      // 公用工具代碼
│
└───static
│   │───plugins    // 公用插件
│   │   └───文件夾  // 可能包含插件圖片樣式等
│   └───libs       // 公用庫
│
└───page           // 頁面部分

切記: 配置文件是具體針對項目文件夾路徑打包,不能隨意改動

打包目錄結構

.
└───dist
    │───img              // 項目打包圖片
    │───index.html      // 項目打包入口
    └───pkg             // 打包後的項目文件夾
        │───all.css      // 項目打包樣式
        │───libs.js      // 項目打包庫
        └───page.js      // 項目打包業務代碼

安裝依賴

時間關係直接附上,先安裝完以後再講解

package.json

{
  "name": "fis3_demo",
  "version": "1.0.0",
  "scripts": {
    "dev": "fis3 release dev -wL",
    "prod": "fis3 release prod -c",
    "lint": "eslint --fix",
    "clean": "rimraf dist/"
  },
  "dependencies": {
    "cross-env": "^5.2.0",
    "eslint": "^5.9.0",
    "fis-optimizer-clean-css": "^0.0.12",
    "fis-optimizer-html-compress": "^0.0.7",
    "fis-optimizer-png-compressor": "^0.2.0",
    "fis-optimizer-uglify-js": "^0.2.3",
    "fis-parser-babel-6.x": "^6.24.1",
    "fis-parser-node-sass": "^1.0.4",
    "fis3-optimizer-img-compressor": "^0.1.3",
    "fis3-packager-deps-pack": "^0.1.2",
    "fis3-packager-map": "^1.1.3",
    "fis3-parser-typescript": "^1.2.2",
    "fis3-postpackager-loader": "^2.1.11",
    "fis3-preprocessor-autoprefixer": "^0.1.1",
    "fis3-preprocessor-js-require-css": "^0.1.3",
    "fis3-preprocessor-js-require-file": "^0.1.3"
  },
  "devDependencies": {
    "fis-postpackager-map": "^0.0.2"
  }
}

裏面有兩個命令分別執行開發環境和生產環境

"dev": "fis3 release dev -wL", // 監聽文件實時更新
"prod": "fis3 release prod -c", // 清除緩存

參數回顧上面介紹命令行功能便可.爲了方便使用不用每次打開終端,咱們寫兩個執行文件

dev.cmd

npm run dev

prod.cmd

npm run prod

雙擊文件便可自動打開終端執行

配置文件

根目錄新建fis-conf.js,每次執行命令都會讀取這裏的配置去構建

忽略文件

由於fis3是根據文件打包,不像webpack4根據依賴解析,因此咱們須要聲明哪些文件不被加入構建隊列中

fis.set('project.ignore', [
  '/dist/**',
  '/node_modules/**',
  '/fis-conf.js',
  '/package.json',
  '/*.cmd',
  '/doc/**',
  '/yarn*',
  '*.md',
  '*.zip'
]);

樣式處理

指向樣式目錄覆蓋全部文件

fis.match('/assets/style/(**)', {
    rExt: '.css',
    // 支持 sass/scss 編譯成 css
    parser: fis.plugin('node-sass', {
      // options...
    }),
    // 自動給 css 屬性添加前綴,讓標準的 css3 支持更多的瀏覽器.
    preprocessor: fis.plugin('autoprefixer', {
      browsers: ['Android >= 2.1', 'iOS >= 4', 'ie >= 8', 'firefox >= 15'],
      cascade: true
    })
  })
  • 支持sass/scss處理
  • 指定瀏覽器版本自動添加前綴

腳本處理

fis.match('/assets/(js)/(**).js', {
    // rExt: 'js',
    // 支持 es六、es7 或者 jsx 編譯成 es5
    parser: fis.plugin('babel-6.x'),
    /* 容許你在 js 中直接 require 文件。好比圖片,json, 其餘靜態文件。
        require 部分將會替換成部署後的 url。 同時還支持,若是文件小於 20K 直接替換成 base64 字符串。 */
    preprocessor: [
      fis.plugin('js-require-file'),
      fis.plugin('js-require-css', {
        mode: 'dependency'
      })
    ]
  })
  • ES6兼容
  • 支持js裏require腳本和樣式

頁面&圖片處理

fis.match('/assets/img/(**)', {
    // 資源相對輸出路徑打包
    release: './img/$1'
  })
  .match('/pages/(**)', {
    release: './$1'
  })

先不作處理,單純輸出指定位置

依賴處理

這個是打包的關鍵配置,能夠直接使用打包相關依賴的文件,若是對打包順序有要求的話須要本身控制.固然還有不少插件幫你更好處理.這是最基礎的用法.當下以個人本地測試代碼設置

fis.match('::package', {
    postpackager: fis.plugin('loader'),
    packager: fis.plugin('deps-pack', {
      'pkg/libs.js': ['static/libs/jquery-1.11.0.min.js'],
      'pkg/home/all.css': ['assets/style/reset.css', 'assets/style/style.scss'],
      'pkg/home/page.js': [
        'assets/js/index.js'
      ]
    })
  })

輸出位置

首先須要指定打包路徑,咱們根據不一樣環境配置一下,到時候代碼裏全部相關路徑都會被轉成絕對路徑.

const baseDir = './dist', // 項目打包路徑
  devDir  = '../dist',   // 開發資源路徑
  prodDir = '../dist';   // 線上資源路徑

開發環境打包配置

// dev
fis.media('dev').match('*', {
  domain: devDir,
  deploy: fis.plugin('local-deliver', {
    to: baseDir
  })
});

意思就是將代碼打包到baseDir路徑,裏面的資源地址所有轉成絕對路徑devDir+url

生產環境咱們能夠進行更多針對性操做

// prod
fis
  .media('prod')
  .match('*.{js,css,png}', {
    useHash: true // 添加hash緩存
  })
  .match('/assets/js/(**)', {
    // fis-optimizer-uglify-js 插件進行壓縮,已內置
    optimizer: fis.plugin('uglify-js')
  })
  .match('/pages/(**):js', {
    // 針對html內js作壓縮
    optimizer: fis.plugin('uglify-js')
  })
  .match('/assets/style/(**)', {
    // fis-optimizer-clean-css 插件進行壓縮,已內置
    optimizer: fis.plugin('clean-css')
  })
  .match('/pages/(**):{css,inline-style,scss}', {
    // 針對html內css作壓縮
    optimizer: fis.plugin('clean-css')
  })
  .match('/assets/img/(**)', {
      // 圖片壓縮
    optimizer: fis.plugin('img-compressor')
  })
  .match('*', {
    domain: prodDir,
    deploy: fis.plugin('local-deliver', {
      to: baseDir
    })
  });

基本配置到此就完成了,咱們能夠測試效果看看

用例

新建pages/index.html

<!DOCTYPE html>
<html>

<head>
  <meta charset='utf-8'>
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Page Title</title>
  <link rel="stylesheet" type="text/css" media="screen" href="../assets/style/style.scss" />
</head>

<body>
  <div class="container">
    <img src="../assets/img/banner.jpg">
  </div>

  </div>
  <!-- JS -->
  <script src="../static/libs/jquery-1.11.0.min"></script>
  <script src="../assets/js/index.js"></script>
</body>

</html>

而後根據裏面對應的位置加上些資源執行命令便可,最終輸出以下

.
└───dist
    │───static          // 源文件處理後的資源,已經被打包入pkg的libs.js中,可忽略
    │───assets          // 源文件處理後的資源,已經被打包入pkg的對應文件中,可忽略
    │───img              // 項目打包圖片
    │───index.html      // 入口
    └───pkg             // 打包後的項目文件夾
        │───all.css      // 項目打包樣式
        │───libs.js      // 項目打包庫
        └───page.js      // 項目打包業務代碼

最終咱們獲得的輸出資源如上.至於被合併的資源應該有辦法忽略不讓輸出,可是我沒去找

還有當前項目沒有引入模塊插件,只是單純講解打包,有須要自行研究.

相關文章
相關標籤/搜索