Skip to content

Latest commit

 

History

History
190 lines (129 loc) · 6.24 KB

File metadata and controls

190 lines (129 loc) · 6.24 KB

Contributing to SQIP

CircleCI Maintainability

Contributor Covenant

👍🎉 First off, thanks for taking the time to contribute! 🎉👍

Atom Dev Team - CONTRIBUTING.md

Development Setup

SQIP uses a monorepo pattern to manage its many dependencies via npm workspaces. Lerna is used only for publishing and changelog generation.

Requirements

  • Node.js >= 20
  • npm (comes with Node.js)

Installation and repo setup

npm will automatically setup the monorepo workspaces for you:

npm install

Directory structure

SQIP is organized in packages. They are located in the packages directory. Each package is released as a separate NPM package.

All packages should follow the same directory structure to allow proper TS builds.

Relevant files and directories:

.
├── Dockerfile
├── lerna.json
├── package.json
├── packages
│   ├── sqip
│   │   ├── README.md
│   │   ├── __tests__
│   │   ├── dist
│   │   ├── node_modules
│   │   ├── package.json
│   │   └── src
│   ├── ...
└── package-lock.json

Developing

If not specified differently, all commands are executed from the project root directory.

A npm run will give you a first overview of all available scripts.

Building the source

To build/transpile the source of all packages via TypeScript, execute:

npm run build

You can watch for changes as well:

npm run build:watch

Create a new plugin

To build a new SQIP plugin is pretty simple:

  1. Make sure the SQIP repository is checked out at master with the latest status and you ran npm install.
  2. Create a new directory under packages/ for your plugin (e.g. packages/sqip-plugin-my-amazing-plugin).
  3. Use the following template to rocket-start your new plugin:
import { SqipPlugin } from 'sqip'

export default class MyAmazingPlugin extends SqipPlugin {
  static get cliOptions() {
    // Make options available to the CLI.
    return [
      {
        name: 'bar',
        alias: 'b',
        type: String,
        description: 'Set replacement value for "foo"',
        defaultValue: 'bar'
      }
    ]
  }

  constructor({ pluginOptions }) {
    /**
     * Will enhance your plugin instance with the following:
     * this.metadata: Object with width, height and type
     * this.sqipConfig: The configuration passed to SQIP by the user
     */
    super(...arguments)

    // Set your options
    this.options = {
      // Inject default options
      bar: 'bar',
      ...pluginOptions
    }
  }

  async apply(imageBuffer) {
    console.log('Incoming image:', imageBuffer)

    // Check for correct format for your plugin
    if (this.metadata.type !== 'svg') {
      throw new Error('The plugin needs a svg image as input.')
    }

    // Read plugin options
    const { bar } = this.options

    // Do some transformation
    const svg = imageBuffer.toString()
    const newSvg = svg.replace('foo', bar)

    // Hint: Consider to use https://www.npmjs.com/package/buffer-replace for replacements instead of this hack

    // Return new svg as buffer
    return Buffer.from(newSvg)
  }
}

Add dependencies to a package

To add a dependency to a specific package, use npm's workspace flag:

npm install the-dependency-i-badly-need -w sqip-plugin-my-amazing-plugin

Testing

eslint vitest

This project uses eslint for linting and Vitest for unit and e2e tests.

  • Run npm run lint to lint all packages
  • Run npm run test to lint and test all packages

Watching and executing specific tests

Run a specific test file and watch for changes:

npx vitest packages/sqip/__tests__/unit/sqip.test.ts

Unit tests

  • Run npm run test:unit to execute unit tests in all packages
  • Run npm run test:unit:watch to execute unit tests in all packages and rerun if code changes

End-to-end tests

  • Run npm run test:e2e to execute end-to-end tests in all packages. Will build the packages before execution.
  • Run npm run test:e2e:watch to execute end-to-end tests in all packages and rerun if code changes

Hint: When watching end-to-end tests, you need to rebuild the source after each of your changes. You can use npm run build:watch for this.

Code style

Code Style

This project uses prettier to format its source code. Your committed code will be automatically linted and transformed via husky.

See .prettierrc for the configuration details.

Commit conventions

Commitizen friendly semantic-release

To keep the automated release and changelog engine running, every commit should follow the conventional commits guidelines originally introduced by angular.

You may use Commitizen to ease up creating commit messages with the conventional commits guidelines. It is fully integrated into the project.

After merging into our master branch, this will allow semantic release to decide what kind of version to release. An automated changelog will also be created.