前端架构之路(6) - 组件化
组件化
1. 什么是 “组件化”
组件化就是将项目中可以共用的代码提取出来,单独成一个组件,以便在多个地方调用此组件,这样便可以做到只维护一份代码,而不需要每次更新都要改多个地方,而且还不能保证都一样。
组件化一般分为项目内的组件化和项目外的组件化。
2. 项目内组件化
项目内的组件化,就是一个项目中可以共用的代码提取出来,独立成组件,供项目其他地方调用。比如像上一节推荐使用的目录结构中的 component
目录:
|-- project/ 工程目录 |-- src/ 源代码目录 |-- component/ 全局组件目录 |-- util/ 全局工具函数目录 |-- ...
项目内的组件化对于单个项目是很适用,但当组件需要被跨项目使用(多个项目同时使用)时,便有些棘手了。
3. 彻底组件化
彻底组件化就是将组件独立成一个项目,如果需要在其他项目使用这个组件,就需要依赖这个项目。这个时候,组件化一般都是搭配版本管理工具和版本管理系统一起使用。
版本管理系统以 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. 动态开发组件
组件开发中有一个比较突出的问题,就是很多组件往往是与实际项目有强依赖性,需要与实际项目进行实时调试,而实际项目又是以版本化在管理组件,不能做到实时更新组件代码,组件必须发布一个版本,实际项目才能更新,这极大的降低了开发效率和便利性。
解决这个问题当然还是需要构建工具的支持。以 lila 与 yume 为例进行说明:
目录结构是这样的
|-- 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. 后续
下一篇:私有 npm 仓库
更多博客,查看 https://github.com/senntyou/blogs
版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)