FCon7折倒计时最后一周:日程已上线70%!查看详情>>> 了解详情
写点什么

前端应用能从 Node.js 学到什么

  • 2015-12-25
  • 本文字数:2410 字

    阅读完需:约 8 分钟

Will Binns-Smith 是一位热爱 JavaScript 的全栈工程师,喜欢通过技术来解决实际问题。他开发了 Bonobos.com 的前端购物车功能。Will 喜欢与设计师一对一工作,将 PC 网站转换为针对更小的触摸设备的站点。近日,Will 撰写了一篇文章,谈到了Node.js 有哪些做法和特性值得前端应用学习。

Web 平台能从 Node.js 学到什么这篇文章中,我们探索了由开发者为开发者所创建的小范围抽象所带来的好处。在这篇文章中,我们来了解如何以及为何应该将这种开发风格引入到你自己的 Web 前端中。

选择你自己的方式

作为小模块的用户,如果你不接受依赖所做的变动,那么你可以换另一个依赖。也许应用会使用某个模块的新版本(比如说 2.x),而应用的另一个依赖使用的却是老版本(比如说 1.x)。在 Node 中,由于依赖的查找是从邻近的 node_modules 目录开始,然后沿着文件系统逐级向上,即便需要不同版本号的相同模块,这种方式也是可以满足需求的。如果版本匹配,那么只会使用一个副本。

浏览器中的 npm 模块?这难道不是 Node 的事情?

你可能想知道如何能在不使用成百上千个 script 标签或是不在 RequireJS 配置文件中使用那么多条目的情况下维护如此多的依赖。也许你还想知道如何在浏览器中使用来自于 npm 的模块轻松创建 SVG 元素。诸如 Browserify Webpack 等现代工具让这件事成为了可能,他们会通过 Node 所用的相同的 CommonJS require 语句来追踪应用的依赖图。他们使得一个大型包文件中的模块彼此可见,而你在页面中则可以通过单个 script 标签将其引入进来。

另一个常见问题就是这么做会不会增加向浏览器传送的 JavaScript 文件大小。在新版的 npm 中,这种模块树采用了扁平形式,同时又会向应用中的每个依赖提供所需的版本。借助于这种方式,你不会传递任何不需要的库的副本,同时又能满足每个模块的要求。此外,还有一个名为 rollup 的更加新颖的包管理器,它使用了 ES2015 模块格式,只打包你所导入的模块的子集。

我所认识的很多人都对将多个 jQuery 版本放到浏览器中这个想法感到惊讶。没错,这么做确实有些恐怖,虽然做了精简与 gzip 压缩,但 jQuery 依然会有 30KB 的大小。不过,传输 2 个、3 个、甚至 4 个 2KB 大小的库的副本相比起来却是微不足道的,特别是这么做能够避免手工解析依赖和升级 jQuery 以及安装的那些插件。即便如此,你也只应该在应用中包含了很多模块,并且这些模块又依赖于很多不兼容模块的情况下才这么做,因为 npm 3 在默认情况下会尽可能打平模块目录。你可以通过简单的安装随意使用 npm 注册的 100,000 多个模块。

界限在哪里

我们先来了解一些术语:包指的是可以发布到 npm 注册中心或是通过 git 仓库使用的单元。不过在 CommonJS 中,模块与文件是一一对应的。因此,一个包可以包含多个模块,不过通常情况下,一个 npm 包本身就是一个模块。

定义包的职责是最困难的一件事。如果包的范围过大,那么就会出现破坏性的改变,其后果就是破坏了生态圈。与之类似,如果一个包有很多依赖,那么破坏性的改变与 Bug 就会导致整个系统出现级联更新,无论开源还是内部使用都是如此。在设计包的范围时,一个好的原则就是软件组件的内聚性 %E3%80%82%E6%9C%AC%E8%B4%A8%E4%B8%8A%EF%BC%8C%E5%A6%82%E6%9E%9C%E5%87%A0%E4%B8%AA%E7%BB%84%E4%BB%B6%E4%BC%9A%E4%B8%80%E5%90%8C%E5%8F%98%E5%8C%96%EF%BC%8C%E9%82%A3%E4%B9%88%E4%BB%96%E4%BB%AC%E5%B0%B1%E5%BA%94%E8%AF%A5%E5%B1%9E%E4%BA%8E%E5%90%8C%E4%B8%80%E4%B8%AA%E5%8C%85%E3%80%82%E5%A6%82%E6%9E%9C%E4%B8%8D%E6%98%AF%EF%BC%8C%E9%82%A3%E5%B0%B1%E8%AF%B7%E6%8A%BD%E5%8F%96%E5%87%BA%E6%9D%A5%EF%BC%81">https://en.wikipedia.org/wiki/Cohesion_(computer_science)。本质上,如果几个组件会一同变化,那么他们就应该属于同一个包。如果不是,那就请抽取出来!

请记住,借助于 npm 与大多数包管理器,一个包不一定需要一个专门的仓库。如果过多的 Pull Request 的负担阻碍了发布新模块的流程,那就请考虑创建新的仓库,同时发布每一个包。Babel 是个开源的 JavaScript 编译器,它通过这种方式在单个仓库中维护了 100 多个包,极大地提升了效率,同时又将每个包发布到了 npm 中。

值得注意的是,Bower(另一个 JavaScript 包管理器)的一个限制是它使用 Git 仓库(或是 tarballs)作为接收模块代码的方式,因此它需要为每个包都创建一个仓库。我的建议则是使用 npm

尝试

通过小模块来构建应用要比你想象的简单多了。你的应用可能已经有了很多抽象,确定哪些抽象应该拥有自己的包其实是个很困难的事情。首先,如果只抽象了平台,并且提供通用目的的门面,那么最好提供一个开源的包。诸如 GitHub 与 Bitbucket 等服务都非常适合于这一点,如果使用的是 Node 或是浏览器,那么你当然应该将自己的工作成果发布到 npm 注册中心了。当然,其他语言的生态圈也拥有自己的包管理解决方案。

如果应用为内部业务逻辑提供了可重用的抽象,比如说对内部服务或是 API 的包装器,那么组织中的其他人就会从独立的包中获益匪浅。在 Atlassian,我们有很多小型的 JavaScript 客户端来访问报表或是分析等服务。此外,还有一个通用目的的包,它用于在新产品中快速开始 Atlassian Connect 的实现。对于源代码管理来说,我的建议是不要以每个仓库作为基础,这样才能创建出由很多小模块所构成的内部生态圈。Bitbucket Cloud 与 Bitbucket Server 都可以随着团队规模的变化而水平扩展。在发布包时,npm 在其云服务上提供了私有模块,并且提供了自托管的服务,从而作为源代码仓库管理的一个有益补充。你甚至还可以通过 Bitbucket Cloud 仓库来方便地安装 npm 模块:只需执行命令 npm install bitbucket:user/repo 即可。

一旦拥有了很多小模块,你就可以对其设计进行迭代,将其组合起来构建出更高层次的抽象。你可以无所畏惧地破坏 APIs,因为现代工具与语义化版本可以确保消费者能够从中作出选择,所有一切都会快速演进。这才是变化的真正意义。

2015-12-25 02:491709
用户头像

发布了 88 篇内容, 共 255.7 次阅读, 收获喜欢 6 次。

关注

评论

发布
暂无评论
发现更多内容

Redisson:这么强大的实现分布式锁框架,你还没有?

华为云开发者联盟

redis 分布式 分布式锁 可重入锁 Redisson框架

对话龙智专家,共探DevSecOps实践难点

龙智—DevSecOps解决方案

DevOps DevSecOps

10个比较不错的 JavaScript 库

编程江湖

JavaScript 前端开发

龙智宣布与ConnectALL成为合作伙伴 进一步提升DevOps解决方案水平

龙智—DevSecOps解决方案

DevOps ConnectALL 价值流 价值流管理

建木持续集成平台v2.1.0发布

Jianmu

DevOps CI/CD 开源社区

【征集令】寻找2022年鸿蒙智联“出行新爆款产品”

HarmonyOS开发者

HarmonyOS

比特币挖矿与源码解析

恒生LIGHT云社区

比特币 区块链 挖矿

大数据开发hadoop之yarn基础架构详解

@零度

大数据 hadoop YARN

超细!细说Zookeeper选举的一个案例(下)

恒生LIGHT云社区

Go golang zookeeper Go 语言

读《思辨与立场》-07思维的标准

wood

28天写作 批判性思维 思辨与立场

书单 | “实战派”系列,每一本都是学好用好一门技术的“航空母舰”

博文视点Broadview

COG云原生优化遥感影像,瓦片切分的最佳实践

华为云开发者联盟

云原生 遥感影像 瓦片切分 云上遥感影像文件 华为云地理遥感平台

【LeetCode】在 D 天内送达包裹的能力Java题解

Albert

算法 LeetCode 12月日更

容器技术正在颠覆传统,重构整个软件世界

巨子嘉

容器 云原生

Go语言逆向技术:常量字符串

华为云开发者联盟

字符串 go语言 字符 逆向技术 常量字符串

你可能不信,52小时能做出7款超酷产品!

LigaAI

程序员 技术 技术人生 技术分享 hackathon

GaussDB(DWS)中共享消息队列实现的三大功能

华为云开发者联盟

线程 数据同步 GaussDB(DWS) 共享消息队列 共享消息

以 Vuex 为引,一窥状态管理全貌

杨成功

JavaScript Vue 大前端 vuex

跟着动画学Go数据结构之选择排序

宇宙之一粟

golang 数据结构 选择排序 12月日更

Java开发Excel数据导入mysql的实用小技巧

@零度

Java MySQL

Android 8.0 下载安装进入【安装未知应用】页面,两步简化一步

阿策小和尚

28天写作 Android 小菜鸟 12月日更

【1分钟调研赢好礼】HarmonyOS Connect 视频课堂用户反馈问卷

HarmonyOS开发者

HarmonyOS

Kubernetes 集群无损升级实践

vivo互联网技术

容器 云原生 服务器集群 Kubernetes 集群

前端开发之JS中filter()的使用

@零度

JavaScript 前端开发

19《重学JAVA》--集合(一)

杨鹏Geek

Java25周年 28天写作 12月日更

被灵魂问倒:这个BUG为什么没测出来?

华为云开发者联盟

测试 bug 文档 测试用例 测试工程师

netty系列之:netty对SOCKS协议的支持

程序那些事

Java Netty 程序那些事 SOCKS 12月日更

龙智第四次荣登“2021上海软件和信息技术服务业高成长百家”名单

龙智—DevSecOps解决方案

上海软件和信息技术服务业

Hive查询的18种方式

编程江湖

大数据 hive

即构科技 RTC 实践与深度解析 | 内容合集

ZEGO即构

音视频 RTC 内容合集 技术实践 技术专题合集

从 WAN 到 SD-WAN 边缘设备的网络架构

devpoint

TLS ssl SD-WAN 12月日更

  • 扫码添加小助手
    领取最新资料包
前端应用能从Node.js学到什么_语言 & 开发_张龙_InfoQ精选文章