Node.js项目拆包工程化基础指南_工程化指南教程

背景在我们开发的过程中,经常会遇到这样的问题,开发完了一些代码或者一个接口,别的小伙伴过来问你,代码可不可以给他复用,接口可以给他调用。这说明代码的复用和抽象对团队协作是很重要的。举个例子,如下图在这幅图中A服务先开发的,B服务开发的时候与A服务功能相似,尽量使用A服务的接口以提高效率,那么B服务是依赖A服务的,这样会产生如下痛点如果B服务有需求,A服务不满

Node.js项目拆包工程化基础指南

背景

在我们开发的过程中,经常会遇到这样的问题,开发完了一些代码或者一个接口,别的小伙伴过来问你,代码可不可以给他复用,接口可以给他调用。这说明代码的复用和抽象对团队协作是很重要的。举个例子,如下图

Node.js项目拆包工程化基础指南_工程化指南教程

Node.js项目拆包工程化基础指南_工程化指南教程

在这幅图中A服务先开发的,B服务开发的时候与A服务功能相似,尽量使用A服务的接口以提高效率,那么B服务是依赖A服务的,这样会产生如下痛点

  1. 如果B服务有需求,A服务不满足,则需求要先提给A服务,如果A服务的小伙伴没时间开发…那么B服务只能等待,因为这是一种依赖关系。
  2. 代码复用,因为是通过接口,所以也谈不上复用
    要想解决这个两个痛点,通用的思路是将A服务做下沉抽象,找团队专门做,或者约定规范A服务组和B服务组共同维护一个下沉的服务 ,这里我们使用node.js来开发A、B项目,通过包来代替web服务,可以提供一种不一样的思路,通过对node.js项目的工程化,优化A、B项目的依赖,使开发A服务的同时对B服务进行开发支持

思路

如何一边开发A服务一边对外提供支持?node.js抽象的形式就是包,也就是说我们一边开发A服务一边对外发布公用的包,这是一个koa项目的目录,问题来了,除了node_modules,这个项目里面可以有几个包,有人会说一个项目就是一个包。

在routes里面添加一个路由地址,调用services里面的方法

const router = require('koa-router')()
const FooService = require('services').FooService

router.get('/queryFoo', async (ctx, next) => {
  let fooService = new FooService()
  ctx.body = await fooService.queryFoo()
})

module.exports = router

写一个service

class FooServices {
  async queryFoo () {
    return 'foo'
  }
}

module.exports = FooServices

下面开始改造:
在services里面加入index.js和package.json,将FooService.js通过index.js曝露出来,这样services我们就拆成了一个包了

然后直接把services扔到node_modules里面,修改下routes里面的index.js的引入

const router = require('koa-router')()
const FooService = require('services').FooService //修改

router.get('/queryFoo', async (ctx, next) => {
  let fooService = new FooService()
  ctx.body = await fooService.queryFoo()
})

module.exports = router

那么routes可不可以变成包、models可以不可以,当然可以,虽然不用这么极端的把一切都拆成包,但把services拆成包,效果是很不错的,如下图

Node.js项目拆包工程化基础指南_工程化指南教程

在这里我们可以这样定义, A服务在开发的同时,也开发一个公用的下沉式的服务包,开发完services后,A组可以继续开发controller、view层,B组在services基础之上就可以开始开发了,不需要等A服务都开发完成,更高效,团队间的配合更加灵活。

实现

上面只是提供了一种想法,实现这个想法还需要一个过程,先说产生了什么问题:
问题1,如果我们把services单独拆出来变成一个项目,可以…但是我们开发的时候回很郁闷,会遇到: 修改services发包、下包、调试、修改、发包、下包、调试…真是好麻烦啊~~~
那么如何在一个项目里面解决包依赖,我们来看一种实现的思路:
先编写一个js脚本,将services文件夹通过创建符号链接,链接到node_modules

#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const rootPath = process.cwd();
fs.symlinkSync(`${rootPath}/services`, `${rootPath}/node_modules/services`, 'dir');

随便配置个命令将调用脚本命令配置到package.json中

  "scripts": {
    "start": "node bin/www",
    "dev": "./node_modules/.bin/nodemon bin/www",
    "prd": "pm2 start bin/www",
    "test": "echo \"Error: no test specified\" && exit 1",
    "l": "node bin/link"
  }

使用命令执行脚本

npm run l

建立符号链接后,修改services里面的代码,node_modules里的services也会跟着变,这样我们就解决了上面的问题。
注意:这里只是提供思路,要完善功能,请有兴趣的小伙伴自己实现。

问题2,上面的项目里我们只同时多开发一个包,如果在一个项目里面同时开发几十个包,引包和发布,岂不是每次都要做几十次,这个问题还好,更恐怖的是,如果这几十个包还有引用关系….

在services里面有两个包,下面我们用zz-foo-services引用下zz-bar-services,多个services之间的引用是十分常见的。

问题来了,zz-bar-services就没有发布,从哪引用啊,难不成又建个脚本用来建符号链接,那要是包多,几十个包都有依赖关系,怎么建链接啊~~~
这里我们就需要使用lerna来帮我们管理一个项目的多个包的包依赖、包发布等,例如babel项目的开发就是使用lerna进行包管理、发布的,下面我们来看下lerna的用法。

安装 lerna

npm i -g lerna

初始化

在项目根目录执行命令

lerna init

在根目录建一个packages,是lerna管理的跟目录,我们把刚才的包移动到这个目录下

使用命令将packages里面的包的依赖安装好

lerna bootstrap

这个命令会执行npm i,还有创建符号链接。

注意:这里packages里面的包链接到node_modules,有兴趣的小伙伴自己动手试试。
问题3 多包的版本管理,这里我们使用lerna publish命令将包批量发布出去,这里我们不举例子,有兴趣的小伙伴可以自己都动手试试。

总结

通过对node.js的项目工程化的处理,我们可以在一个项目里面同时开发多个包,管理多个包,使得更紧密的团队协作,包的高效拆分,包的管理与优化的开发过程,本文中笔者只是提供了工程化的部分思路,要想产出最佳实践还需要做很多的优化。

来自:大转转FE

作者:孔令涛  

海计划公众号
(0)
上一篇 2020/04/03 19:37
下一篇 2020/04/03 19:37

您可能感兴趣的内容

  • stackoverflow基础知识一个与程序相关的IT技术问答网站。用户可以免费提交问题,浏览问题,索引相关内容等

    stackoverflow基础入门 官方网址:https://stackoverflow.com/ 简介描述:一个与程序相关的IT技术问答网站。用户可以免费提交问题,浏览问题,索引…

    2020/03/05
  • happypack基础知识_提升 webpack 的构建速度

    happypack基础知识 GitHub:https://github.com/amireh/happypack 简介描述:提升 webpack 的构建速度 由于有大量文件需要解析…

    2020/03/06
  • 什么是解构赋值?指南攻略_变量小白基础

    解构赋值给我们一种新的变量赋值方式,主要可以利用数组解构赋值和对象解构赋值。它的用途包括:交换变量值,提取函数返回值,函数参数定义,默认值设定等等,给我们编程带来便利。解构赋值的用途1.交换变量的值
    var x = 1;
    var y = 2;
    [x,y] = [y,x];//成功交换x,y的值。2.提取函数返回的多个值(实现快速的提取对应的值)
    functi

    2020/03/29
  • PHP微服务集群搭建基础教程_微服务菜鸟教程

    近些年微服务架构大行其道,趁着最近有时间,来捣鼓捣鼓微服务是怎么一回事。微服务架构微服务的概念由 Martin Fowler 于2014年3月提出:微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间相互协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务和服务之间采用轻量级的通信机制相互沟通。每个服务都围绕着具体的业

    2020/03/26
  • CSS中层叠上下文菜鸟教程网_上下文基础教程

    前言在有些 CSS 相互影响作用下,对元素设置的 z-index 并不会按实际大小叠加,一直不明白其中的原理,最近特意查了一下相关资料,做一个小总结。层叠上下文与层叠顺序层叠上下文(stacking content)是 HTML 中的三维概念,也就是元素z轴。层叠顺序(stacking order)表示层叠时有着特定的垂直显示顺序。层叠准则谁大谁上当具有明显

    2020/03/21
  • 微内核架构在大型前端系统中的应用基础入门_架构使用攻略

    只讨论架构,不讨论框架1、名词解释由一群尽可能将数量最小化的软件程序组成,他们负责提供、实现一个操作系统所需要的各种机制和功能。这些最基础的机制,包括了底层地址空间管理,线程管理,与进程间通讯。2、设计理念将系统的实现,与系统的基本操作规则区分开来。它实现的方式是将核心功能模块化,划分成几个独立的进程,各自运行,这些进程被称为服务。所有的服务进程,都运行在不

    2020/04/03
  • 优雅解决微信小程序授权登录需要button触发基础知识教程_小程序基础入门

    聊一聊最近的一个项目,这个项目是一个收书、售书的小程序,有商城、专栏、信息发布论坛等功能。虽然不是面向所有用户,但要求无论用户是否授权都皆可使用,但同时也要求部分功能对不授权的用户限制开放。问题总结如下首先是小程序不授权也可以使用,但是只有部分功能可用,比如浏览第二问题是在用户想进一步使用小程序时需要获取用户授权获取到用户授权的时候该如何处理跳转解决方案1.

    2020/03/31
  • canvas 兼容性和尺寸菜鸟教程下载_canvas入门教程

    一,兼容性 1.ie9及其以上版本 2.canvas 兼容性判断方式

    you browser not support canvas!


    如果不兼容canvas,canvas 标签会被浏览器解析为自定义标签,显示标签内提示信息如果兼容canva

    2020/03/26
  • js是面向对象还是基于对象?小白帮助_对象菜鸟指南

    以前感觉这两个在本质上没有什么区别,面向对象和基于对象都是对一个抽象的对象拥有一系列的行为和状态,本质都是对象层。拜读了winter老师的音频和文档,颇有收获。对象:一个可以触摸或者可以看见的东西;人的智力可以理解的东西;可以指导思考或行动(进行想象或施加动作)的东西。对象的特点:对象具有唯一标识性:即使完全相同的两个对象,也并非同一个对象。对象有状态:对象

    2020/03/30
  • 元素的显示与隐藏基础指南_元素使用说明

    1. 如果希望元素不可见,同时不占据空间,辅助设备无法访问,同时不渲染,可以使用 标签隐藏
    此时,图片 1.jpg 是不会有请求的。 标签是不支持嵌套的如果希望在 标签中再放置其他不渲染的模板内容,可以试试

    2020/03/20
  • 你不一定知道的head标签入门基础教程_标签小白基础

    先来梳理一下本文的目录结构 现在我将详解head标签和它六个子标签的属性和作用,请耐心看完,会有很大的收获哦!一、 head标签可选属性:属性值描述profileURL一个由空格分隔的 URL 列表,这些 URL 包含着有关页面的元数据信息。说明:·文档的头部经常会包含一些 meta 标签,用来告诉浏览器关于文档的附加信息。在将来,创作者可能会利用预先定义好

    2020/03/29
  • JS 的 Document对象入门指南_对象入门百科

    Document 对象是是window对象的一个属性,因此可以将document对象作为一个全局对象来访问。当浏览器载入 HTML 文档, 它就会成为 Document 对象。Document对象的 属性和方法1.html元素和body对象  document.documentElement 获取html元素,文档的根节点  document.body

    2020/03/26
  • 微信和支付宝中的一些常用方法封装入门基础知识_封装小白知识

    最近做了同一个样子的小程序的支付宝版本,现在如果想想是开发两次的话心里应该是很难受的。去年11月12月份左右开发了两个微信小程序是一个在超市买商品的,一个用户版本,一个商户版本的。我们团队看到了uniapp这个东西,然后用这个东西写了一点demo,然后就决定采纳这个东西开发微信小程序了。这个开发体验真的是让人揪心,因为编译起来太慢了,就是这边保存完代码,你如

    2020/03/24
  • Plottable.js小白常识_基于 D3 的图表模块组件库

    Plottable.js小白常识 官方网址:http://plottablejs.org/ GitHub:https://github.com/palantir/plottable…

    2020/03/06
  • 选择开源项目什么很重要?入门攻略_开源使用说明

    开发人员在决定是否使用某个开源项目时考虑到的比较重要的事项是什么?代码质量?安全性?好的文档?上述因素都很重要,但根据 Tidelift 和 The New Stack 的联合调查,控制着开源项目的开源许可证才是最需要考量的因素。86% 的受访者认为“可接受的开源许可证”对于决定使用开源软件包来讲非常重要,其中 61% 的人将其描述为“非常重要”。在超过千名

    2020/03/23
  • statusfy菜鸟知识_一款优秀的状态管理页面

    statusfy菜鸟知识 官方网址:https://statusfy.co/ GitHub:https://github.com/bazzite/statusfy 简介描述:一款优…

    2020/03/06