Node.js 项目拆包工程化

2024-01-10 04:10
文章标签 项目 js node 工程化 拆包

本文主要是介绍Node.js 项目拆包工程化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

(给前端大全加星标,提升前端技能


作者:大转转FE/孔令涛


背景

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

640?wx_fmt=png

在这幅图中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服务一边对外发布公用的包,我们来看下面这幅图

640?wx_fmt=png

这是一个koa项目的目录,问题来了,除了node_modules,这个项目里面可以有几个包,有人会说一个项目就是一个包,我们先写一个简单的例子,如下图

640?wx_fmt=png

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

 
  1. const router = require('koa-router')()

  2. const FooService = require('services').FooService


  3. router.get('/queryFoo', async (ctx, next) => {

  4.  let fooService = new FooService()

  5.  ctx.body = await fooService.queryFoo()

  6. })


  7. module.exports = router

写一个service

 
  1. class FooServices {

  2.  async queryFoo () {

  3.    return 'foo'

  4.  }

  5. }


  6. module.exports = FooServices

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

640?wx_fmt=png

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

 
  1. const router = require('koa-router')()

  2. const FooService = require('services').FooService //修改


  3. router.get('/queryFoo', async (ctx, next) => {

  4.  let fooService = new FooService()

  5.  ctx.body = await fooService.queryFoo()

  6. })


  7. module.exports = router

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

640?wx_fmt=png

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

实现

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

 
  1. #!/usr/bin/env node

  2. const fs = require('fs');

  3. const path = require('path');

  4. const rootPath = process.cwd();

  5. fs.symlinkSync(`${rootPath}/services`, `${rootPath}/node_modules/services`, 'dir');

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

 
  1.  "scripts": {

  2.    "start": "node bin/www",

  3.    "dev": "./node_modules/.bin/nodemon bin/www",

  4.    "prd": "pm2 start bin/www",

  5.    "test": "echo \"Error: no test specified\" && exit 1",

  6.    "l": "node bin/link"

  7.  }

使用命令执行脚本

 
  1. npm run l

640?wx_fmt=png

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

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

640?wx_fmt=png

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

640?wx_fmt=png

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

安装 lerna

 
  1. npm i -g lerna

初始化

在项目根目录执行命令

 
  1. lerna init

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

640?wx_fmt=png

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

 
  1. lerna bootstrap

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

640?wx_fmt=png

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

总结

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



推荐阅读

(点击标题可跳转阅读)

Google 推出 Node 应用 Web 渲染界面 Carlo

从 1 到完美,用 node 写一个命令行工具

Node 错误处理之挖坑系列



觉得本文对你有帮助?请分享给更多人

关注「前端大全」加星标,提升前端技能

640?wx_fmt=png

喜欢就点一下「好看」呗~

这篇关于Node.js 项目拆包工程化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/589510

相关文章

一文教你如何将maven项目转成web项目

《一文教你如何将maven项目转成web项目》在软件开发过程中,有时我们需要将一个普通的Maven项目转换为Web项目,以便能够部署到Web容器中运行,本文将详细介绍如何通过简单的步骤完成这一转换过程... 目录准备工作步骤一:修改​​pom.XML​​1.1 添加​​packaging​​标签1.2 添加

tomcat多实例部署的项目实践

《tomcat多实例部署的项目实践》Tomcat多实例是指在一台设备上运行多个Tomcat服务,这些Tomcat相互独立,本文主要介绍了tomcat多实例部署的项目实践,具有一定的参考价值,感兴趣的可... 目录1.创建项目目录,测试文China编程件2js.创建实例的安装目录3.准备实例的配置文件4.编辑实例的

springboot集成Deepseek4j的项目实践

《springboot集成Deepseek4j的项目实践》本文主要介绍了springboot集成Deepseek4j的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录Deepseek4j快速开始Maven 依js赖基础配置基础使用示例1. 流式返回示例2. 进阶

SpringBoot项目启动报错"找不到或无法加载主类"的解决方法

《SpringBoot项目启动报错找不到或无法加载主类的解决方法》在使用IntelliJIDEA开发基于SpringBoot框架的Java程序时,可能会出现找不到或无法加载主类com.example.... 目录一、问题描述二、排查过程三、解决方案一、问题描述在使用 IntelliJ IDEA 开发基于

SpringBoot项目使用MDC给日志增加唯一标识的实现步骤

《SpringBoot项目使用MDC给日志增加唯一标识的实现步骤》本文介绍了如何在SpringBoot项目中使用MDC(MappedDiagnosticContext)为日志增加唯一标识,以便于日... 目录【Java】SpringBoot项目使用MDC给日志增加唯一标识,方便日志追踪1.日志效果2.实现步

nvm如何切换与管理node版本

《nvm如何切换与管理node版本》:本文主要介绍nvm如何切换与管理node版本问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录nvm切换与管理node版本nvm安装nvm常用命令总结nvm切换与管理node版本nvm适用于多项目同时开发,然后项目适配no

Ubuntu中Nginx虚拟主机设置的项目实践

《Ubuntu中Nginx虚拟主机设置的项目实践》通过配置虚拟主机,可以在同一台服务器上运行多个独立的网站,本文主要介绍了Ubuntu中Nginx虚拟主机设置的项目实践,具有一定的参考价值,感兴趣的可... 目录简介安装 Nginx创建虚拟主机1. 创建网站目录2. 创建默认索引文件3. 配置 Nginx4

SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法

《SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法》本文主要介绍了SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法,具有一定的参考价值,感兴趣的可以了解一下... 目录方法1:更改IDE配置方法2:在Eclipse中清理项目方法3:使用Maven命令行在开发Sprin

Nginx实现高并发的项目实践

《Nginx实现高并发的项目实践》本文主要介绍了Nginx实现高并发的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录使用最新稳定版本的Nginx合理配置工作进程(workers)配置工作进程连接数(worker_co

Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx