# ws-directives [![CircleCI](https://circleci.com/gh/wealthsimple/ws-directives.svg?style=svg&circle-token=81f05ae608abbca2fba5dee19038ea566dcecadd)](https://circleci.com/gh/wealthsimple/ws-directives.svg?style=svg&circle-token=81f05ae608abbca2fba5dee19038ea566dcecadd)

Angular directives shared between our UIs.

## installation

install it locally with bower

```sh
bower install --save ws-angular-directives
```

or with npm

```sh
npm install --save @wealthsimple/angular-directives
```

or with yarn

```sh
yarn add @wealthsimple/angular-directives
```

make sure you also have the following installed:

- jquery
- angularjs
- [wealthsimple-fabric](https://github.com/wealthsimple/fabric)
- angular-animate
- angular-ui-router
- angular-translate

Check `peerDependencies` in `package.json` for specific versions.

## usage

[Checkout out our fancy Github page!](http://wealthsimple.github.io/ws-directives/)

## local development

1. run `npm install` to install dev dependencies
2. run `npm run start:dev` o watch & build files, and serve up the examples page.
3. open [http://localhost:8080](http://localhost:8080) in your browser to preview your changes.

As you make changes, the output will be rebuilt and the browser will re-load your changes automatically.

## hooking your local copy into another project

Use `bower link` (or `npm link`) if you'd like to reference this library locally from another ng project
* run `bower link` (or `npm link`) in root of this library
* run `bower link ws-angular-directives` (or `npm link @wealthsimple/angular-directives`) in the root of the other ng project to refer to your local version of this library.

## publishing

If you have merge rights, you should also have the ability to release new versions (you know who to ask for access).

We currently publish on both `bower` and `npm` package registries.

Once you merge a change to master, follow the steps below to issue a new release of this package:

### 1. prepare a PR with updated distributables and a new version number.

Please follow [semantic versioning](http://semver.org/). **Seriously, this is super important**. If you don't and downstream users are careless with their shrinkwrapping strategy, **you may break them**.

Once you've picked a new version number, update the `version` field in `package.json` to that version. This is what NPM will use. Also run this command locally:

`npm run prepublishOnly`

This builds the new `dist` outputs that we'll publish. It also regenerate the github-pages content in `docs`.

Get this PRed up and approved, then merge it.

**At this point gh-pages is using the new code**

### 2. prepare a new release

* Go to the ['releases' tab in github](https://github.com/wealthsimple/ws-directives/releases).
* Hit the 'draft new release button'. Use the `master` branch only please. This does two things:
    * it prompts you to enter some info about what's in the new release. **Be descriptive!** This serves as our changelog, and your colleagues will thank you. Screenshots of new controls/features are handy too.
    * it creates the git tag that bower will use.

### 3. publish

At this point bower already knows about the new version: the act of creating the git tag in the last step was enough. When consumers update their bower dependencies they'll get the version of the `/dist` folder at that tag.

For `npm` you need to manually publish.  Go to your terminal, rebase latest master, and run:

```sh
npm login
npm publish
```

This runs the unit tests, regenerates the distributables, and uploads them to `npm`'s registry.

## My awesome new feature requires me to use amazing-3rdparty-lib.js. Can I add it as a dependency?

Sure, make a PR. Get someone from #web-tech-maintenance to review it though, so we can check that the license is in line with policies, etc. Be aware that this is the start of the conversation though. Pulling in new libs requires a little extra diligence from the broader team.

Also think about whether it should be a dependency or a peerDependency.

### Dependencies:

These are for things that you don't expect consumers to also be using.  So, really specific libs that are implementation details of a component for example.

Dependencies will get included directly in our webpack output bundle, so be aware that if consumers are also using those libs they'll end up with two copies in their bundles, which apart from being wasteful can also cause problems at runtime.

Generally it should be pretty rare to add new dependencies.

### PeerDependencies:

Peer dependencies are for things that you expect consumers to also be using directly. We don't include them in our output bundle; instead, we expect consumers to install them alongside ws-directives (npm will give them an error if they don't).

So for example, AngularJS is a peer dependency.

Most of the time, new deps will be peer dependencies.

To add a peerDependency, do three things:

1) add it to `peerDependencies` in `package.json`: specify a version range that we'll commit to working with.  Our webpack config loads the list of `peerDependencies` and marks them as `external`, meaning if you `import` them in code, webpack won't include them in our bundle.
2) also add a specific version to `devDependencies` so you can develop against it
3) but since it's not in the bundle, you'll have to edit `index.html` to pull the lib in from a CDN. I recommend http://unpkg.com, which is a thin wrapper over the npm registry exposed as a CDN.

### Can I use underscore/lodash/ramda? Pleaaase?

My default stance is: yes in consuming projects, **but probably not in ws-directives**.  Those libs are pretty big and I don't want to force consumers to include them.

The good news is we do expect consumers to target modern JavaScript runtimes, with polyfills as necessary (e.g. core-js). Which means you can use `array.map`, `array.prototype.includes`, `array.prototype.reduce`, `array.prototype.filter`, `Array.prototype.forEach`, etc.  That should cover most of your underscore needs.  If it doesn't, post in #web-tech-maintenance and we'll discuss it.

### How can I check that I got it right?

1) Run the unit tests to make sure the new lib is available to the test setup: `npm run test`.
2) Run the example page in devmode to make sure you got any CDN additions right: `npm run start:dev`, `open http://localhost:8080`.
3) Look at the bundle stats report to make sure the dep is included or not included as appropriate: `npm run build:docs && open docs/report.html`
