Koa2源码开篇

168 阅读2分钟
原文链接: zhuanlan.zhihu.com

初衷

最新用Koa2写了一个项目, 本着想更加深刻熟悉Koa2于是想好好学习下它的源码以及设计思想,这篇专栏特点就是非常详细,逐行解读,因为源码本身也不多。

题外话: 用Koa写了一个项目才知道为什么大家都喜欢基于Koa去封装一个上层框架,确实单用Koa+集成插件的方式真不适合多人协作。


目录结构

Koa2源码的版本是V2.8.1。

- benchmarks: 基准测试
- docs: Koa使用的一些文档介绍
- lib: 源码目录
- test: 单元测试
- package.json

入口文件

看一个开源项目, 我们一般都是先大致看下目录结构,然后开始找到入口文件,一般从package.json文件去找到入口,这里主要介绍几个字段。

{
  "main": "lib/application.js",
  "scripts": {
    "test": "egg-bin test test",
    "test-cov": "egg-bin cov test",
    "lint": "eslint benchmarks lib test",
    "bench": "make -C benchmarks",
    "authors": "git log --format='%aN <%aE>' | sort -u > AUTHORS"
  },
  "engines": {
    "node": "^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4"
  },
  "files": [
    "lib"
  ]
}
  • main字段: 用来指定程序的入口文件
  • engines字段: 指定项目运行的node版本范围, 如果你限制范围即为*。
  • files字段: 一个数组, 内容是模块下的文件名或者文件夹名,如果是文件夹名那么该文件夹下所有文件都会包含在内(除非某些文件被其他配置排除在外)

扩展知识

  • CommonJS package的标准目录结构
- 一个package.json文件需要置于项目根目录下面
- 二进制文件需要放在bin目录下面(可选)
- 代码入口文件默认index.js, 其他源代码需要放在lib目录下面
- 文档放在doc目录下面
- 单元测试代码放在test目录下面
  • 如果files字段包含某些文件,但是可以通过.npmignore配置(优先级高)来排除
  • 关于main字段与module字段区别

简单理解就是:

  1. main: 基于CommonJS package.json规范一开始就默认支持的
  2. module: 目前该字段还不是规范, 只是一个提案,不过支持的话也是指日可待。

我们现在都知道ESM是JS支持的默认模块机制,现在打包工具如webpack4.x,rollup等支持Tree Shaking,

但是使用Tree Shaking的前提就是需要使用ESM的写法,所以我们如果发布一个支持ESM的npm包, 那么就是通过module字段

所以我们经常会看到一些开源库这样的写法,如Vue.js

{
  "main": "dist/vue.runtime.common.js",
  "module": "dist/vue.runtime.esm.js"
}

所以这就相当于一个包同时支持两种模块规范的版本。 如果打包工具遇到package.json文件:

  1. 如果打包工具已经支持module字段,会优先使用ESM规范的版本,可以启动Tree Shaking。
  2. 如果打包工具还不能识别module字段,就会使用我们已经编译好的CMJ规范的版本。