code: function analyzeFile (file, content, filter, depResolve, depth, result) {
    depth = typeof depth === 'number' ? depth : Infinity
    result = result || {}
  
    if (depth < 1) {
      return
    }
  
    if (file in result) {
      return
    }
  
    debug('analyze file: file = %s, depth = %s', file, depth)
  
    let deps = parseFile(file, content) || []
    let item = result[file] = {
      deps: [],
      relatives: [],
      modules: []
    }
  
    // filter deps
    if (filter) {
      deps = deps.filter(dep => filter(dep, file))
    }
  
    // convert
    deps.forEach(dep => {
      let info = getDepInfo(dep, file, depResolve)
  
      item.deps.push(info)
  
      if (info.module && item.modules.indexOf(info.module) < 0) {
        item.modules.push(info.module)
      } else if (info.file && item.relatives.indexOf(info.file) < 0) {
        item.relatives.push(info.file)
  
        // deep first traversing
        analyzeFile(info.file, fs.readFileSync(info.file, 'utf8'), filter, depResolve, depth - 1, result)
      }
    })
  
    return result
  }
docs: recursively analyze single file
  @param  {String} file      file path
  @param  {String} content   file content
  @param  {Function} filter  filter function
  @param  {Function} depResolve resolve dep to normal dep format
  @param  {Number} depth     max analyze depth
  @param  {Object} result    the analyed result
  @return {Object}