Skip to content

Open Source Vue.js Component Analyzer - Save time communicating and effort in development to create better and more efficient code

License

Notifications You must be signed in to change notification settings

logicspark/berryjam

Repository files navigation

UI Components Analyzer for Vue 3 & Nuxt

Scan your Vue.js codebase for component visibility and actionable insights.

Issues - Join our Discord - License - Berryjam Cloud

Available for: Vue.js (3.X), Nuxt (3.X)

NPM License Discord Twitter

📖 Table of Contents

  1. Why Berryjam
  2. Features
  3. Limitations
  4. Getting Started
  5. Development
  6. Contributing
  7. Need Help?
  8. License
  9. Acknowledgement

⭐ Why Berryjam

Berryjam provides a simple way to identify your component usage, props and their relationships. Based on the output from your scan, you can create your own dashboard and run analysis across your project components to improve communications across your development team.

✨ Features

1. Scan your project for components

2. Analyze components and their relationships

3. Scan Git log for author and datetime

4. Automatically detect props for each component

🙈 Limitations

  • Berryjam is not compatible with Vue 2 or lower versions.

  • Berryjam has been fully tested to work with node version from 16.0 to 18.17.1 (LTS). Versions above 18.17.1 (LTS) should work as well but have not been fully tested.

🚀 Getting Started

Install Berryjam

There are a few ways you can install Berryjam, namely npm, pnpm and yarn. If you install via npm, here is a single cmd to install this library

  npm install berryjam

Other options

  • pnpm
  pnpm add berryjam
  • yarn
  yarn add berryjam

Usage

To start scanning your project, you will first need to import VueScanner class and create its instance.

import { homedir } from 'os';
import VueScanner from "berryjam"
import type { VueScannerOption, ComponentProfile } from "berryjam"
...
const pathToScan = '../your-vue-project-path';
const option: VueScannerOption = {
  // this folder will be used to store the exact versions of babel & vue compiler
  appDir: `${homedir()}/.vueScanner`,
  // ... any other options
}
// Create a new VueScanner instance with the required parameters
const vueScanner = new VueScanner(pathToScan, option);
...
// To start scanning without async/await
vueScanner.scan().then(result => {
  // the result will be an array of ComponentProfile
  // log to see the result
  console.log(result);
})

// or, You can use async/await
async function whatEverFunction() {
  const result = await vueScanner.scan();
}

Note: For a Nuxt project, please ensure that you have a .nuxt folder before scanning.


The VueScanner function takes two parameters as follow:

  • The first parameter is the path of the project to be scanned.
  • The second is an option object that utilizes the VueScannerOption interface.

Here is the detailed description of each available option within the VueScannerOption interface:

VueScannerOption Interface

Property Type Description
appDir string The path of the project directory to be scanned.
output OutputFormat (optional) The desired output format of the scanned result. (JSON by default)
ignore string[] (optional) An array of file names or directory names to exclude from scanning.
verbose boolean (optional) Enable verbose mode for more detailed scanning information.
debug boolean (optional) Operate the scanner in debug mode, providing debugging information.

OutputFormat Type

The OutputFormat type represents available output formats.

Type Description
"json" Output the scanned result in JSON format and saved as 'component-profiles.json' within the 'appDir'.
"stdout" Display the scanned result directly in the console (stdout).

These options and types offer flexibility and customization when using the VueScanner function to analyze Vue.js projects.

For more details on VueScanner class, please check out below.

Output

By calling the scan method, it will scan for Vue components and return ComponentProfile[]. Here is an example of how it may look. For demonstration purposes, we have scanned an open-source project called Koel.

Sample Result
[
  {
    "name": "PlaybackControls",
    "type": "internal",
    "total": 1,
    "source": {
      "path": "/resources/assets/js/components/layout/app-footer/FooterPlaybackControls.vue",
      "property": {
        "dataLastModified": "Sun Feb 04 2018",
        "lastModified": "Sun Feb 04 2018",
        "created": "2018-02-02T21:12:19.000Z",
        "createdBy": "Phan An",
        "updatedBy": "Phan An"
      }
    },
    "usageLocations": [
      {
        "name": "PlaybackControls",
        "source": "/resources/assets/js/components/layout/app-footer/FooterPlaybackControls.vue",
        "destination": "/resources/assets/js/components/layout/app-footer/index.vue",
        "rows": [
          9
        ],
        "fileInfo": {
          "path": "/resources/assets/js/components/layout/app-footer/FooterPlaybackControls.vue",
          "property": {
            "dataLastModified": "Sun Feb 04 2018",
            "lastModified": "Sun Feb 04 2018",
            "created": "2018-02-02T21:12:19.000Z",
            "createdBy": "Phan An",
            "updatedBy": "Phan An"
          }
        }
      }
    ],
    "children": {
      "total": 4,
      "tags": [
        "LikeButton",
        "icon",
        "PlayButton",
        "RepeatModeSwitch"
      ],
      "source": "/resources/assets/js/components/layout/app-footer/FooterPlaybackControls.vue"
    }
  },
  {
    "name": "PlayButton",
    "type": "internal",
    "total": 1,
    "source": {
      "path": "/resources/assets/js/components/ui/FooterPlayButton.vue",
      "property": {
        "dataLastModified": "Sun Feb 04 2018",
        "lastModified": "Sun Feb 04 2018",
        "created": "2018-02-02T21:12:19.000Z",
        "createdBy": "Phan An",
        "updatedBy": "Phan An"
      }
    },
    "usageLocations": [
      {
        "name": "PlayButton",
        "source": "/resources/assets/js/components/ui/FooterPlayButton.vue",
        "destination": "/resources/assets/js/components/layout/app-footer/FooterPlaybackControls.vue",
        "rows": [
          11
        ],
        "fileInfo": {
          "path": "/resources/assets/js/components/ui/FooterPlayButton.vue",
          "property": {
            "dataLastModified": "Sun Feb 04 2018",
            "lastModified": "Sun Feb 04 2018",
            "created": "2018-02-02T21:12:19.000Z",
            "createdBy": "Phan An",
            "updatedBy": "Phan An"
          }
        }
      }
    ],
    "children": {
      "total": 1,
      "tags": [
        "icon"
      ],
      "source": "/resources/assets/js/components/ui/FooterPlayButton.vue"
    }
  },
]

🚧 Development

The library uses Nodejs, TypeScript and Jest for development. Since this is a tool for detecting Vue components, you may find the rules on how Vue components in the built-in-rules folder.

How It Works

Berryjam contains 2 classes, namely:

  1. VueScanner - Use to scan a project for component profiles. It will extract relevant relative values such as source, file path, component name from package.json files and their respective supported files to transform or normalize raw component data which will be mapped to each component profile.

  2. GitService - If the project has .git folder, it will look for git related information such as author and datetime and map to each component profile.

VueScanner Overview

Within the VueScanner class, you may call on scan() method to start scanning. The method encompasses 5 main steps. There are as follow:

Five main steps in VueScanner class

Step Description
1. Group by Related Package.Json Since there are multiple package.json files and supported files (.vue, .js, .jsx, .ts, .tsx and all files from the .nuxt folder (if any)), the system will group and determine the source of origin
2. Select Analyzer Lib To choose the right library that matches the Vue version of your project
3. Prepare Alias Paths To gather all aliases from TS, JS and Vite config files to use for replacement in the 'import' statements
4. Analyze Component Files For each file extension, the system will gather component info, including props
5. Optimize Analyzed Results Based on the component info, improvements are made by removing duplicates and formatting the component profile in a more structured way

GitService Overview

Below are the main methods in the GitService class:

Method Description
gitScanner Initiate git log shell commands to scan which will be used by gitMapping.
gitMapping Using the result from gitScanner to compare component name and git log filename. If both match, the git information will update into the respective component profile.

Dependencies

Third-Party plugins are loaded automatically from Berryjam’s package.json

For more information, please refer to the documentation folder.

💪 Contributing

We are thankful and appreciative for all types of contributions. Whether you are helping us report or fix bugs, proposing new features, improving our documentation or spreading the word - we would love to have you as a part of the Berryjam community. Please refer to our Contributing Guide and Code of Conduct.

If you wish to start contributing right away, navigate to the GitHub Issues tab and start looking through interesting issues. You may start off by working on issues labeled under documentation and good first issue.

If you run into an error or an issue while using Berryjam, you have an idea on how to better Berryjam or perhaps you are looking through the documentation and thinking that it could be improved... please don’t hesitate to submit an issue 😎

If you are a Vue.js developer who is not familiar with Node.js., you can submit an issue labeled code example on how you create Vue components. Check out our built-in-rules for more details.

🙋 Need Help?

We are more than happy to help you. If you have any questions, run into any errors or face any problems, please feel free to ask for help in Berryjam Discord. Anything related to Berryjam is on the table!

📄 License

Berryjam is distributed under MIT License. Please refer to our LICENSE.md file for more details.

Acknowledgement