mime-db 源码解析(Npm library)

news/2024/7/7 21:44:20 标签: http, mime, npm, nginx, charset
http://www.w3.org/2000/svg" style="display: none;">

mimedb_Npm_library_0">mime-db 源码解析(Npm library)

文章目录

  • mime-db 源码解析(Npm library)
  • 正文
    • 0. 基本信息
    • 1. 源码解析
      • 1.1 导出模块入口
      • 1.2 MIME 数据来源
      • 1.3 db.json 生成
  • 其他资源
    • 参考连接
    • 阅读笔记参考

正文

0. 基本信息

  • version:v1.51.0
  • 功能:导出标准 MIME 类型映射表

1. 源码解析

1.1 导出模块入口

mime-db 与 mime 类型,同时作为 mime 库构建的强依赖,而实际上 mime-db 的源码没啥内容,实际上就是导出一个 db.json 文件而已

  • index.js
module.exports = require('./db.json')

而这个 db.json 的内容结构如下

https://img-blog.csdnimg.cn/img_convert/b31ca911d0ff7ebb29f344149a5858fc.png" alt="" />

第一层的 key 是 MIME 类型,映射到的对象有来源(source)、编码类型(charset)、是否可压缩(compressible)

1.2 MIME 数据来源

而这个 db.json 的数据又是哪来的呢?实际上作者写了一个类似爬虫的方式,从不同标准的网页抓取类型定义并生成统一格式

https://img-blog.csdnimg.cn/img_convert/65f76786248745ff5f36e075f26dbe9b.png" alt="" />

而抓取下来的文件就如上图被保存在 src 目录下,我们观察 package.json 文件就能看到类似的 fetch 指令

  • package.json
{
  "scripts": {
    "build": "node scripts/build",
    "fetch": "node scripts/fetch-apache && gnode scripts/fetch-iana && node scripts/fetch-nginx",
    "lint": "eslint .",
    "test": "mocha --reporter spec --bail --check-leaks test/",
    "test-ci": "nyc --reporter=lcov --reporter=text npm test",
    "test-cov": "nyc --reporter=html --reporter=text npm test",
    "update": "npm run fetch && npm run build",
    "version": "node scripts/version-history.js && git add HISTORY.md"
  }
}

而解析各网页爬下来的数据这里就不展开,其实就是对数据对象的适配和转换

1.3 db.json 生成

mime-db 做的事实际上就是再根据这些 -types.json 文件进行解析、合并然后生成最终的 db.json 导出

  • /scripts/build.js

首先是导入数据,也就是前面提到的几个 -types.json 文件

var db = {};

// initialize with all the IANA types
/**
 * 初始化所有 -types.json 文件
 */
// ? Read
addData(db, require('../src/iana-types.json'), 'iana');

// add the mime extensions from Apache
addData(db, require('../src/apache-types.json'), 'apache');

// add the mime extensions from nginx
addData(db, require('../src/nginx-types.json'), 'nginx');

// now add all our custom data
addData(db, require('../src/custom-types.json'));

addData 就是简单抽取目标对象的几个指定的需要属性罢了

function addData(db, mime, source) {
  Object.keys(mime).forEach(function (key) {
    var data = mime[key];
    var type = key.toLowerCase();
    var obj = (db[type] = db[type] || createTypeEntry(source));

    // add missing data
    // 添加 obj.charset
    setValue(obj, 'charset', data.charset);
    // 添加 obj.compressible
    setValue(obj, 'compressible', data.compressible);

    // append new extensions
    // 添加 obj.extensions
    appendExtensions(obj, data.extensions);
  });
}

接下来是利用 custom-suffix.json 对 db 对象进行一些属性值的不全

// finally, all custom suffix defaults
var mime = require('../src/custom-suffix.json');
// ? Read
// suffix => s
Object.keys(mime).forEach(function (suffix) {
  var s = mime[suffix];

  // type => d
  Object.keys(db).forEach(function (type) {
    // 相同后缀类型
    if (type.substr(0 - suffix.length) !== suffix) {
      return;
    }

    var d = db[type];
    if (d.compressible === undefined) d.compressible = s.compressible;
  });
});

最后调用 write-db.js 模块生成最终的 db.json 文件

  • /scripts/lib/write-db.js
module.exports = function writeDatabaseSync(fileName, obj) {
  var fd = fs.openSync(fileName, 'w');
  // keys 排序
  var keys = Object.keys(obj).sort();

  /**
   整体结构如下
   {
     "<type>": {
       "<key>": "<val>",
       // ...
       "<key>": "<val>"
     },
     // ...
   }
   */
  // {
  fs.writeSync(fd, '{\n');

  keys.forEach(function (key, i, arr) {
    // "<type>": {
    fs.writeSync(fd, '  ' + JSON.stringify(key) + ': {');

    var end = endLine.apply(this, arguments);
    var data = obj[key];
    var keys = Object.keys(data).sort(sortDataKeys);

    // 无内容直接闭合 }
    if (keys.length === 0) {
      fs.writeSync(fd, '}' + end);
      return;
    }

    // 有内容先换行
    fs.writeSync(fd, '\n');
    keys.forEach(function (key, i, arr) {
      var end = endLine.apply(this, arguments);
      var val = data[key];

      if (val !== undefined) {
        var str =
          Array.isArray(val) &&
          val.some(function (v) {
            return String(v).length > 15;
          })
            ? JSON.stringify(val, null, 2).split('\n').join('\n    ')
            : JSON.stringify(val);
        // "<key>": "<val>"<end>
        fs.writeSync(fd, '    ' + JSON.stringify(key) + ': ' + str + end);
      }
    });
    // }
    fs.writeSync(fd, '  }' + end);
  });

  // }
  fs.writeSync(fd, '}\n');

  fs.closeSync(fd);
};

实际上不得不说这个 write 有点无聊,或许可以使用像是 prettier 直接进行格式化就能生成好看的输出格式了

其他资源

参考连接

TitleLink
mime-db - npmhttps://www.npmjs.com/package/mime-db
jshttp/mime-db - Githubhttps://github.com/jshttp/mime-db
String.prototype.localeCompare() - MDNhttps://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare

阅读笔记参考

https://github.com/superfreeeee/Blog-code/tree/main/source_code_research/mime-db-1.51.0


http://www.niftyadmin.cn/n/735099.html

相关文章

IDEA工具开发一些辅助功能设置

程序员开发大多数都是使用IDE进行代码开发的&#xff0c;这样能快速的开发出需要的项目。之前一直在使用eclipse进行项目开发。近期在学习springboot开始使用IDEA进行项目的开发。 这里总结一些IDEA开发工具的一些辅助设置&#xff0c;这些设置不会使开发更加简单&#xff0c;但…

mime-type 源码解析(Npm library)

mime-type 源码解析(Npm library) 文章目录mime-type 源码解析(Npm library)正文0. 基本信息1. 源码解析1.0 API1.1 MIME 类型源 & 初始化1.2 lookup1.3 contentType1.4 extension1.5 charset2. 小结其他资源参考连接阅读笔记参考正文 0. 基本信息 version&#xff1a;v2…

浅谈TCP拥塞控制算法

TCP通过维护一个拥塞窗口来进行拥塞控制&#xff0c;拥塞控制的原则是&#xff0c;只要网络中没有出现拥塞&#xff0c;拥塞窗口的值就可以再增大一些&#xff0c;以便把更多的数据包发送出去&#xff0c;但只要网络出现拥塞&#xff0c;拥塞窗口的值就应该减小一些&#xff0c…

yallist 源码解析(Npm library)

yallist 源码解析(Npm library) 文章目录yallist 源码解析(Npm library)正文0. 基本信息1. 源码解析1.0 类型 & 接口1.1 类型定义1.2 增&#xff1a;push、pushNode、unshift、unshiftNode1.3 删&#xff1a;pop、shift、splice1.4 查&#xff1a;get、getReverse、toArray…

安全牛学习——主机发现

一、二层主机发现 目的&#xff1a;实现局域网内的主机扫描 1.arping命令扫描主机 使用kali对局域网主机进行扫描时候&#xff0c;arping命令只能挨个挨个ip的扫描&#xff0c;下面写一个简单的脚本实现批量扫描rootkal:~/scan# vim arping.sh #! bin/bash if [ $# -ne 1 ];the…

lru-cache 源码解析(Npm library)

lru-cache 源码解析(Npm library) 文章目录lru-cache 源码解析(Npm library)正文0. 基本信息1. 源码解析1.1 LRUCache 结构 & 构造函数1.2 set(key, value, maxAge)1.3 get(key)、peek(key)1.4 del(key)1.5 forEach(fn(value, key, cache), \[thissp\])1.6 dump、load其他资…

Linux常用命令——awk

awk 一种编程语言 语法格式&#xff1a;awk 【option】pattern{action}【file】... awk [选项] 条件{动作} [文件] ...注意&#xff1a;awk 命令及后面的选项和文件里&#xff0c;每个元素之间都要至少要有一个空格选项说明&#xff1a; 参数选项解释说明-F指定字符安分隔符-v…

single-line-log 源码解析(Npm library)

single-line-log 源码解析(Npm library) 文章目录single-line-log 源码解析(Npm library)正文0. 基本信息1. 实现原理2. 源码解析2.1 逃脱序列定义2.2 log 函数包装2.3 代理标准流其他资源参考连接阅读笔记参考正文 0. 基本信息 version&#xff1a;v1.1.2功能&#xff1a;单…