# Introduction

[![Build Status](https://img.shields.io/circleci/project/github/wintercounter/mhy/master.svg)](https://circleci.com/gh/wintercounter/mhy/tree/master) [![Downloads](https://img.shields.io/npm/dm/mhy.svg)](https://npmcharts.com/compare/mhy?minimal=true) [![](https://david-dm.org/wintercounter/mhy/status.svg)](https://david-dm.org/wintercounter/mhy) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier) [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org) [![Version](https://img.shields.io/npm/v/mhy.svg)](https://www.npmjs.com/package/mhy) [![License](https://img.shields.io/npm/l/mhy.svg)](https://www.npmjs.com/package/mhy)

## mhy [![](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Try%20out%20%23mhy%20as%20your%20new%20JavaScript%20development%20environment.%20https%3A%2F%2Fmhy.js.org\&hashtags=mhy,webpack,babel,jest,typescript,frontend,developers,javascript,html)

A **zero-config**, **out-of-the-box**, **multi-purpose** *toolbox* and *development environment*.

[mhy.js.org](https://mhy.js.org)

***

## Summary

It's really hard to define what `mhy` (my) is, because it tries to create a unified developer experience for any stage of your project:

* a pre-configured **development environment** to not waste time with the set-up when starting a new project or just need a quick playground.
* a pre-configured **production environment** to help you reach production faster compiling/building your code without any necessary setup.
* an **ecosystem** to be able to run different task together at once, connected together perfectly.
* a **toolbox** help your work with the most common tasks.
* a **solution for littering** your machine with the same npm package over and over again.
* a **config management** tool to make necessary changes faster at a single place.
* an **interoperable environment** to be shared across multiple projects and ensure they are being build on the same principles/stack.

> `mhy` helps you to be able to focus on your code again rather then the tech behind it.

## Using `mhy` you'll have

* a **zero-configuration** environment **out-of-the-box**.
* a **portable** codebase without any `npm install`.
* **simple customization** if you don't favor the default settings.
* **package.json based customization** for any configs value `mhy` provides.
* **boot templates** for easy setup.
* **most common packages** provided to your work.
* **less boilerplate**.
* configs/tools **well-playing** together *(webpack+swc, jest+swc, storybook+webpack, webpack+typescript, etc.)*.
* **pre-built and public Docker images** for faster CI.

> Note that `mhy`'s focus is on client side currently, but server side features are about to come.

## Setup

### Install

```bash
npm install mhy -g
```

From `npm@7.0.0` peer dependencies are automatically being installed. `mhy` uses some dependencies that are not prepared yet for this new mechanism. We cannot do anything, but wait for updates. You need to install `mhy` using the `--legacy-peer-deps` or `--force` flag.

```bash
npm install mhy -g --legacy-peer-deps
```

### Start a new Webpack project

Create an empty project with a single `index.js` file that is being served using `webpack-dev-server` *(wds)* pre-configured with **Babel**, **React** and **React Fast-Refresh**.

```bash
mkdir src
echo "console.log('Hello mhy!')" > src/index.js
mhy wds
```

### Compile library

Create a production ready library. From the `src` folder it creates a complied `dist` folder.

```bash
mhy babel ---mhy-env=prod
```

### Build bundle

Create a production ready bundle for you website/app using pre-configured **Webpack**. From the `src` folder it creates a `build` folder with your bundle ready to be served supporting many popular features/loaders.

```bash
mhy webpack --mhy-env=prod
```

### Start the default ecosystem

It'll run Jest, Webpack Dev Server, TypeScript compiler, Storybook at once in a single Terminal UI (TUI).

```bash
mhy
```

## Supported packages

`mhy` is providing many common/popular packages \_out-of-the\_box. There are continuous adjustments being made to the includes to match the most common needs and being able to develop without the need of your own `npm install` command ever again.

## Contributors ✨

| <p><a href="http://andy1210.com"><img src="https://avatars0.githubusercontent.com/u/964291?v=4" alt=""><br><strong>Andy1210</strong></a><br><a href="https://github.com/wintercounter/mhy/issues?q=author%3AAndy1210">🐛</a> <a href="https://github.com/wintercounter/mhy/commits?author=Andy1210">⚠️</a></p> | <p><a href="https://github.com/pablohpsilva"><img src="https://avatars1.githubusercontent.com/u/2090635?v=4" alt=""><br><strong>Pablo Henrique</strong></a><br><a href="https://github.com/wintercounter/mhy/commits?author=pablohpsilva">📖</a></p> | <p><a href="http://beagl.in"><img src="https://avatars0.githubusercontent.com/u/8502021?v=4" alt=""><br><strong>Eugen Guriev</strong></a><br><a href="https://github.com/wintercounter/mhy/commits?author=gcofficial">💻</a></p> | <p><a href="https://github.com/FabianLauer"><img src="https://avatars0.githubusercontent.com/u/2205595?v=4" alt=""><br><strong>Fabian Lauer</strong></a><br><a href="https://github.com/wintercounter/mhy/commits?author=FabianLauer">💻</a></p> | <p><a href="http://winckell.com"><img src="https://avatars1.githubusercontent.com/u/5302702?v=4" alt=""><br><strong>Thomas Winckell</strong></a><br><a href="https://github.com/wintercounter/mhy/commits?author=thomaswinckell">💻</a> <a href="https://github.com/wintercounter/mhy/commits?author=thomaswinckell">📖</a></p> | <p><a href="https://github.com/stevenmitts"><img src="https://avatars1.githubusercontent.com/u/13355405?v=4" alt=""><br><strong>Steven Mitts</strong></a><br><a href="https://github.com/wintercounter/mhy/commits?author=stevenmitts">📖</a></p> | <p><a href="https://zakhardolozhevskiy.github.io/CV"><img src="https://avatars0.githubusercontent.com/u/5322859?v=4" alt=""><br><strong>Zakhar</strong></a><br><a href="https://github.com/wintercounter/mhy/commits?author=ZakharDolozhevskiy">💻</a> <a href="https://github.com/wintercounter/mhy/commits?author=ZakharDolozhevskiy">📖</a></p> |
| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|                                        <p><a href="http://andor.cool"><img src="https://avatars3.githubusercontent.com/u/747365?v=4" alt=""><br><strong>Andor Polgar</strong></a><br><a href="https://github.com/wintercounter/mhy/commits?author=andormade">💻</a></p>                                        |        <p><a href="https://github.com/bafxyz"><img src="https://avatars1.githubusercontent.com/u/892175?v=4" alt=""><br><strong>Andrei Bunulu</strong></a><br><a href="https://github.com/wintercounter/mhy/commits?author=bafxyz">💻</a></p>        |                                                                                                                                                                                                                                  |                                                                                                                                                                                                                                                  |                                                                                                                                                                                                                                                                                                                                 |                                                                                                                                                                                                                                                   |                                                                                                                                                                                                                                                                                                                                                    |

❤ Thank you all! ❤

## Credits ❤

I'm using Webpack's logo to build an `M` shape from multiple blocks. I'd like to say **Thank You** for their great logo.

I also would like to thank to every developer's hard work which I'm using as a dependency in `mhy`. It would be really hard to collect all those people, but in case you find your work in our `package.json`, please feel free to create a pull request and add your logo and link.

|                                                                                                                                                                                                                                         |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p><img src="https://avatars0.githubusercontent.com/u/963776?v=4&#x26;s=128" alt="" data-size="original"></p><p><a href="https://github.com/wintercounter">wintercounter</a></p><p>while(!credits.length)<br>console.log('Example')</p> |

***

🌟 PLEASE STAR THIS REPO IF YOU FOUND SOMETHING INTERESTING! 🌟


# Installation

```
npm i mhy -g
```

> `mhy` has an *always-up-to-date* policy which means it is updated regularly. Please follow this practice in your project also. To update `mhy` simply use: `npm i mhy@latest -g`.
>
> Even though it's possible, `mhy` isn't supposed to be installed locally.


# Usage

## Command syntax

```bash
mhy [process|tool] [argument1] [argument2] [...]
```

All arguments will be passed to the given process's CLI tool, just like you would use that tool by default - making `mhy` act as a wrapper for your command.

```bash
mhy jest -u

# Equals to (except it's using the environment/config provided by mhy)
jest -u
```

## Configure

You may change some behaviors of `mhy` and it's processes by changing the following config options under the key: `mhy`

| Option              | Default                                                    | Details                                                                                                          |
| ------------------- | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `defaultIndexHtml`  | `process.cwd()/src/index.html` or `resources/index.html`   | Falls back to global if local not found.                                                                         |
| `srcFolder`         | `src`                                                      | Root folder to be used for sources.                                                                              |
| `defaultIgnoreList` | See: `src/configs/mhy`                                     | -                                                                                                                |
| `defaultAliases`    | `{ '@' : 'src' }`                                          | Default aliases to be resolved. With the default solution you only need to use it as `@/components` for example. |
| `ecosystem`         | `['webpack-dev-server', 'tsc', 'jest', 'storybook-start']` | The default ecosystem to be loaded.                                                                              |

## NODE\_ENV

The `process.env.NODE_ENV` variable is having different effects on different parts of `mhy` which can be either `development` or `production`. The term `root` in the hierarchy is always referring to the resource that's being available in every case, regardless of the current environment.

## Docker

With each version of `mhy` we're also releasing a Docker image containing the corresponding version. It can be used to speed up deployments and/or to prevent a local/global install on your host OS.

```bash
docker pull wintercounter/mhy
docker run -it -v $(pwd):/app -w /app wintercounter/mhy mhy jest

# On Windows (different CWD syntax)
docker run -it -v %CD%:/app -w /app wintercounter/mhy mhy jest
```

### Docker Hub repository & versions

<https://hub.docker.com/r/wintercounter/mhy/tags>


# UI


# Ecosystem


# How does it work?

`mhy` has a huge list of common/popular packages as it's dependencies (over **300 MB** when installed). Usually in case you have several projects on your computer, you end up having the same package in your project's `node_modules` folder over and over again. To eliminate this issue `mhy` uses it's own dependencies with-in your project by providing you tools out-of-the-box which are supporting this method.

1. Create an `src` folder in your project root.
2. Create an `index.js` inside.
3. Run the command: `mhy wds`.
4. Voila, you have `webpack-dev-server` running serving you file.

   without any `npm install` or dependency in your `package.json`


# Built-ins


# boot

This tool will let you initialize codebase from a template.

## Usage

```bash
mhy boot [technology:react|vue|...] [template:default|...] [-o,--output: output path]
```

* `technology`: what tech should be used.
  * `default`: react
* `template`: what template should be loaded.
  * `default`: default
* `-o, --output`: path where the template should be boot.
  * `default`: ''

Examples:

```bash
mhy boot react default -o myProject
# or
mhy boot
# or
mhy boot react
# or
mhy boot -o xproject/path/src
```

> Your `package.json` will be extended with the necessary changes you might need to run the template. If it doesn't exists, it'll be created for you.

## Available Templates

### React Minimal

A minimal code to render a single React component.

```
mhy boot react minimal
```

### React Default

A complete example codebase with *Redux*, *async rendering*, *API calls* and *Service Worker*.

```
mhy boot react
```

#### Structure

* `components`: components directory
* `config`: app configuration directory
* `core`: app mounting, routing and flux store directory
* `entities`: HTTP code related directory
* `fields`: app specific form fields directory
* `forms`: app specific forms and business logic directory
* `layouts`: is a container for a page to represent different states of an application
* `overlays`: basically containers to construct a overlay's structure.
* `pages`: basically containers to construct a page's structure.
* `services`: a base service implementation which you build your APIs on.
* `validators`: custom validator function usually for `react-redux-form`
* `index.js`: files are being used to export sub-modules for easier/simplier/nicer imports.


# config

This is a built-in CLI process used to retrieve final config objects in various formats OR initialize a single/environment configuration.

* Alias: `c`

## Initialize

`mhy` is able to generate your config files for your environment. Use it to initialize your environment in your IDE/Editor.

```bash
mhy config
```

By default `mhy` won't overwrite your existing configuration files, it gives you a warning instead. In case you want to overwrite anyway, use the `-o --overwrite` flag.

```
mhy config -o
```

Use the `-i --init` flag to initialize a single configuration file only.

```
mhy config webpack -i

# in case you also wan't to overwrite
mhy config webpack -io
```

## Get

In certain situations you might want to initialize only a certain configuration or just want to check the final object `mhy` will use.

Log out a single config object:

```bash
mhy config webpack
```

You may use the `-f --format` flag to change the output format:

```bash
mhy config webpack -f json
```

You might want to write the contents into a file, you just need to use the > operator which works both on Windows and Linux:

```bash
mhy config webpack --format=mjs > webpack.config.mjs
```

Available formats:

* `js` plain JavaScript object `module.exports = module.exports.default = {}`
* `mjs` plain JavaScript object `export default {}`
* `json` plain JSON object
* `raw` try to print out as is

## Set

Setting configuration values can be done in multiple ways. Before showing those, let's get famimilar with the configuration loading flow and some definitions first.

### Entities

* `root` entities are being loaded always
* `env` entities are being loaded if the current environment matches

### Directory structure

This is an example of `webpack`'s structure:

```
webpack
|- root
|- development
|- production
|- index.js
```

`mhy` will recursively load all configuration values from the directory structure recursively.

File names are becoming keys in the final object and folders are becoming arrays.

#### Example

```
webpack
|- root
   |- plugins
      |- swc.js // returns {foo: 'bar'}
   |- resolve.js // returns 'Resolve value'
|- development
|- production
```

From the directory structure above you will end up having the following object:

```
{
    plugins: [{ foo: 'bar' }],
    resolve: 'Resolve value'
}
```

{% hint style="info" %}
For further examples check out `mhy`'s repository.
{% endhint %}

### Flow

1. Load `root` from `mhy`
2. Load `root` from `local`
3. Load `root` from `package.json`
4. Load `env` from `mhy`
5. Load `env` from `local`
6. Load `env` from `package.json`

### Overriding

#### Using package.json (recommended)

`mhy`'s practice to to keep every configuration in the `package.json` of the project. You can manipulate almost every aspect of a configariation object through JSON, even removals, appends, replaces, pushes or even searching and running JavaScript code.

All `mhy` related values are being stored under the key `"mhy"` in your `package.json`. The structure is the same. By default your object basically are being deep merged.

`mhy` is coming with support for [json-merger](https://www.npmjs.com/package/json-merger) which enables manipulation of JSON data easily without using JavaScript.

Let's assume the same `webpack` directory structure as above and the follwing in out `package.json` file:

```javascript
{
    "mhy": {
        "webpack": {
            "development": {
               "resolve": "new resolve value",
               "plugins": [{
                  "$append": "kex"
               }]
            }
        }
    }
}
```

The result for `webpack` will be:

```javascript
{
   resolve: "new resolve value",
   plugins: [{ foo: 'bar' }, 'kex']
}
```

#### Using files

This method is for more advanced cases or those who prefer to manage their configs in files.

`mhy` will search a `.mhy` directory in your project root. There you need to have a config directory with the same environment base as in the previous examples:

```
.mhy
  |- configs
    |- webpack
      |- development
        |- resolve.js
```

In your files you need to default export a function that is returning the value. In the first parameter you'll also get the current value of the key if there's any.

```
module.exports = current => {
    current.extensions.push('svg')
    return current
}
```

{% hint style="info" %}
Please note that there will be no code transformations applied to your custom config files. Only use syntax/features that are available in your current NodeJS version.
{% endhint %}

**Local processes/commands**

Using this method you can have your own, local processes/commands as well. More info on this is about to come, stay tuned!


# dep

This is a built-in CLI process used to manage dependencies whether using mhy's dependencies or not.

* Alias: `deps`

## Tools

* `search`
* `collect`
* `install`

### Search

```bash
# List all dependencies mhy provides
mhy dep search

# Search for certain dependencies mhy provides
mhy dep search react
```

### Collect

```bash
# Collect all dependencies not listed in your package.json (provided by mhy)
mhy dep collect

# Write collected dependencies to you packages.json as 'mhyDependencies'
mhy dep collect write

# Write collected dependencies to you packages.json as 'peerDependencies'
mhy dep collect write-peer

# Write collected dependencies to you packages.json both as 'mhyDependencies' and 'peerDependencies'
mhy dep collect write-both
```

### Install

Utility tool to install `*dependecies` from your `package.json`.

> This tool is usually only used for special cases, most of the times you don't need this.

```bash
# Install dependencies found in mhyDependencies
mhy dep install

# Install dependencies found in peerDependencies
mhy dep install peer
```


# options

## --mhy-help

```bash
# show usage details
mhy --mhy-help
```

## --mhy-debug

```bash
# show debug messages
mhy --mhy-debug
```

## --mhy-verbose

```bash
# show more info than usual
mhy --mhy-verbose
```

## --mhy-env

Controls `process.env.NODE_ENV` variable and adds support to have multiple secondary environments.

Aliases:

* `prod`: `production`
* `dev`: `development` *(default)*

### Basic Usage

```bash
# Run as NODE_ENV=production
mhy eslint --mhy-env=prod

# Run as NODE_ENV=production with secondary env called `ci`
mhy eslint --mhy-env=prod:ui
```

### Secondary environments

You can use the `:` separator to define multiple secondary environments.

> The first environment will be always set as a value for `process.env.NODE_ENV`.

Example

```bash
# Run webpack with configuration loaded for production mode, on Travis-CI only for the master branch.
mhy webpack --mhy-env=prod:travis:master
```

> Secondary environments are supported and config also.

## --mhy-if

Executes the command only when the given expression is *truthy*.

```bash
# On building master I don't need to run tests because they were validated before pull requests
mhy jest --mhy-if="!process.env.MHY_ENVS.includes('master')"
```

## --mhy-version

```bash
# show mhy's currently installed version
mhy --mhy-version
```


# ui


# Processes


# eslint

> Linting is done by Webpack also in production mode. You only need this process to manually run linting, or run it's `fix` command for example.

## Default command

```bash
eslint ./src/**/*.{js,jsx,ts,tsx}
```

## CLI Options

<https://eslint.org/docs/user-guide/command-line-interface>

## Examples

### Default CLI

```bash
mhy eslint
```

### Only lint one file

```bash
mhy eslint src/file.js
```

### Fix fixable errors

```bash
mhy eslint --fix
```


# jest

* Jest is using `mhy/configs/swc` config. You don't want your test environment to act differently.

## Default command

```bash
jest --passWithNoTests --colors --config=mhy/configs/jest
```

## CLI Options

<https://jestjs.io/docs/en/cli.html>

## Examples

### Default CLI

```bash
mhy jest
```

### Only test one file

```bash
mhy jest src/test.js
```

### Update snapshots

```bash
mhy jest -u
```

### Watcher

```bash
mhy jest --watch
```


# node

Run scripts in Node.JS.

* TypeScript support.
* Uses `swc-register`
* Support for aliases.
* Default: `./src`
* Resolves `.js`, `.jsx`, `.ts` and `.tsx` files.

## Default command

```bash
node ./src
```

## CLI Options

<https://nodejs.org/api/cli.html>

## Examples

### Default CLI

```bash
mhy node
```

### Run a specific file/folder

```bash
mhy node file
```


# nodemon

Run scripts in Node.JS using `nodemon`. Almost the same as `node` process with watcher.

* Same support as with the `node process`.
* Default: `./src`

## Default command

```bash
nodemon ./src
```

## CLI Options

<https://github.com/remy/nodemon#nodemon>

## Examples

### Default CLI

```bash
mhy nodemon
```

### Run a specific file

```bash
mhy nodemon file
```


# prettier

## Default command

```bash
prettier --config=mhy/configs/prettier --write src/**/*.{js,jsx,ts,tsx}
```

## CLI Options

<https://prettier.io/docs/en/cli.html>

## Examples

### Default CLI

```bash
mhy prettier
```

### On another directory

```bash
mhy prettier another_directory
```


# standard-version

* Alias: `sv`

## Default command

```bash
standard-version
```

## CLI Options

<https://github.com/conventional-changelog/standard-version>

## Examples

### Default CLI

```bash
mhy sv
```

### With argument

```bash
mhy sv --dry-run
```


# storybook-start

* Alias: `sb-start`
* Storybook is being setup to use `mhy`'s `Webpack` and `SWC` config.

### Default command

```bash
start-storybook
```

### CLI Options

<https://storybook.js.org/configurations/cli-options/>

### Example

```bash
mhy sb-start
# or
mhy storybook-start
```

### Customization

To customize your Storybook you can create `storybook.preview.js`, `storybook.manager.js` and/or `storybook.main.js` files anywhere inside your `src` folder.

Preview file is also supporting `parameters`, `globalTypes` and `decorators` exports. The difference is that you need to use a function where you'll get the default values as a parameter. Manipulate this value however you want.

```
export const parameters = (defaults) => {
    defaults.foo = 'bar'
}
```

The above is also for for `main.js`'s default export where you can define `addons` for example.


# storybook-build

* Alias: `sb-build`
* Storybook is being setup to use `mhy`'s `Webpack` and `SWC` config.
* Builds a standalone version of your Storybook to the `.sb` directory.

### Default command

```bash
build-storybook
```

### CLI Options

<https://storybook.js.org/docs/configurations/cli-options/#for-build-storybook>

### Example

```bash
mhy sb-build
# or
mhy storybook-build
```


# tsc

* By default `tsc` is only used for type-checking and to generate `.d.ts` files. Compilation is done by `swc`.

> A `tsconfig.json` is required for you to have at your project's root folder. `mhy` will create one if it doesn't exists yet.

## Default command

```bash
tsc --project ./tsconfig.json
```

## CLI Options

<https://www.typescriptlang.org/docs/handbook/compiler-options.html>

## Examples

### Default CLI

```bash
mhy tsc
```

### With watcher

```bash
mhy tsc -w
```


# webpack

* Alias: `wp`
* For development use `mhy wp serve`

## Default command

```bash
webpack --config mhy/configs/webpack
```

## CLI Options

<https://webpack.js.org/api/cli/>

## Examples

### Default CLI

```bash
mhy webpack
# or
mhy wp
# or dev server
mhy wp serve
```

### In `production` mode

```bash
mhy webpack --mhy-env=prod
# or
NODE_ENV=production mhy webpack
```

### With watcher

```bash
mhy webpack -w
# or
mhy wp --watch
```

## Debug performance

`SpeedMeasurePlugin` is being supported out-of-the-box which is giving statistics for you about the time being spent on different stages of the build process to make it easier to track down build performance issues.

### Usage

You just need to pass the `--mhy-debug` flag to your command.

```
mhy wp --mhy-debug
```


# webpack-bundle-analyzer

* Alias: `wba`

## Default command

```bash
webpack-bundle-analyzer stats.json
```

## CLI Options

<https://github.com/webpack-contrib/webpack-bundle-analyzer#options-for-cli>

## Examples

### Default CLI

```bash
mhy webpack-bundle-analyzer
# or
mhy wba
```

### Analyze `production` bundle instead

```bash
mhy webpack-bundle-analyzer --mhy-env=prod
# or
NODE_ENV=production mhy webpack-bundle-analyzer
```

### With watcher

```bash
mhy webpack -w
# or
mhy wp --watch
```


# webpack-dev-server


# Configs


# eslint

<https://eslint.org/docs/user-guide/configuring>

```bash
# Print config to console
mhy config eslint

# Write .eslintrc
mhy config eslint -i
```

## Used by

* `eslint`
* `jest`
* `storybook-start (through webpack config)`
* `webpack (config)`
* `webpack-dev-server (through webpack config)`


# gitignore

<https://git-scm.com/docs/gitignore>

```bash
# Print config to console
mhy config gitignore

# Write .gitignore
mhy config gitignore -i
```

> Note that `mhy` is also adding generated config files like `webpack.config.js` for example.


# jest

<https://jestjs.io/docs/en/configuration.html>

For custom jest setup file support you can simple add file with such name pattern `jest.setup.[js|ts]` to your project and provide all needed configurations there

```bash
# Print config to console
mhy config jest

# Write jest.config.js
mhy config jest -i
```

## Used by

* `jest`


# manifest

<https://developer.mozilla.org/en-US/docs/Web/Manifest>

Used by `webpack` to generate `manifest.json` WebApp Manifest file.

```bash
# Print config to console
mhy config manifest

# Write manifest.json
mhy config manifest -i
```

## Used by

* `webpack`


# mhy

`mhy` is being built using `mhy` :) Just like `npm` is a package on `npm`. It's core configuration values are stored using `mhy` also.

```bash
# Print config to console
mhy config mhy
```

## Options

### `defaultIndexHtml`

The `index.html` file to load when using `webpack`.

Default is provided by `mhy`: `resources/index.html`

> You can use your own by putting it to your `src` folder. Not necessary to overwrite this value.

### `srcFolder`

Folder to your source files from you project root.

Default: `src`

### `defaultIgnoreList`

An array including the list of filenames needed to be excluded in general (like cache folders, log files, etc). Both `gitignore` and `npmignore` configs are extending this list.

> Please see source file for details.

### `defaultAliases`

Aliases provided for `SWC` and `TypeScript` imports.

Default: `{ '@': 'src' }`

With the default solution you can have aliases to all the folder in `src`.

Example: `import Foo from '@/components/foo'`

> Please note that previously aliases were provided for certain folders as `@components`. These are being **DEPRECATED** and should not be used. The new way is more flexible and avoids collision with NPM namespaces.


# npmignore

<https://docs.npmjs.com/misc/developers#keeping-files-out-of-your-package>

```bash
# Print config to console
mhy config npmignore

# Write .npmignore
mhy config npmignore -i
```

> Note that `mhy` is also adding generated config files like `webpack.config.js` for example.


# prettier

<https://prettier.io/docs/en/configuration.html>

```bash
# Print config to console
mhy config prettier

# Write .prettierrc
mhy config prettier -i
```

## Used by

* `prettier`


# storybook

> Currently only `start` options are available. \*\[]:

<https://storybook.js.org/configurations/cli-options/>

```bash
# Print config to console
mhy config storybook
```

## Overriding from `package.json`

```json
{
    "mhy": {
        "storybook": {
            "root" : {
                "start": {
                    "port": 3500
                }
            }
        }
    }
}
```

## Used by

* `storybook-start`


# typescript

* <https://www.typescriptlang.org/docs/handbook/compiler-options.html>
* <https://www.typescriptlang.org/docs/handbook/tsconfig-json.html>

```bash
# Print config to console
mhy config typescript

# Write tsconfig.json
mhy config typescript -i
```

## Used by

* `typescript`


# webpack

<https://webpack.js.org/configuration/>

```bash
# Print config to console
mhy config webpack

# Write webpack.config.js
mhy config webpack -i
```

## Used by

* `webpack`
* `webpack-dev-server`
* `storybook-start`


# WebStorm & PHPStorm

## Search for global `node_modules` folder (GLOBAL\_NODE\_MODULES)

1. Use the `npm config get prefix` command to find the path to the `mhy` executable file.
2. The *global* `node_modules` folder should be around there somewhere. It varies between different systems, maybe it is right next to it, maybe inside a `lib` directory next to it or the upper levels.
3. Inside the *global* `node_modules` folder, you'll find `mhy/node_modules`. The path to that directory is what we will need.

## Generating config files

```bash
# Generating all possible config files mhy can provide
mhy config

# Use -o to overwrite existing files
mhy config -o

# Generate specific config files
mhy config prettier typescript webpack -io
```

## `node_modules` resolution

Since you're using modules coming from `mhy`, you need to tell the IDE to include a `node_modules` folder outside your project's directory.

1. Find `GLOBAL_NODE_MODULES/mhy/node_modules`
2. Add the path at `File > Settings > Directories` and mark it as `Excluded` and `Resource root`.

## Alias resolution

Alias resolution is done by Webpack. You only need to have a `webpack.config.js` file in your root.

1. **ONLY** in case you haven't run `mhy config` yet to set-up your empty project, run `mhy config webpack -i` to initialize a config file.
2. Make sure at `File > Settings > Webpack` that the feature is turned on.

## Prettier (for automatic formatting on save; recommended)

While it's possible to add watchers without the `Prettier plugin`, the plugin simply helps you with pre-filling the necessary fields with the necessary values for your watcher.

1. Install `Prettier plugin` from `File > Settings > Plugins`
2. Restart IDE
3. Go to `File > Settings > Tools > File Watchers`
4. Create watcher by clicking the `+` sign.
5. Select `prettier`
6. Set `Scope` to `Current file` which is more optimal.
7. Set `Program` to `GLOBAL_NODE_MODULES/mhy/node_modules/.bin/prettier` (add `.cmd` on Windows).
8. Save with `OK`.
9. **(Optional)** You might want to add change the `Level` of the watcher to `Global` to be able to re-use it across projects.

> Unfortunately you'll need to create watcher for each `File Type` you want the IDE to watch. By default it was creating it only for JavaScript. Most probably you want to add `jsx, ts, tsx` watcher also. Do this with copying the watcher and change the `File Type`.

## TypeScript

> Step 0: If it's necessary, please do `npm i` first for your project, only create `tsconfig.json` file after that. This is important to avoid duplicated `@types` to be loaded.

1. **ONLY** in case you don't have `tsconfig.json` file yet: `mhy config typescript -i`
2. Go to `File > Settings > Language & Frameworks > TypeScript`
3. For `TypeScript` set `GLOBAL_NODE_MODULES/mhy/node_modules/typescript`

> Note that in `mhy` TypeScript is only being used to perform type-checks and to generate `.d.ts` files. You don't need to enable compilation, that is being done by SWC.

## ESLint

1. **ONLY** in case you don't have `.eslintrc` file yet: `mhy config eslint -i`
2. Go to `File > Settings > Language & Frameworks > JavaScript > Code Quality Tools > ESLint`
3. `Enable`
4. For `ESLint package` set `GLOBAL_NODE_MODULES/mhy/node_modules/eslint`
5. Go to `Help > Find Action` and type `registry`
6. Click the first result (`Registry...`)
7. Scroll down to `eslint.additional.file.extensions` and set `js,jsx,ts,tsx` as value.

## Tips

1. Disable automatic `package.json` dependency inspection.
2. Disable statement termination inspection. `CTRL+Enter` at the end of any line. (ONLY in case you choose to continue using ASI which is the default setting.)
3. Set 4 spaces for indent. (ONLY in case you choose to continue using the default setting.)
4. Make sure you use LF for line endings. Set it globally or project level, and also you can convert every file if needed by selecting the `root folder` then `File > Line separators`.
5. You might want most settings/watchers to be global (where possible), so you can re-use them for all your projects.


# VSCode

## Search for global `node_modules` folder (GLOBAL\_NODE\_MODULES)

1. Use the `npm config get prefix` command to find the path to the `mhy` executable file.
2. The *global* `node_modules` folder should be around there somewhere. It varies between different systems, maybe it is right next to it, maybe inside a `lib` directory next to it or the upper levels.
3. Inside the *global* `node_modules` folder, you'll find `mhy/node_modules`. The path to that directory is what we will need.

## Generating config files

```bash
# Generating all possible config files mhy can provide
mhy config

# Use -o to overwrite existing files
mhy config -o

# Generate specific config files
mhy config prettier typescript webpack -io
```

## Alias resolution and `node_modules` resolution

Generate a `tsconfig.json` file in your root folder `mhy config typescript -io`. VSCode will handle it for you, even if you have a JavaScript project.

## Prettier (for automatic formatting on save; recommended)

Generate prettier config `mhy config prettier -io` and install `Prettier - Code formatter` plugin.

> Unfortunately you'll need to create watcher for each `File Type` you want the IDE to watch. By default it was creating it only for JavaScript. Most probably you want to add `jsx, ts, tsx` watcher also. Do this with copying the watcher and change the `File Type`.

## ESLint

1. **ONLY** in case you don't have `.eslintrc` file yet: `mhy config eslint -i`
2. Go to `File > Preferences > Settings > Extensions > ESLint`
3. `Enable`
4. Click on `Edit in settings.json`
5. Grab `mhy`'s node*modules path and add the following key into \_VSCode* `settings.json`: `"eslint.nodePath": ".../mhy-node_modules-path",`
6. Save it.


# package.json overrides

Using `json-merger`'s syntax you have powerful ways to customize configs without *JavaScript* directly in your `package.json` files. There can be some really exotic cases tho. This is a place to collect some of these solutions.

All samples should be placed inside `{ "mhy": { HERE } }` in your `package.json` file.

## Extend `.npmignore` with custom file names

```json
"npmignore": {
  "root": {
    "$concat": [
      "/test",
      "/ci.sh",
      "/.gitbook"
    ]
  }
}
```

## `babel`: Deep customization

> Note: Babel support was replaced by SWC, but the example is still helpful.

1. Change `preset-env` to produce `commonjs` modules
2. Add `module.exports` statements to each module for default exports (from Babel v7 it is not being added anymore by default)
3. Remove `regenerator-plugin`, it doesn't needed in `node`.

```json
"babel": {
  "production": {
    "presets": [
      {
        "$match": {
          "query": "$[?(@[0].includes('preset-env'))]",
          "value": [
            {
              "$match": {
                "index": 1,
                "value": {
                  "modules": "commonjs",
                  "targets": {
                    "node": true,
                    "esmodules": true
                  }
                }
              }
            }
          ]
        }
      }
    ],
    "plugins": [
      {
        "$prepend": {
          "$expression": "$params.require.resolve('babel-plugin-add-module-exports')"
        }
      },
      {
        "$match": {
          "query": "$[?(@.includes('regenerator'))]",
          "value": {
            "$remove": true
          }
        }
      }
    ]
  }
}
```

## `Webpack`: Some customization

1. Generate `index.php` file instead of `index.html` (in this case `html-webpack-plugin` is the first in the plugins array).
2. Change regex for ignored modules from watch. This exact example is useful when working with locally linked npm modules and you want to recompile on it's changes also.

```json
"webpack": {
    "production": {
        "plugins": [{
            "$expression": "Object.assign($targetProperty.options, {filename : 'index.php'})"
        }]
    },
    "development": {
        "watchOptions": {
            "ignored": [
                "node_modules.(?!(my-module-.*)).*"
            ]
        }
    }
}
```

## `Jest`: Load extra environment setup file

```json
"jest": {
  "development": {
    "setupFilesAfterEnv": {
      "$concat": [
        "./test-setup.js"
      ]
    }
  }
}
```


# Add your own

Since `mhy` can be used in many different ways for many different cases, there can be a tons of great solutions. You're always welcome to add your own solutions to the list on the for of a Pull Request.


# FAQ

## Why `mhy`?

My original plan was to make a simple tool that can run all MY(!) processes at once. Then the project grew. The first idea was to run the tool using `my dev`. But the name (*my*) was taken on NPM. Then I checked `mhy` which was free, H is a silent sound when you pronounce it and also finding a 3 letter name is kinda a hidden gem, so I took it. It's important to be short because you'll end up typing the command many times so it's more comfortable.

## Are there any upcoming features?

You can always follow our continuous TODO list here: <https://github.com/wintercounter/mhy/issues/1>

## How can I use another version of a certain package?

`mhy` will try to resolve packages first in your project's `node_modules` folder. Simply install your own version as usual.

## Why no more question?

Feel free to add your own!


# Help

## Experienced/resolve any issues?

Help your fellow developers and make a PR to this page with your solution! Thank you!

## TypeScript

### Errors after updating `mhy` to the latest version.

1. Remove your local `node_modules` folder if you have any.
2. `npm i` if you have any local dependencies.
3. Use `mhy config typescript -io` to regenerate your `tsconfig.json` file.
4. You might also need an IDE restart.


# Development of mhy

## Setup environment (an environment to develop `mhy` itself!)

1. Fork repository
2. Open `mhy`'s `package.json` file.
3. Rewrite the values for `name` and `bin` to something else (eg: `mhyd`).
4. Run `npm link` ([See npmjs.org](https://docs.npmjs.com/cli/link.html))
5. The above command will make your local version of `mhy` available globally with the command (`mhyd`).
6. Create PR when done (do not commit in the changes for the naming).

> Use `npm run build -- --watch` to watch for file changes.
>
> The name rewrite is needed because `mhy` itself is being built using `mhy` which is why you also need an untouched stable version of it.
>
> The environment should work fine on Linux, Mac and Windows also.

## Creating processes/commands

Coming soon...


# Suggest a library

## Suggest a library

You can suggest any JS library to be added to the project. Use GitHub issues for that. The goal is you don't need to install anything to work on you project.


