1. 程式人生 > >前端架構之路(6)

前端架構之路(6)

元件化

1. 什麼是 “元件化”

元件化就是將專案中可以共用的程式碼提取出來,單獨成一個元件,以便在多個地方呼叫此元件,這樣便可以做到只維護一份程式碼,而不需要每次更新都要改多個地方,而且還不能保證都一樣。

元件化一般分為專案內的元件化和專案外的元件化。

2. 專案內元件化

專案內的元件化,就是一個專案中可以共用的程式碼提取出來,獨立成元件,供專案其他地方呼叫。比如像上一節推薦使用的目錄結構中的 component 目錄:

|-- project/ 工程目錄
    |-- src/ 原始碼目錄
        |-- component/ 全域性元件目錄
        |-- util/ 全域性工具函式目錄
        |-- ...

專案內的元件化對於單個專案是很適用,但當元件需要被跨專案使用(多個專案同時使用)時,便有些棘手了。

3. 徹底元件化

徹底元件化就是將元件獨立成一個專案,如果需要在其他專案使用這個元件,就需要依賴這個專案。這個時候,元件化一般都是搭配版本管理工具和版本管理系統一起使用。

比較常用的版本管理工具有 gitsvn

版本管理系統以 gitlab 為例進行說明。

3.1 目錄結構示例

|-- project1/ 專案1
    |-- package.json
    |-- .gitignore
    |-- README.md
    |-- lila.config.js
    |-- ...
|-- project/ 工程目錄 |-- src/ 原始碼目錄 |-- component/ 專案內元件目錄 |-- util/ 全域性工具函式目錄 |-- ... |-- component1/ 元件1 |-- package.json |-- .gitignore |-- README.md |-- webpack.config.js |-- src/ 原始碼目錄 |-- ... |-- component2/ 元件2 |-- package.json |-- .gitignore |-- README.md |-- webpack.config.js |-- src/ 原始碼目錄 |-- ...

3.2 使用元件

project1 中安裝 component1, component2 依賴。

# package.json
{
    "dependencies": {
        "component1": "git+http://yourGit.com/yourName/component1.git#0.0.1",
        "component2": "git+http://yourGit.com/yourName/component2.git#0.0.1"
    }
}

# code
// commonjs
const component1 = require('component1');
// es6
import component1 from 'component1';

一般來說,獨立化元件要有 私有包命名字首

# package.json
{
    "dependencies": {
        "@yourCompany/component1": "git+http://yourGit.com/yourName/component1.git#0.0.1",
        "@yourCompany/component2": "git+http://yourGit.com/yourName/component2.git#0.0.1"
    }
}

# code
// commonjs
const component1 = require('@yourCompany/component1');
// es6
import component1 from '@yourCompany/component1';

獨立化元件與私有 npm 倉庫配合使用是最完美的,下一節 私有 npm 倉庫 將會講到。

# npm
$ npm config set registry http://your.company.npm.registry.com

# package.json
{
    "dependencies": {
        "@yourCompany/component1": "^0.0.1",
        "@yourCompany/component2": "^0.0.1"
    }
}

# code
// commonjs
const component1 = require('@yourCompany/component1');
// es6
import component1 from '@yourCompany/component1';

4. 使用構建工具

團隊開發元件化之後,就會有大量的元件產生。與諸多專案一樣,如何既能快速開發,又有規範可循,維護成本最小化,當然還是得用構建工具呀。

yume 構建工具為例進行說明。

4.1 安裝工具

npm install yume -g

4.2 新建專案

yume new yume-demo && cd yume-demo && npm install yume --save-dev

4.3 根據需要更新配置檔案

配置檔案在專案根目錄下 yume.config.js 中。

module.exports = {
    // 模組定義
    modules: {
        index: {
            js: 'src/index.js',
            filename: 'demo',
            library: 'Demo',
            libraryTarget: "umd"
        },
        ui: {
            html: 'ui/index.html',
            js: 'ui/index.js'
        },
        demo: {
            html: 'demo/index.html',
            js: 'demo/index.js'
        },
        example: {
            html: 'example/index.html',
            js: 'example/index.js'
        }
    },
    // 外部依賴包(不需要被打包進 dist 檔案中)
    externals: {
        jquery: {
            commonjs: 'jquery',
            amd: 'jquery',
            commonjs2: 'jquery',
            root: 'jQuery'
        },
        ...
    },
    // 單獨打包 css
    packCssSeparately: true,
    ...
};

4.4 開發專案

yume dev moduleName

4.5 打包專案

yume dist moduleName

這個時候,會在 dist 目錄中生成相應的包檔案,然後執行 npm publish 就可以釋出到遠端倉庫中了。

5. 動態開發元件

元件開發中有一個比較突出的問題,就是很多元件往往是與實際專案有強依賴性,需要與實際專案進行實時除錯,而實際專案又是以版本化在管理元件,不能做到實時更新元件程式碼,元件必須釋出一個版本,實際專案才能更新,這極大的降低了開發效率和便利性。

解決這個問題當然還是需要構建工具的支援。以 lilayume 為例進行說明:

目錄結構是這樣的

|-- projects/
    |-- project1/ 專案1
    |-- project2/ 專案2
    |-- component1/ 元件1
    |-- component2/ 元件2

project1 中程式碼是這樣的

# package.json
{
    "dependencies": {
        "@yourCompany/component1": "^0.0.1"
    }
}

# code
require('@yourCompany/component1/dist/component1.css'); // css 檔案
const component1 = require('@yourCompany/component1'); // 主檔案

配置 lila.config.js,讓專案支援動態載入 @yourCompany/component1 的開發程式碼

module.exports = {
    ...,
    // 新增一個 `resolve.modules`(新增一個 webpack 載入包基地址)
    resolveModules: [
        '../'
    ],
    // 別名配置(只有當命令列中有 `-o|out` 引數時才生效)
    outResolveAlias: {
        '@yourCompany/component1/dist/component1.css': 'component1/dist/component1.css',
        '@yourCompany/component1': 'component1/dist/component1.js'
    }
}

dev, dist @yourCompany/component1 元件的本地開發程式碼

執行 dev, dist, sync 命令時加上 -o, --out 引數,就可以載入 @yourCompany/component1 元件的本地開發程式碼

# dev
$ lila dev moduleName -o

# 正常執行,載入 0.0.1 版本中的程式碼
$ lila dev moduleName

# dist
$ lila dist moduleName -e 1 -out

# sync
$ lila sync moduleName -e 2 --out

6. 後續