分类
开源 技术

为什么要投资开源项目

在群里聊起开源项目,说到现在投资者很喜欢投做开源软硬件公司,有同学问:“投资开源项目会有哪些形式获得回报呢?”我觉得一句两句说不清楚,所以写一篇博客作答。

开源软件的优势

先说软件。开源软件因其免费、开源的特性,越来越受到各个级别的公司、团队、开发者的欢迎。因为免费,我可以试试,好用就继续用,不好用就换一家;因为开源,如果使用过程中发现一些小问题,我可以自己修、自己适配,大大提升开发效率;同时,由于开源,用户可以更方便地对代码进行安全审计,安全性也会大大提升。

所以,相比于传统付费商业软件,开源软件的用户量一般要大很多,而且往往成长非常快。当使用人数上升到一定级别的时候,开源软件又具备了一些新的优势。

开源软件的用户量很大,使得开源软件的问题更容易被发现,也更容易被修复

会有很多用户贡献使用文档,也会有很多用户在各种问答平台贡献问题解决方案,也会有很多用户写各种教程。如今是视频年代,自然视频领域也有很多用户主动贡献

开源软件的初用成本很低,使得开源软件可以进入更多行业,获得更多使用场景,接触到更多的设备,尤其是新设备。比如,当苹果 iOS 取得成功之后,Google 立刻基于 Linux 开发了 Android 系统,然后理所当然的击败了闭源的 Symbian 和 Windows,成为移动双雄之一,并在移动互联网领域彻底接管了微软的系统软件地位。物联网方面,更是 Linux 各种发行版一枝独秀。

开源软件的用户可能比作者更厉害,使得开源软件可以实现超越式发展。比如当年的 Backbone,它最初的成功得益于 API 设计,但是本身代码质量一般。后面有了大量用户贡献生产实例和改进代码,慢慢在代码质量上也远超一般项目。

开源软件的版权属于全世界,很多厂商都愿意投资开源软件,因为不用担心被竞争对手用专利限制;从国家层面更是如此,开源就不怕卡脖子。《“十四五”软件和信息技术服务业发展规划》解读 中重点强调了开源生态。

开源硬件也差不多,现在不光是开发板,机械臂什么的也都有开源项目,动手能力强者照着完全可以 DIY 出来。对于我国这样有完整工业体系的制造业大国来说非常有优势。

投资开源产业的价值

上面简单梳理了开源软硬件对比传统收费软件行业的优势,接下来深入分析一下投资者,包括投身开源软件的创业者能从中获得哪些特有价值。

获得事实标准

前面说过,开源软件发展的更快,触及行业更广。所以开源软件更容易形成事实标准。比如,现在服务器上装的,几乎都是 Linux;当年 RIA(Rich Internet Application,指功能更强大效果更出彩的网络应用)的开创者、商业软件 Flash,遭遇几乎全开源的 HTML5 挑战,如今坟头草一人多高,很多新晋前端开发者听都没听说……

取得行业标准之后,再想让行业朝着自己喜欢的方向发展,就容易很多。比如 Chrome,如果你对比一下 MV2 阶段的 Browser Extension API,会发现,它基本就是照搬自 Chrome Extension API。结果就是,Safari、Firefox 的扩展也必须兼容 Chrome 规范;Chrome Extension MV3 推出后,其它浏览器开发厂商都要迅速跟进。

如果你需要某个功能,而规范还不支持,那也没关系。你完全可以调整产品线的优先级,让你的需求优先被满足。

掌握制定规范的权力

有时候,事实标准没有那么好拿到,但是只要掌握一定程度的市场,就可以参与规范的制定。能够参与制定规范,就能提前布局产品的设计和生产,从而在后面的竞争中处于优势。相信大家都记得当年的 4G、5G 规范之争吧?

开源不挣钱,但开源软件公司可以挣钱

开源并不是做慈善,做开源软件的公司当然可以赚钱。事实上,目前成功案例很多。比如红帽,比如 Automatic(WordPress 就是他们家的产品,本博客就是用 WordPress 搭的),还有 MySQL、PingCap、F5 等等,不胜枚举。

这些公司的商业模式大约是:

  • 打造一款开源软件,利用开源软件的优势赢下市场
  • 提供基于自家开源软件的服务,比如技术支持、定制开发、咨询培训等等
  • 除了开源免费的社区版,还有给付费用户的高级定制版,一般来说功能更丰富、性能更好

所以投资开源软硬件企业,完全不用担心投资回报。

不惧巨头垄断,突破行业壁垒

开源软件挑战巨头取得胜利的例子更是举不胜举。跟众多“如果 BAT 要做,你怎么办?”的行业比起来,开源软硬件天然不怕专利限制,也不担心巨头在同领域竞争。开源软件即使失败,也是因为自身质量不好,或者瞄准的领域营养不足,或者败于其它开源项目。

国家政策扶持

前面说了,作为 IT 行业的后来者,我们国家要想追上行业壁垒森严的先行者,开源是我们的第一选择。所以未来很长一段时间,开源都会是国家关注且支持的领域。

总结

时代不同了,以前看起来只能用爱发电的开源软硬件也可以一边造福全人类一边造福自己家;开源从业者也可以不靠捐款过活。当然开源也有不少问题,限于篇幅,我就不在本文里讨论了。

上面都是我从一个行业爱好者的角度,做的民科式总结。纰漏错误都有可能,欢迎指出、讨论。

分类
js

聊聊 NPM 里的版本号和依赖

好像一直没有写过版本号和依赖相关的内容,偶尔会有同学问,所以写一篇总结一下。

0. Semver

我们目前使用的版本规范通常基于 Semver,语义化版本。官方网站:语义化版本 2.0.0 | Semantic Versioning (semver.org)。按照其规则,版本号的结构应该是:

主(大)版本号.次(小)版本号.修正(补丁版本)号

其中,

  • 主版本号一般包含架构和 API 的变化。如果 API 出现重大变化,使得依赖它的软件要重构,那么就要体现在大版本号里。不过现在的代码仓库很少有破坏式重构,API 一般能够在至少 2、3 个大版本里保持稳定。所以主版本号变化一般出现在大型重构时,仓库内部的代码架构和组织形式出现重大变化,或者基于不同系统,就需要升级主版本了。
  • 次版本号一般表达功能变化。架构没有变化,原有 API 也基本维持不变,只是新增了功能。这个时候就会上调次版本号。
  • 修订号一般表示修复 bug。

0.1 年代版本号

另一种流行的版本号规范是年代版本号,比如 Ubuntu,每年会发布两个版本,目前是 21.04,10月份会发布 21.10。偶数年的 .04 版本会最终成为 LTS,长期维护版本;奇数年的版本和 .10 版本则只维护半年,里面包含各种最新的软件组件,方便喜欢尝新的用户。

前端常见的软件和库,包括 node.js、Angular、Electron 也用这种方式确定版本号。

1. 依赖中指定版本号

我们在项目中可能会使用大量开源代码,这些开源代码通常都会使用包管理工具(比如 NPM,node package manager)安装和管理。

在 package.json 里,我们可以使用几个运算符告诉 NPM 我们希望怎么使用这些依赖:

  • 不写,repo: '1.0.0'。要求使用 1.0.0 版本的 repo,必须完全一致。
  • ~repo: ~1.0.0。要求大版本为 1,小版本为 0,修订版本不限制,比 0 高就可以。
  • ^repo: ^1.0.0。要求大版本为 1,小版本高于 0 就可以。

一般来说,使用 npm i repo 安装的依赖,默认规则是 ^;使用 npm i repo@version 安装的依赖,默认规则是写死。

2. 升级依赖

这个世界上不存在没有 Bug 的代码,也没有功能完善的代码。使用开源仓库,我们就要考虑升级依赖。一方面可以使用新功能,一方面可以解决 bug。

通常来说,直接使用 npm update 就能升级项目依赖,NPM 会按照(1)里设定的规则更新依赖。

3. 升级依赖的大版本

只使用 npm update 无法升级大版本。原因如上文所述,大版本可能包含破坏性的 API 更新,很容易导致 dev/build 失败,作为工具无法妥善处理,必须交给开发者手动完成。

很多同学因此不愿意升级大版本。但我建议大家还是要找机会做升级,尤其工具链,比如 webpack、babel。这些工具很多时候有时效性,长期不升级会导致各种问题。而且,升级工具链本身这也是我们偿还技术债务的好机会。

其实升级工具链的大版本并不复杂,大多数半天就搞定了;如果没有用到偏门功能,甚至可能直接升级就能跑。——通常来说,开源软件的作者面对使用频率高的功能,会比较保守;没人用的功能改动就会大刀阔斧一些。

升级依赖需要指定大版本,比如从 webpack 4 升级到 webpack 5,可以使用 npm i webpack@5,这样会安装大版本是 v5 的最新版本。这里有个小建议,公司的生产级别的项目,最好不要着急升级,等到 X.2 X.3 这样基本稳定的次版本发布后再升级,可以避免踩很多坑。

一般来说,开源仓库的官方也会提供迁移指南,比如 webpack v4 to v5。只要你有 v4 的配置经验,照着指南操作,大多数时候都能顺利完成。

4. 解决 npm audit 问题

开源仓库的安全问题日趋严重,GitHub 和 NPM 都会帮我们检查依赖,并且根据已知的安全问题列表发出警告。所以在安装依赖时,我们经常能看到类似下面这种警告信息:

found 5 moderate severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

这个时候,我们应该执行 npm audit 查看所有的审计结果,可能得到如下的报告:

┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate      │ Regular expression denial of service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ glob-parent                                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >=5.1.2                                                      │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ @vue/cli-service [dev]                                       │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ @vue/cli-service > webpack-dev-server > chokidar >           │
│               │ glob-parent                                                  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/1751                            │
└───────────────┴──────────────────────────────────────────────────────────────┘

这个报告说明有问题的包是 glob-parent,它由 webpack-dev-server 引入,又因为 @vue/cli-service 而最终成为项目的依赖。很明显,它是 @vue/cli 的组成部分,是前端工具链的一环。那么通常来说,它的危害层级很低,多半不会影响到项目整体安全性。

如果是 node.js 项目,就要小心了,服务器和后端都是安全重灾区,后果可能会很严重。这个时候,你可以往上翻,找到这些报告的最前面,如果可以修复,NPM 会告诉你应该运行什么命令更新问题依赖。如果不能修复,就要自己想办法了。

比如,你可以移除出问题的依赖,不过多半不可行。或者,我比较常用的方案是,在 GitHub 上找到依赖仓库,自己 fork 一份,然后升级其中的依赖,然后发布一个我个人的版本,接下来就用我自己的版本。等到官方修复后,再用回官方版本。

5. 总结

最后按惯例总结一下。依赖是我们软件产品的重要组成部分,它们的版本事关重大,必须给予足够的关注。至少,每个月要检查一次依赖的安全审计问题,如有需要,就升级依赖。

我们自己写代码的时候,也要遵守 Semver 的规定,适时上调版本号,让版本号能表示代码的发展情况。

分类
作品

超全面全栈入门项目:fastest

TL;DR.

前些天做了个覆盖面很广的项目:FastTest。涉及到静态网站、node.js 后端 API、响应式、多语言、Vue3 全家桶、前端工具链、nginx 配置等一系列技术,都是很基础的应用,相信对大家入门很有帮助。

GitHub:https://github.com/meathill/fasttest

欢迎阅读学习,有任何问题均可提问或提 issue。


前些日子有个朋友找到我,想请我帮他做个项目。我看了一眼需求,不太想接:这个项目太小,要多了不合适;要少了感觉又不值当——有那时间还不如砍两把胖虎。

后来我仔细一想,感觉这个项目很适合拿来做教程,而且是非常全面的全栈入门教程。

先来看需求。他的需求很简单:开发一个测速应用。用户打开页面,点击按钮,然后下载一些东西,下载完成之后,告诉他他的网速是多少。与之前的测速产品不同,这个应用不下载大文件,而是从各种 CDN 下载 JS 库和 SDK,因为大部分 web 应用都依赖这些资源,所以可能更接近真实体验。

关于需求我们不深入讨论(我觉得挺有道理,但也未必有道理到哪儿去……),只看实现。为了满足这个需求,我们需要开发这些东西:

  1. 静态页,让用户能够测速。这就需要:
    1. HTML+CSS+JS,静态资源
    2. 响应式,支持桌面和移动端
    3. 多语言支持
  2. 后台,能调整待测资源、修改翻译、控制广告、查看数据。这就需要:
    1. 友好的 Admin panel:vue 全家桶
    2. 后端 API:express.js + node.js server
    3. 自动发布静态页(webpack 前端工具链)
  3. 部署到服务器:
    1. 静态服务供给用户端页面和资源
    2. SPA 服务,提供后台 Admin Panel 给管理员
    3. 反向代理 express.js API
    4. 配置 CDN
  4. 其它,比如版本管理、前端预处理工具,等等

这些东西可以说是非常全栈,除了没有移动 App、没有数据库操作,其它 Web 开发的东西都用到了。而且涉及到技术也都很基础,没有特别深入的东西。再加上,这个项目会上线,会迭代,是个真实产品。所以,很适合拿来做教程,大部分观众,不管是什么背景,都可以拿来入门。

于是我就答应了,然后断断续续在直播的时间把它做了出来。当然还有一些问题,不过大部分功能都就绪了。

项目放在 GitHub 上:https://github.com/meathill/fasttest,有需要的同学请自由取用。对其中任何技术点有问题都可以提问或者开 issue。

网站地址在 https://afasttest.com

视频还需要一些时间来整理,将来慢慢放出来吧。着急且有时间的同学可以自行从百度网盘下载:https://pan.baidu.com/s/1KPuCM-9gPd0hQsr5Df_PnA 提取码: w8f2。

分类
技术

npm 支持开发者添加募款链接

昨天随手升级个人首页的依赖,更新完之后,npm 提示:

6 packages are looking for funding
  run `npm fund` for details

如果你执行 npm fund,可以看到类似这样的信息:

your-repo@0.1.0
├─┬ core-js@3.4.2
│ ├── type: opencollective
│ └── url: https://opencollective.com/core-js
├─┬ eslint@6.7.0
│ └── url: https://opencollective.com/eslint
└─┬ swiper@5.2.1
  ├── type: patreon
  └── url: https://www.patreon.com/vladimirkharlampidi

opencollective 和 patreon 都是众筹网站,只不过众筹的内容不是实物商品,而是支持你喜欢的创作者,无论他是摄影师、画家,还是开源软件作者。据说 Vue 的作者尤雨溪每年可以从 Patreon 上获得将近 $20w 的捐赠,这笔钱可以帮助他以独立身份继续开发 Vue,还可以雇佣一名全职开发者帮助他把这份工作做得更好。

我去 NPM 官网找了一下,npm fund 的文档还没更新上去,只找到这篇 RFC: Add funding support to package.json,大意是包开发者可以在包的描述文件(package.json)里放上一段募款声明,这样包的用户在安装的时候,就会看到我开篇写的那些文字。提醒包的开发者:你们可以通过捐赠的方式,表达对依赖开发者的感谢。

我觉得这种形式挺好的。当然,有些人可能看不惯这种有“伸手嫌疑”的行为,但是,与其在无酬工作中纠结、放弃自己的项目、甚至被别有用心的人利用埋后门,任何不影响安全性、不增加使用负担的变现方式都是合理且值得鼓励的。

希望开源软件开发者越过越好,开源基建开发者越过越好,世界越来越好。

分类
jQuery

推荐类库 jquery-ui-touch-punch

正如我在前一篇文章《前端框架点评》中所说,jQuery UI库中最有用的是那几个 xxxable,而不是里面的组件(因为自带样式且较丑)。所以当它们在某些环境下没法正常工作就比较老火了,比如draggable,在iPad之类的移动设备中,就无法使用,因为它没有针对触摸事件进行侦听。

经过Google,发现有人已经解决了这个问题,就是我说的jquery-ui-touch-punch,开源,代码托管在github。直接在html中引用jQuery UI和这个补充包,后者会覆盖前者的实现,帮助它支持触摸拖动。感兴趣的同学可以到这个页面去尝试。感谢它的作者furf

顺便说下我对开源、免费、盗版的态度。开源和免费都是好东西,影响着改变着我们的世界。但是决定一个作品一段代码一款产品是否开源免费的人,只能是其作者或者其版权拥有者,别人无权“替”他们做出选择。换句话说,我是反盗版的,对于海盗湾也无甚好感,对于那些有意无意忽视盗版危害反而替海盗湾摇旗呐喊的人,很是反感。

现在的版权政策和专利制度,确实在某种程度上阻碍着创新,也给流氓(比如苹果)留下可乘之机。但是在更好的方案出台之前,我们只应该尽力输送好的原创作品给开源社区,而不是盗版他人的东西,再冠以自己“开放、分享”之名。那样太无耻了。