👍🎉 First off, thanks for taking the time to contribute! 🎉👍
Atom Dev Team - CONTRIBUTING.md
SQIP uses a monorepo
pattern to manage its many dependencies and relies on Lerna and Yarn to configure the repository for active development.
- Make sure to have Yarn installed
Yarn will automatically setup the monorepo for you. The only thing you have to do:
yarn
You can find all available lerna commands via
npx lerna --help
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.
.
├── Dockerfile
├── lerna.json
├── package.json
├── packages
│ ├── sqip
│ │ ├── README.md
│ │ ├── __tests__
│ │ ├── dist
│ │ ├── node_modules
│ │ ├── package.json
│ │ └── src
│ ├── ...
└── yarn.lock
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.
To build/transpile the source of all packages via babel, execute:
npm run build
You can watch for changes as well:
npm run build:watch
To build a new SQIP plugin is pretty simple:
- Make sure the SQIP repository is checked out at master with the latest status and you ran
yarn
. - Create a rough file structure via
lerna create --es-module sqip-plugin-my-amazing-plugin
- 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)
}
}
To add a dependency to a package, you need to go into the package directory and execute Yarn as usual:
yarn add the-dependency-i-badly-need
You might speed this up by using:
npx lerna add the-dependency-i-badly-need
Make sure to read npx lerna add --help
This project uses eslint for linting and jest for unit and e2e tests.
- Run
npm run lint
to lint all packages - Run
npm run test
to lint and test all packages
Run a specific test file and watch for changes:
npx jest packages/sqip/__tests__/unit/sqip.test.js --watch
- 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
- 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.
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.
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.