前端架構之路(6) - 組件化

組件化

1. 什麼是 「組件化」

組件化就是將項目中能夠共用的代碼提取出來,單獨成一個組件,以便在多個地方調用此組件,這樣即可以作到只維護一份代碼,而不須要每次更新都要改多個地方,並且還不能保證都同樣。css

組件化通常分爲項目內的組件化和項目外的組件化。html

2. 項目內組件化

項目內的組件化,就是一個項目中能夠共用的代碼提取出來,獨立成組件,供項目其餘地方調用。好比像上一節推薦使用的目錄結構中的 component 目錄:jquery

|-- project/ 工程目錄
    |-- src/ 源代碼目錄
        |-- component/ 全局組件目錄
        |-- util/ 全局工具函數目錄
        |-- ...

項目內的組件化對於單個項目是很適用,但當組件須要被跨項目使用(多個項目同時使用)時,便有些棘手了。webpack

3. 完全組件化

完全組件化就是將組件獨立成一個項目,若是須要在其餘項目使用這個組件,就須要依賴這個項目。這個時候,組件化通常都是搭配版本管理工具和版本管理系統一塊兒使用。git

比較經常使用的版本管理工具備 gitsvnes6

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

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 依賴。web

# 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';

通常來講,獨立化組件要有 私有包命名前綴apache

# 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
$ 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. 後續

上一篇:構建工具 for teamwork

下一篇:私有 npm 倉庫

更多博客,查看 https://github.com/senntyou/blogs

做者:深予之 (@senntyou)

版權聲明:自由轉載-非商用-非衍生-保持署名(創意共享3.0許可證

相關文章
相關標籤/搜索