From 15b22572ef6e90780fc0053f2ce18e468e595dc4 Mon Sep 17 00:00:00 2001 From: Oleg Proskurin Date: Fri, 10 Mar 2017 11:39:53 +0700 Subject: [PATCH 01/29] fix Jest logo --- img/jest-padded-90.png | Bin 2101 -> 23556 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/img/jest-padded-90.png b/img/jest-padded-90.png index f1aacf78e7ea55e6619de6257025cee7a8304d14..e2b0830e02fb184c2baff5c5f4c7bff7249c9793 100644 GIT binary patch literal 23556 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 O>DE%yQ!N5nh5kQbo`1Ul delta 2090 zcmV+_2-Ww5xB;~gkRyKw{7FPXRCt`_oq4QWQyj-Xk5*|YwQH+h5v7QzCDv5zVqZ%_ z>=7zNDIr86wiLD2k|K6$i>lX_($-qk(yFZ~N^K9-YIUQVKfW`0^X|;MbI$LanYlMU z$wcSAbAI>CckcY|@BGg1TupfL!2U=3cCm6fFc|oyUMF;*3D|!G7;)Z&QP=u(>{Ofa zL}3d0P@6P*APN2kUiR&@S`7vgi;2KHjUGe=UIae&?UZGq!Eoi&fzg&uSr@tmSlZ}8 zl<)&E-qJDaLVpFk*XTi%@EWkd(lP5ouL8z4dJrYFSUYB2XwX%Z1^4kC@P@T>9)$i3 z_@L2)KsUjK*3N%<5E_hk`Vy`J?hmvvE~Il_gnk8BZ0tK1xD6Nz{A;xFHSo5vFOVOh zXJG%JBapze&}75H>%byoUm!n11B^2CSp*C(d4C(Q+|$NN^ot52PePAJc?KWu1AZ)d z{}J$vr;VAwo1T5j$dl0D0Fyl0{{`Gr;rOj6K6hmt5yF4VJP8dj#-r^MXv&;q8t{UL zozRE}$e+-!0`nc(%}4&YBZlJUtEU0)I<%`w-h`fo(x=sU5codj?^AHQQb!SKR+=}V zq58z(AK-2WJJs5(#Lrcwl1HJ(qDe?cJVIsPoMa;D39D(qRQF+}lSiRv0~0#<+hW|V z<{~$z{B3_U`gKGhk3vJo{`Gm_3lBSQQTeJ~iEg~n$g9w=1M?Ec7L$I3cEnI5Y$;RG zBq5W#da$s11tveI%gL4~6@+|aN;LpOp zN1!RXl`*vaLOv|KqLOE!f1|Cw;@$}M?kN1X1^<5xUsbYPspP^RDRPkmfsuuFR=NOBQZ90l?NOxA z9B_`VXe}`*a*-W@XMruOCkPdK2(WvVHvIvw>i7hMkxNRW4{&|JIW7kFtmJ;vF(51#&ZPu=nauybD6RkN`dZ6TZ!4SLSNVMn4*sm*YP_lE^*;Y3|B$n9Mc`!&O()^MOH%*5lG-}g=2qx zfDKC8{f7IJ)z67@I1?iDa^NAywvS+2O5NU3Z{g;+Sit=|eQ& ziUtWdvPzp4wES;n9M#1hM_cx-$RWVS9kf3*@qQFaD5dcl<#}soLWN#|W>U9O{!K4M z13QuMMa~O>OVNz8lqJAjz%jI65m|o&7?fh~40NL{Wk})mXX5x0^!bj(UOG&ZZ--YE&?9&=rb6t&UAlqY;VpQ z#u9p+NOmlAMLCr*=$_!~4$nthp$Ag#w~KT^v)l2&0hU3=a2>m#G~!I)O45r9V=x%l z2;E>e1$F}V2(-B?N-BK|Oh)nYJd|eWfs#u56xx1@VH;cwp)W*Y?*d#M!Co5Yl3tD* z%2tI}8hZh2;Tcbdx{kiI-MN3KqS;xk*alSPM&x3`h<~FtnH1Kgk1B#^<){!)qIM|+*$}&x=LaZ+LHV}xbVsX z%a9wGjZ(UE&{nr^k;ta!+Ev3MboBilHRK;OlbeR>F=nB4%!Pkw5!U?FFJCM|Cs&EH z#ynJBI}xpjd`SkLn`aUF``Cks#1s@Jj>WyYscu+=uC%=0D3+sLulJ$yhPt@|Uo1ku zk8U8fNQt`g7n-TvTNsbeGm;vDC5~<-(sPCk6f2VkpnUjbav(C;vv3 zxh+83++r{jmH3XtR=A#7LJMe?qCI%ik?*u@q?wDRz)zxWY(X0*vr4RL(%XTjflE-0 zTBS<+Qs$zt>_e2miScxTOcS$gw-vYoMI?Ko(yBhF>V6^x68Aeavz&^OIR6{|1Iu2U UK>cf&+5i9m07*qoM6N<$f@`7xC;$Ke From c2454b618ac84860f9805ef983b2a57d75c8dc8a Mon Sep 17 00:00:00 2001 From: Fabrizio Bertone Date: Sun, 12 Mar 2017 11:53:12 +0100 Subject: [PATCH 02/29] fix repetition in Webpack section remove a duplicated "in" --- tutorial/04-webpack-react-hmr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial/04-webpack-react-hmr.md b/tutorial/04-webpack-react-hmr.md index 39ad3d0e..3ab0d976 100644 --- a/tutorial/04-webpack-react-hmr.md +++ b/tutorial/04-webpack-react-hmr.md @@ -27,7 +27,7 @@ import { APP_CONTAINER_SELECTOR } from '../shared/config' document.querySelector(APP_CONTAINER_SELECTOR).innerHTML = '

Hello Webpack!

' ``` -If you want to use some of the most recent ES features in your client code, like `Promise`s, you need to include the [Babel Polyfill](https://babeljs.io/docs/usage/polyfill/) before anything else in in your bundle. +If you want to use some of the most recent ES features in your client code, like `Promise`s, you need to include the [Babel Polyfill](https://babeljs.io/docs/usage/polyfill/) before anything else in your bundle. - Run `yarn add babel-polyfill` From 1deb43ebc7cb8e42a478aa86bc0099805e04da00 Mon Sep 17 00:00:00 2001 From: Samar Dhwoj Acharya Date: Fri, 10 Mar 2017 22:20:29 -0600 Subject: [PATCH 03/29] update info about immutable import update code update more codes and fix flow type check remove note about immutable-js & update type import remove unnecessary line --- tutorial/05-redux-immutable-fetch.md | 12 ++++++------ tutorial/06-react-router-ssr-helmet.md | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tutorial/05-redux-immutable-fetch.md b/tutorial/05-redux-immutable-fetch.md index 713fb5db..65bc2b2d 100644 --- a/tutorial/05-redux-immutable-fetch.md +++ b/tutorial/05-redux-immutable-fetch.md @@ -46,8 +46,6 @@ console.log(immutablePerson) - Run `yarn add immutable` -**Note**: Due to the implementation of ImmutableJS, Flow does not accept importing it with `import Immutable from 'immutable'`, so use this syntax instead: `import * as Immutable from 'immutable'`. Let's cross fingers for a [fix](https://github.com/facebook/immutable-js/issues/863) soon. - ## Redux > 馃挕 **[Redux](http://redux.js.org/)** is a library to handle the lifecycle of your application. It creates a *store*, which is the single source of truth of the state of your app at any given time. @@ -75,7 +73,8 @@ This file exposes an *action*, `SAY_HELLO`, and its *action creator*, `sayHello` ```js // @flow -import * as Immutable from 'immutable' +import Immutable from 'immutable' +import type { fromJS as Immut } from 'immutable' import { SAY_HELLO } from '../action/hello' @@ -83,7 +82,7 @@ const initialState = Immutable.fromJS({ message: 'Initial reducer message', }) -const helloReducer = (state: Object = initialState, action: { type: string, payload: any }) => { +const helloReducer = (state: Immut = initialState, action: { type: string, payload: any }) => { switch (action.type) { case SAY_HELLO: return state.set('message', action.payload) @@ -412,7 +411,8 @@ Let's handle these different actions in `src/client/reducer/hello.js`: ```js // @flow -import * as Immutable from 'immutable' +import Immutable from 'immutable' +import type { fromJS as Immut } from 'immutable' import { SAY_HELLO, @@ -426,7 +426,7 @@ const initialState = Immutable.fromJS({ messageAsync: 'Initial reducer message for async call', }) -const helloReducer = (state: Object = initialState, action: { type: string, payload: any }) => { +const helloReducer = (state: Immut = initialState, action: { type: string, payload: any }) => { switch (action.type) { case SAY_HELLO: return state.set('message', action.payload) diff --git a/tutorial/06-react-router-ssr-helmet.md b/tutorial/06-react-router-ssr-helmet.md index 539b5475..cb215abb 100644 --- a/tutorial/06-react-router-ssr-helmet.md +++ b/tutorial/06-react-router-ssr-helmet.md @@ -303,7 +303,7 @@ Here is our controller. It would typically make business logic and database call ```js // @flow -import * as Immutable from 'immutable' +import Immutable from 'immutable' import { createStore, combineReducers, applyMiddleware } from 'redux' import thunkMiddleware from 'redux-thunk' @@ -408,7 +408,7 @@ export default renderApp - Edit `src/client/index.jsx` to use that preloaded state: ```js -import * as Immutable from 'immutable' +import Immutable from 'immutable' // [...] /* eslint-disable no-underscore-dangle */ From 533b6e414bb401f15ff35b1178c0e3550a4ec320 Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Mon, 13 Mar 2017 12:42:52 +0800 Subject: [PATCH 04/29] Add explanation about import type --- tutorial/05-redux-immutable-fetch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial/05-redux-immutable-fetch.md b/tutorial/05-redux-immutable-fetch.md index 65bc2b2d..7f811d7b 100644 --- a/tutorial/05-redux-immutable-fetch.md +++ b/tutorial/05-redux-immutable-fetch.md @@ -94,7 +94,7 @@ const helloReducer = (state: Immut = initialState, action: { type: string, paylo export default helloReducer ``` -In this file we initialize the state of our reducer with an Immutable Map containing one property, `message`, set to `Initial reducer message`. The `helloReducer` handles `SAY_HELLO` actions by simply setting the new `message` with the action payload. The Flow annotation for `action` destructures it into a `type` and a `payload`. The `payload` can be of `any` type. It looks funky if you've never seen this before, but it remains pretty understandable. Note the usage of `Immutable.fromJS()` and `set()` as seen before. +In this file we initialize the state of our reducer with an Immutable Map containing one property, `message`, set to `Initial reducer message`. The `helloReducer` handles `SAY_HELLO` actions by simply setting the new `message` with the action payload. The Flow annotation for `action` destructures it into a `type` and a `payload`. The `payload` can be of `any` type. It looks funky if you've never seen this before, but it remains pretty understandable. For the type of `state`, we use the `import type` Flow instruction to get the return type of `fromJS`. We rename it to `Immut` for clarity, because `state: fromJS` would be pretty confusing. The `import type` line will get stripped out like any other Flow annotation. Note the usage of `Immutable.fromJS()` and `set()` as seen before. ## React-Redux From 26469a95e8d18cfe31072b5b726eeb37d17ab415 Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Mon, 13 Mar 2017 12:52:02 +0800 Subject: [PATCH 05/29] Update all Jest logos, optimized --- img/jest-padded-90.png | Bin 23556 -> 3131 bytes img/jest-padded.png | Bin 2795 -> 3965 bytes img/jest.png | Bin 2664 -> 3821 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/img/jest-padded-90.png b/img/jest-padded-90.png index e2b0830e02fb184c2baff5c5f4c7bff7249c9793..1f942a87a6de8fb3f8d5083d80c059907ad02d1c 100644 GIT binary patch delta 3128 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 O>DE%yQ!N5nh5kQbo`1Ul diff --git a/img/jest-padded.png b/img/jest-padded.png index 9e39cba852f39a3119d87d2617b340df5479a03a..ff62dd02a4c1494345c04758ad9738d0ac16b1a4 100644 GIT binary patch literal 3965 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 XIA9IW7+~=F00000NkvXXu0mjf#>a(s delta 2788 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 WDIY#tQA8jB0000 Date: Mon, 13 Mar 2017 12:55:12 +0800 Subject: [PATCH 06/29] Clarified module resolution part for Webpack --- tutorial/04-webpack-react-hmr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial/04-webpack-react-hmr.md b/tutorial/04-webpack-react-hmr.md index 3ab0d976..6ccc9372 100644 --- a/tutorial/04-webpack-react-hmr.md +++ b/tutorial/04-webpack-react-hmr.md @@ -78,7 +78,7 @@ export default { } ``` -This file is used to describe how our bundle should be assembled: `entry` is the starting point of our app, `output.filename` is the name of the bundle to generate, `output.path` and `output.publicPath` describe the destination folder and URL. We put the bundle in a `dist` folder, which will contain things that are generated automatically (unlike the declarative CSS we created earlier which lives in `public`). `module.rules` is where you tell Webpack to apply some treatment to some type of files. Here we say that we want all `.js` and `.jsx` (for React) files except the ones in `node_modules` to go through something called `babel-loader`. We also want these two extensions to `resolve`. Finally, we declare a port for Webpack Dev Server. +This file is used to describe how our bundle should be assembled: `entry` is the starting point of our app, `output.filename` is the name of the bundle to generate, `output.path` and `output.publicPath` describe the destination folder and URL. We put the bundle in a `dist` folder, which will contain things that are generated automatically (unlike the declarative CSS we created earlier which lives in `public`). `module.rules` is where you tell Webpack to apply some treatment to some type of files. Here we say that we want all `.js` and `.jsx` (for React) files except the ones in `node_modules` to go through something called `babel-loader`. We also want these two extensions to be used to `resolve` modules when we `import` or `require` them. Finally, we declare a port for Webpack Dev Server. **Note**: The `.babel.js` extension is a Webpack feature to apply our Babel transformations to this config file. From a78b44ce65d34fd7c64172c998c6d30479f3ae32 Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Mon, 13 Mar 2017 12:56:25 +0800 Subject: [PATCH 07/29] Shorten text --- tutorial/04-webpack-react-hmr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial/04-webpack-react-hmr.md b/tutorial/04-webpack-react-hmr.md index 6ccc9372..a22ec5de 100644 --- a/tutorial/04-webpack-react-hmr.md +++ b/tutorial/04-webpack-react-hmr.md @@ -78,7 +78,7 @@ export default { } ``` -This file is used to describe how our bundle should be assembled: `entry` is the starting point of our app, `output.filename` is the name of the bundle to generate, `output.path` and `output.publicPath` describe the destination folder and URL. We put the bundle in a `dist` folder, which will contain things that are generated automatically (unlike the declarative CSS we created earlier which lives in `public`). `module.rules` is where you tell Webpack to apply some treatment to some type of files. Here we say that we want all `.js` and `.jsx` (for React) files except the ones in `node_modules` to go through something called `babel-loader`. We also want these two extensions to be used to `resolve` modules when we `import` or `require` them. Finally, we declare a port for Webpack Dev Server. +This file is used to describe how our bundle should be assembled: `entry` is the starting point of our app, `output.filename` is the name of the bundle to generate, `output.path` and `output.publicPath` describe the destination folder and URL. We put the bundle in a `dist` folder, which will contain things that are generated automatically (unlike the declarative CSS we created earlier which lives in `public`). `module.rules` is where you tell Webpack to apply some treatment to some type of files. Here we say that we want all `.js` and `.jsx` (for React) files except the ones in `node_modules` to go through something called `babel-loader`. We also want these two extensions to be used to `resolve` modules when we `import` them. Finally, we declare a port for Webpack Dev Server. **Note**: The `.babel.js` extension is a Webpack feature to apply our Babel transformations to this config file. From 5e0e85f22afb3f63a01f22c72ec479dd16851d39 Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Mon, 13 Mar 2017 13:05:41 +0800 Subject: [PATCH 08/29] Add comment about yarn add --dev husky --force --- tutorial/02-babel-es6-eslint-flow-jest-husky.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tutorial/02-babel-es6-eslint-flow-jest-husky.md b/tutorial/02-babel-es6-eslint-flow-jest-husky.md index d291d10b..e6a9193a 100644 --- a/tutorial/02-babel-es6-eslint-flow-jest-husky.md +++ b/tutorial/02-babel-es6-eslint-flow-jest-husky.md @@ -325,6 +325,8 @@ All we have to do is to create two new tasks in `scripts`, `precommit` and `prep 馃弫 If you now try to commit or push your code, it should automatically run the `test` task. +If it does not work, it is possible that `yarn add --dev husky` did not install the Git Hooks properly. I never encountered this issue but it happens for some people. If that's your case, run `yarn add --dev husky --force`, and maybe post a note in [this issue](https://github.com/typicode/husky/issues/84) to describe your case. + **Note**: If you are pushing right after a commit, you can use `git push --no-verify` to avoid running all the tests again. Next section: [03 - Express, Nodemon, PM2](03-express-nodemon-pm2.md#readme) From 2c7934351c868b2f20d9c0b5419b4686beb6f6f6 Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Mon, 13 Mar 2017 13:06:53 +0800 Subject: [PATCH 09/29] Wording --- tutorial/02-babel-es6-eslint-flow-jest-husky.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial/02-babel-es6-eslint-flow-jest-husky.md b/tutorial/02-babel-es6-eslint-flow-jest-husky.md index e6a9193a..845f0174 100644 --- a/tutorial/02-babel-es6-eslint-flow-jest-husky.md +++ b/tutorial/02-babel-es6-eslint-flow-jest-husky.md @@ -325,7 +325,7 @@ All we have to do is to create two new tasks in `scripts`, `precommit` and `prep 馃弫 If you now try to commit or push your code, it should automatically run the `test` task. -If it does not work, it is possible that `yarn add --dev husky` did not install the Git Hooks properly. I never encountered this issue but it happens for some people. If that's your case, run `yarn add --dev husky --force`, and maybe post a note in [this issue](https://github.com/typicode/husky/issues/84) to describe your case. +If it does not work, it is possible that `yarn add --dev husky` did not install the Git Hooks properly. I never encountered this issue but it happens for some people. If that's your case, run `yarn add --dev husky --force`, and maybe post a note in [this issue](https://github.com/typicode/husky/issues/84) describing your case. **Note**: If you are pushing right after a commit, you can use `git push --no-verify` to avoid running all the tests again. From b6c4a3fbb7b1f8b776273d3d8017f0db2399b111 Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Mon, 13 Mar 2017 13:07:42 +0800 Subject: [PATCH 10/29] Wording --- tutorial/02-babel-es6-eslint-flow-jest-husky.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial/02-babel-es6-eslint-flow-jest-husky.md b/tutorial/02-babel-es6-eslint-flow-jest-husky.md index 845f0174..4f7377a3 100644 --- a/tutorial/02-babel-es6-eslint-flow-jest-husky.md +++ b/tutorial/02-babel-es6-eslint-flow-jest-husky.md @@ -325,7 +325,7 @@ All we have to do is to create two new tasks in `scripts`, `precommit` and `prep 馃弫 If you now try to commit or push your code, it should automatically run the `test` task. -If it does not work, it is possible that `yarn add --dev husky` did not install the Git Hooks properly. I never encountered this issue but it happens for some people. If that's your case, run `yarn add --dev husky --force`, and maybe post a note in [this issue](https://github.com/typicode/husky/issues/84) describing your case. +If it does not work, it is possible that `yarn add --dev husky` did not install the Git Hooks properly. I never encountered this issue but it happens for some people. If that's your case, run `yarn add --dev husky --force`, and maybe post a note describing your situation in [this issue](https://github.com/typicode/husky/issues/84). **Note**: If you are pushing right after a commit, you can use `git push --no-verify` to avoid running all the tests again. From 8779d934dea2b825dbd1a8fbb5a1f82e2550b24a Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Mon, 13 Mar 2017 13:25:18 +0800 Subject: [PATCH 11/29] Update prod:stop command --- tutorial/03-express-nodemon-pm2.md | 2 +- tutorial/04-webpack-react-hmr.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorial/03-express-nodemon-pm2.md b/tutorial/03-express-nodemon-pm2.md index 52d91c04..9a80f35a 100644 --- a/tutorial/03-express-nodemon-pm2.md +++ b/tutorial/03-express-nodemon-pm2.md @@ -197,7 +197,7 @@ Let's update our `package.json` like so: "dev:start": "nodemon --ignore lib --exec babel-node src/server", "prod:build": "rimraf lib && babel src -d lib --ignore .test.js", "prod:start": "cross-env NODE_ENV=production pm2 start lib/server && pm2 logs", - "prod:stop": "pm2 delete all", + "prod:stop": "pm2 delete server", "test": "eslint src && flow && jest --coverage", "precommit": "yarn test", "prepush": "yarn test" diff --git a/tutorial/04-webpack-react-hmr.md b/tutorial/04-webpack-react-hmr.md index a22ec5de..a78026d9 100644 --- a/tutorial/04-webpack-react-hmr.md +++ b/tutorial/04-webpack-react-hmr.md @@ -103,7 +103,7 @@ Let's update our `scripts` to implement all this, and improve some other tasks a "dev:wds": "webpack-dev-server --progress", "prod:build": "rimraf lib dist && babel src -d lib --ignore .test.js && cross-env NODE_ENV=production webpack -p --progress", "prod:start": "cross-env NODE_ENV=production pm2 start lib/server && pm2 logs", - "prod:stop": "pm2 delete all", + "prod:stop": "pm2 delete server", "lint": "eslint src webpack.config.babel.js --ext .js,.jsx", "test": "yarn lint && flow && jest --coverage", "precommit": "yarn test", From 923bc59e135eb7c0eb413e502f93e992314ceb63 Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Mon, 13 Mar 2017 13:31:20 +0800 Subject: [PATCH 12/29] Add link to tj/n --- tutorial/01-node-yarn-package-json.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorial/01-node-yarn-package-json.md b/tutorial/01-node-yarn-package-json.md index ffbc6cf1..521fc0cf 100644 --- a/tutorial/01-node-yarn-package-json.md +++ b/tutorial/01-node-yarn-package-json.md @@ -19,9 +19,9 @@ sudo apt-get install -y nodejs You want any version of Node > 6.5.0. -## NVM +## Node Version Management Tools -If Node is already installed, or if you want more flexibility, install NVM ([Node Version Manager](https://github.com/creationix/nvm)), and make NVM install and use the latest version of Node for you. +If you need the flexibility to use multiple versions of Node, check out [NVM](https://github.com/creationix/nvm) or [tj/n](https://github.com/tj/n). ## NPM From f0fa0cd7d215fb1b2e77c6dbcc0a3cc747626021 Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Mon, 13 Mar 2017 15:36:47 +0800 Subject: [PATCH 13/29] Add React component explicit types, new Webpack config for publicPath --- package.json | 2 +- tutorial/04-webpack-react-hmr.md | 6 +++--- tutorial/05-redux-immutable-fetch.md | 13 +++++++++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 41453e8e..31cfdff2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "js-stack-from-scratch", - "version": "2.4.3", + "version": "2.4.4", "description": "JavaScript Stack from Scratch - Step-by-step tutorial to build a modern JavaScript stack", "scripts": { "test": "node mdlint.js" diff --git a/tutorial/04-webpack-react-hmr.md b/tutorial/04-webpack-react-hmr.md index a78026d9..f717b5db 100644 --- a/tutorial/04-webpack-react-hmr.md +++ b/tutorial/04-webpack-react-hmr.md @@ -59,9 +59,9 @@ export default { './src/client', ], output: { - filename: 'bundle.js', - path: path.resolve(__dirname, 'dist/js'), - publicPath: `http://localhost:${WDS_PORT}/dist/js/`, + filename: 'js/bundle.js', + path: path.resolve(__dirname, 'dist'), + publicPath: isProd ? '/static/' : `http://localhost:${WDS_PORT}/dist/`, }, module: { rules: [ diff --git a/tutorial/05-redux-immutable-fetch.md b/tutorial/05-redux-immutable-fetch.md index 7f811d7b..99b686f9 100644 --- a/tutorial/05-redux-immutable-fetch.md +++ b/tutorial/05-redux-immutable-fetch.md @@ -113,7 +113,12 @@ In this section we are going to create *Components* and *Containers*. import React, { PropTypes } from 'react' -const Button = ({ label, handleClick }: { label: string, handleClick: Function }) => +type Props = { + label: string, + handleClick: Function, +} + +const Button = ({ label, handleClick }: Props) => Button.propTypes = { @@ -133,7 +138,11 @@ export default Button import React, { PropTypes } from 'react' -const Message = ({ message }: { message: string }) => +type Props = { + message: string, +} + +const Message = ({ message }: Props) =>

{message}

Message.propTypes = { From 551392e32af23ae533090268e3eed893a334544e Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Mon, 13 Mar 2017 16:59:59 +0800 Subject: [PATCH 14/29] Small fixes including immutable@4.0.0-rc2 --- tutorial/05-redux-immutable-fetch.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tutorial/05-redux-immutable-fetch.md b/tutorial/05-redux-immutable-fetch.md index 99b686f9..d721416c 100644 --- a/tutorial/05-redux-immutable-fetch.md +++ b/tutorial/05-redux-immutable-fetch.md @@ -44,7 +44,7 @@ console.log(immutablePerson) */ ``` -- Run `yarn add immutable` +- Run `yarn add immutable@4.0.0-rc.2` ## Redux @@ -129,7 +129,7 @@ Button.propTypes = { export default Button ``` -**Note**: You can see another case of destructuring with Flow annotations here. If `props` contains `handleClick`, instead of writing `const Button = (props) => { props.handleClick() }`, we write `const Button = ({ handleClick }: { handleClick: Function }) => { handleClick() }`. The syntax is a bit cumbersome but worth it. +**Note**: You can see a case of Flow *type alias* here. We define the `Props` type before annotating our component's destructured `props` with it. - Create a `src/client/component/message.jsx` file containing: @@ -545,7 +545,7 @@ In order to isolate the logic that is specific to `action/hello.js` we are going - Run `yarn add --dev redux-mock-store fetch-mock` -- Create a `src/client/action/hello.test.js` containing: +- Create a `src/client/action/hello.test.js` file containing: ```js import fetchMock from 'fetch-mock' From 7f43b3a630b577796db1ca74227c8cbdd527475a Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Mon, 13 Mar 2017 17:24:27 +0800 Subject: [PATCH 15/29] Add link to JSS benefits --- tutorial/08-bootstrap-jss.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial/08-bootstrap-jss.md b/tutorial/08-bootstrap-jss.md index 54cfc7e8..44387925 100644 --- a/tutorial/08-bootstrap-jss.md +++ b/tutorial/08-bootstrap-jss.md @@ -264,7 +264,7 @@ const App = () => This is an example of a *React inline style*. -This will translate into: `
` in your DOM. We need this style to push the content under the navigation bar, but that's what's important here. [React inline styles](https://speakerdeck.com/vjeux/react-css-in-js) are a great way to isolate your component's styles from the global CSS namespace, but it comes at a price: You cannot use some native CSS features like `:hover`, Media Queries, animations, or `font-face`. That's the reason why we're going to integrate a CSS-in-JS library, JSS, later in this chapter. For now, just keep in mind that you can use React inline styles this way if you don't need `:hover` and such. +This will translate into: `
` in your DOM. We need this style to push the content under the navigation bar, but that's what's important here. [React inline styles](https://speakerdeck.com/vjeux/react-css-in-js) are a great way to isolate your component's styles from the global CSS namespace, but it comes at a price: You cannot use some native CSS features like `:hover`, Media Queries, animations, or `font-face`. That's [one of the reasons](https://github.com/cssinjs/jss/blob/master/docs/benefits.md#compared-to-inline-styles) we're going to integrate a CSS-in-JS library, JSS, later in this chapter. - Edit `src/shared/component/nav.jsx` like so: From 7829fd4062e9d1dfb7bc8507bb47fff697f30207 Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Mon, 13 Mar 2017 17:34:24 +0800 Subject: [PATCH 16/29] Use node_modules/bootstrap/dist files instead of downloading them --- tutorial/08-bootstrap-jss.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tutorial/08-bootstrap-jss.md b/tutorial/08-bootstrap-jss.md index 44387925..48149ba2 100644 --- a/tutorial/08-bootstrap-jss.md +++ b/tutorial/08-bootstrap-jss.md @@ -21,7 +21,9 @@ For this reason, I'm going to make the tradeoff of integrating the official rele - Delete `public/css/style.css` -- Download the latest official release from Bootstrap and put `bootstrap.min.css` and `bootstrap.min.css.map` in the `public/css` folder. +- Run `yarn add bootstrap@4.0.0-alpha.6` + +- Copy `bootstrap.min.css` and `bootstrap.min.css.map` from `node_modules/bootstrap/dist` to your `public/css` folder. - Edit `src/server/render-app.jsx` like so: @@ -33,7 +35,7 @@ For this reason, I'm going to make the tradeoff of integrating the official rele Now that we have Bootstrap's styles loaded on our page, we need the JavaScript behavior for the components. -- Run `yarn add jquery tether bootstrap@4.0.0-alpha.6` +- Run `yarn add jquery tether` - Edit `src/client/index.jsx` like so: From d8e897b6357f3ec359154df2bc94a1588e731332 Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Mon, 13 Mar 2017 18:05:33 +0800 Subject: [PATCH 17/29] Add JSS composes example --- tutorial/08-bootstrap-jss.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tutorial/08-bootstrap-jss.md b/tutorial/08-bootstrap-jss.md index 48149ba2..542aa615 100644 --- a/tutorial/08-bootstrap-jss.md +++ b/tutorial/08-bootstrap-jss.md @@ -427,6 +427,10 @@ const styles = { color: 'red', }, }, + specialButton: { + composes: ['btn', 'btn-primary'], + backgroundColor: 'limegreen', + }, } const HomePage = ({ classes }: { classes: Object }) => @@ -435,6 +439,7 @@ const HomePage = ({ classes }: { classes: Object }) =>

JSS

Hover me.

Resize the window.

+
// [...] @@ -447,7 +452,7 @@ Unlike React inline styles, JSS uses classes. You pass styles to `injectSheet` a **Note**: In production mode, the `data-meta` is obfuscated. Sweet! -If you hover over the "Hover me" label, it should turn red. If you resize your browser window to be narrower than 800px, the "Resize your window" label should turn red. +If you hover over the "Hover me" label, it should turn red. If you resize your browser window to be narrower than 800px, the "Resize your window" label should turn red. The green button is extending Bootstrap's CSS classes using JSS' `composes` property. Next section: [09 - Travis, Coveralls, Heroku](09-travis-coveralls-heroku.md#readme) From 158f3af482d31a54569c97ba7db67dbd252f80e0 Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Tue, 14 Mar 2017 10:29:15 +0800 Subject: [PATCH 18/29] Tweak part about JSS --- tutorial/08-bootstrap-jss.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial/08-bootstrap-jss.md b/tutorial/08-bootstrap-jss.md index 542aa615..d280fe0c 100644 --- a/tutorial/08-bootstrap-jss.md +++ b/tutorial/08-bootstrap-jss.md @@ -342,7 +342,7 @@ The cool React kids tend to favor React inline styles, CSS-in-JS, or CSS Modules CSS Modules work well, but they don't leverage the power of JavaScript and its many features over CSS. They just provide encapsulation, which is fine, but React inline styles and CSS-in-JS take styling to an other level in my opinion. My personal suggestion would be to use React inline styles for common styles (that's also what you have to use for React Native), and use a CSS-in-JS library for things like `:hover` and media queries. -There are tons of CSS-in-JS libraries. Two leading ones are Aphrodite and JSS. They achieve pretty much the same thing and the syntax is basically the same. To be honest, I haven't done a comparison of the two on any significant-size project, and really just have a slight preference for JSS' API. We can discuss this topic in [this issue](https://github.com/verekia/js-stack-from-scratch/issues/139). I would like to hear the opinion of those who have done a more thorough comparison. +There are [tons of CSS-in-JS libraries](https://github.com/MicheleBertoli/css-in-js). JSS is a full-featured, well-rounded, and [performant](https://github.com/cssinjs/jss/blob/master/docs/performance.md) one. ## JSS From 4adadb919d23adc939db4f815f904b761792fb0a Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Wed, 15 Mar 2017 10:12:07 +0800 Subject: [PATCH 19/29] Create LICENSE.md --- LICENSE.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..5964e335 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Jonathan Verrecchia + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 9b01a871b4724c6b20841dfce13f4336fa781120 Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Wed, 15 Mar 2017 10:15:05 +0800 Subject: [PATCH 20/29] Update LICENSE.md --- LICENSE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.md b/LICENSE.md index 5964e335..8095afd2 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -MIT License +# MIT License Copyright (c) 2017 Jonathan Verrecchia From c65dfa65d02c21063d94f0955de90947ba5273ad Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Wed, 15 Mar 2017 10:27:18 +0800 Subject: [PATCH 21/29] Add flow-react-proptypes --- tutorial/04-webpack-react-hmr.md | 7 +++++-- tutorial/05-redux-immutable-fetch.md | 13 ++----------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/tutorial/04-webpack-react-hmr.md b/tutorial/04-webpack-react-hmr.md index f717b5db..e76e90ab 100644 --- a/tutorial/04-webpack-react-hmr.md +++ b/tutorial/04-webpack-react-hmr.md @@ -199,9 +199,9 @@ const App = () =>

Hello React!

export default App ``` -Since we use the JSX syntax here, we have to tell Babel that it needs to transform it as well. +Since we use the JSX syntax here, we have to tell Babel that it needs to transform it with the `babel-preset-react` preset. And while we're at it, we're also going to add a Babel plugin called `flow-react-proptypes` which automatically generates PropTypes from Flow annotations for your React components. -- Run `yarn add --dev babel-preset-react` and add `react` to your `.babelrc` file like so: +- Run `yarn add --dev babel-preset-react babel-plugin-flow-react-proptypes` and edit your `.babelrc` file like so: ```json { @@ -209,6 +209,9 @@ Since we use the JSX syntax here, we have to tell Babel that it needs to transfo "env", "flow", "react" + ], + "plugins": [ + "flow-react-proptypes" ] } ``` diff --git a/tutorial/05-redux-immutable-fetch.md b/tutorial/05-redux-immutable-fetch.md index d721416c..ac350670 100644 --- a/tutorial/05-redux-immutable-fetch.md +++ b/tutorial/05-redux-immutable-fetch.md @@ -111,7 +111,7 @@ In this section we are going to create *Components* and *Containers*. ```js // @flow -import React, { PropTypes } from 'react' +import React from 'react' type Props = { label: string, @@ -121,11 +121,6 @@ type Props = { const Button = ({ label, handleClick }: Props) => -Button.propTypes = { - label: PropTypes.string.isRequired, - handleClick: PropTypes.func.isRequired, -} - export default Button ``` @@ -136,7 +131,7 @@ export default Button ```js // @flow -import React, { PropTypes } from 'react' +import React from 'react' type Props = { message: string, @@ -145,10 +140,6 @@ type Props = { const Message = ({ message }: Props) =>

{message}

-Message.propTypes = { - message: PropTypes.string.isRequired, -} - export default Message ``` From 03c0239e6e412cfab094a1de5cfc4b9e45ab29ec Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Wed, 15 Mar 2017 10:48:17 +0800 Subject: [PATCH 22/29] Add eslint-plugin-compat --- .../02-babel-es6-eslint-flow-jest-husky.md | 36 +++++++++++++++++-- tutorial/05-redux-immutable-fetch.md | 10 ++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/tutorial/02-babel-es6-eslint-flow-jest-husky.md b/tutorial/02-babel-es6-eslint-flow-jest-husky.md index 4f7377a3..0ba4f049 100644 --- a/tutorial/02-babel-es6-eslint-flow-jest-husky.md +++ b/tutorial/02-babel-es6-eslint-flow-jest-husky.md @@ -152,6 +152,36 @@ I recommend reading the [ESLint documentation about semicolons](http://eslint.or I am aware that some of you will want to keep using semicolons, which will make the code provided in this tutorial inconvenient. If you are using this tutorial just for learning, I'm sure it will remain bearable to learn without semicolons, until going back to using them on your real projects. If you want to use the code provided in this tutorial as a boilerplate though, it will require a bit of rewriting, which should be pretty quick with ESLint set to enforce semicolons to guide you through the process. I apologize if you're in such case. +### Compat + +[Compat](https://github.com/amilajack/eslint-plugin-compat) is a neat ESLint plugin that warns you if you use some JavaScript APIs that are not available in the browsers you need to support. It uses [Browserslist](https://github.com/ai/browserslist), which relies on [Can I Use](http://caniuse.com/). + +- Run `yarn add --dev eslint-plugin-compat` + +- Add the following to your `package.json`, to indicate that we want to support browsers that have more than 1% market share: + +```json +"browserslist": ["> 1%"], +``` + +- Edit your `.eslintrc.json` file like so: + +```json +{ + "extends": "airbnb", + "plugins": [ + "compat" + ], + "rules": { + "semi": [2, "never"], + "no-unexpected-multiline": 2, + "compat/compat": 2 + } +} +``` + +You can try the plugin by using `navigator.serviceWorker` or `fetch` in your code for instance, which should raise an ESLint warning. + ### ESLint in your editor This chapter set you up with ESLint in the terminal, which is great for catching errors at build time / before pushing, but you also probably want it integrated to your IDE for immediate feedback. Do NOT use your IDE's native ES6 linting. Configure it so the binary it uses for linting is the one in your `node_modules` folder instead. This way it can use all of your project's config, the Airbnb preset, etc. Otherwise you will just get some generic ES6 linting. @@ -186,11 +216,13 @@ Right now, our JavaScript code is valid ES6 code. Flow can analyze plain JavaScr "plugin:flowtype/recommended" ], "plugins": [ - "flowtype" + "flowtype", + "compat" ], "rules": { "semi": [2, "never"], - "no-unexpected-multiline": 2 + "no-unexpected-multiline": 2, + "compat/compat": 2 } } ``` diff --git a/tutorial/05-redux-immutable-fetch.md b/tutorial/05-redux-immutable-fetch.md index ac350670..92fc67b6 100644 --- a/tutorial/05-redux-immutable-fetch.md +++ b/tutorial/05-redux-immutable-fetch.md @@ -361,6 +361,16 @@ We are going to use `fetch` to make calls to the server from the client. `fetch` - Run `yarn add isomorphic-fetch` +Since we're using `eslint-plugin-compat`, we need to indicate that we are using a polyfill for `fetch` to not get warnings from using it. + +- Add the following to your `.eslintrc.json` file: + +```json +"settings": { + "polyfills": ["fetch"] +}, +``` + ### 3 asynchronous actions `sayHelloAsync` is not going to be a regular action. Asynchronous actions are usually split into 3 actions, which trigger 3 different states: a *request* action (or "loading"), a *success* action, and a *failure* action. From 78efb9904f5eb9b4839068e532f4c8a3c188984e Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Wed, 15 Mar 2017 11:00:14 +0800 Subject: [PATCH 23/29] Bump version to 2.4.5 --- package.json | 4 +- yarn.lock | 1157 +------------------------------------------------- 2 files changed, 12 insertions(+), 1149 deletions(-) diff --git a/package.json b/package.json index 31cfdff2..1571271a 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "js-stack-from-scratch", - "version": "2.4.4", + "version": "2.4.5", "description": "JavaScript Stack from Scratch - Step-by-step tutorial to build a modern JavaScript stack", "scripts": { "test": "node mdlint.js" }, "devDependencies": { "glob": "^7.1.1", - "markdownlint": "^0.3.0" + "markdownlint": "^0.4.0" }, "repository": "verekia/js-stack-from-scratch", "author": "Jonathan Verrecchia - @verekia", diff --git a/yarn.lock b/yarn.lock index 8889ff60..5b0993cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,138 +2,16 @@ # yarn lockfile v1 -abbrev@1: - version "1.0.9" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" - -amp-message@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/amp-message/-/amp-message-0.1.2.tgz#a78f1c98995087ad36192a41298e4db49e3dfc45" - dependencies: - amp "0.3.1" - -amp@0.3.1, amp@~0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/amp/-/amp-0.3.1.tgz#6adf8d58a74f361e82c1fa8d389c079e139fc47d" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - -anymatch@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507" - dependencies: - arrify "^1.0.0" - micromatch "^2.1.5" - -aproba@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.0.4.tgz#2713680775e7614c8ba186c065d4e2e52d1072c0" - -are-we-there-yet@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz#80e470e95a084794fe1899262c5667c6e88de1b3" - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.0 || ^1.1.13" - argparse@^1.0.7: version "1.0.9" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" dependencies: sprintf-js "~1.0.2" -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - dependencies: - arr-flatten "^1.0.1" - -arr-flatten@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.1.tgz#e5ffe54d45e19f32f216e91eb99c8ce892bb604b" - -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - -arrify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - -asn1@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" - -assert-plus@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" - -assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - -async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - -async-listener@^0.6.0: - version "0.6.3" - resolved "https://registry.yarnpkg.com/async-listener/-/async-listener-0.6.3.tgz#1f6521501b9d1c4e6c7a13d404f756b0900371b8" - dependencies: - shimmer "1.0.0" - -async@1.5, async@^1.5: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - -aws-sign2@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" - -aws4@^1.2.1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.5.0.tgz#0a29ffb79c31c9e712eeb087e8e7a64b4a56d755" - balanced-match@^0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" -bcrypt-pbkdf@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" - dependencies: - tweetnacl "^0.14.3" - -binary-extensions@^1.0.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774" - -blessed@^0.1.81: - version "0.1.81" - resolved "https://registry.yarnpkg.com/blessed/-/blessed-0.1.81.tgz#f962d687ec2c369570ae71af843256e6d0ca1129" - -block-stream@*: - version "0.0.9" - resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" - dependencies: - inherits "~2.0.0" - -boom@2.x.x: - version "2.10.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" - dependencies: - hoek "2.x.x" - brace-expansion@^1.0.0: version "1.1.6" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" @@ -141,312 +19,19 @@ brace-expansion@^1.0.0: balanced-match "^0.4.1" concat-map "0.0.1" -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - -buffer-shims@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" - -caseless@~0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" - -chalk@^1.1, chalk@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chokidar@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2" - dependencies: - anymatch "^1.3.0" - async-each "^1.0.0" - glob-parent "^2.0.0" - inherits "^2.0.1" - is-binary-path "^1.0.0" - is-glob "^2.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.0.0" - optionalDependencies: - fsevents "^1.0.0" - -cli-table@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" - dependencies: - colors "1.0.3" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - -colors@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" - -combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" - dependencies: - delayed-stream "~1.0.0" - -commander@^2.9, commander@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" - dependencies: - graceful-readlink ">= 1.0.0" - concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - -continuation-local-storage@^3.1.4: - version "3.2.0" - resolved "https://registry.yarnpkg.com/continuation-local-storage/-/continuation-local-storage-3.2.0.tgz#e19fc36b597090a5d4e4a3b2ea3ebc5e29694a24" - dependencies: - async-listener "^0.6.0" - emitter-listener "^1.0.1" - -core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - -cron@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/cron/-/cron-1.2.1.tgz#3a86c09b41b8f261ac863a7cc85ea4735857eab2" - dependencies: - moment-timezone "^0.5.x" - -cryptiles@2.x.x: - version "2.0.5" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" - dependencies: - boom "2.x.x" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - dependencies: - assert-plus "^1.0.0" - -debug@*, debug@^2.2.0, debug@^2.3.2, debug@^2.6: - version "2.6.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.0.tgz#bc596bcabe7617f11d9fa15361eded5608b8499b" - dependencies: - ms "0.7.2" - -debug@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" - dependencies: - ms "0.7.1" - -deep-extend@~0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - -ecc-jsbn@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" - dependencies: - jsbn "~0.1.0" - -emitter-listener@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/emitter-listener/-/emitter-listener-1.0.1.tgz#b2499ea6e58230a52c268d5df261eecd9f10fe97" - dependencies: - shimmer "1.0.0" - entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" -escape-regexp@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/escape-regexp/-/escape-regexp-0.0.1.tgz#f44bda12d45bbdf9cb7f862ee7e4827b3dd32254" - -escape-string-regexp@^1.0.2: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - -eventemitter2@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-1.0.5.tgz#f983610517b1737c0b9dc643beca93893c04df18" - -eventemitter2@~0.4.14: - version "0.4.14" - resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab" - -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - dependencies: - is-posix-bracket "^0.1.0" - -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - dependencies: - fill-range "^2.1.0" - -extend@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4" - -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - dependencies: - is-extglob "^1.0.0" - -extsprintf@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" - -fclone@1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fclone/-/fclone-1.0.10.tgz#f7ad6ffa01c82488b16b741cdc04fad03405c64b" - -fclone@1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/fclone/-/fclone-1.0.8.tgz#a0d4a73d983249978c0e0671a161520b996467eb" - -filename-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775" - -fill-range@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^1.1.3" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - -for-in@^0.1.5: - version "0.1.6" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.6.tgz#c9f96e89bfad18a545af5ec3ed352a1d9e5b4dc8" - -for-own@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.4.tgz#0149b41a39088c7515f51ebe1c1386d45f935072" - dependencies: - for-in "^0.1.5" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - -form-data@~2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.2.tgz#89c3534008b97eada4cbb157d58f6f5df025eae4" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" -fsevents@^1.0.0: - version "1.0.17" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.0.17.tgz#8537f3f12272678765b4fd6528c0f1f66f8f4558" - dependencies: - nan "^2.3.0" - node-pre-gyp "^0.6.29" - -fstream-ignore@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" - dependencies: - fstream "^1.0.0" - inherits "2" - minimatch "^3.0.0" - -fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.10.tgz#604e8a92fe26ffd9f6fae30399d4984e1ab22822" - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" - -gauge@~2.7.1: - version "2.7.2" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.2.tgz#15cecc31b02d05345a5d6b0e171cdb3ad2307774" - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - supports-color "^0.2.0" - wide-align "^1.1.0" - -generate-function@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" - -generate-object-property@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" - dependencies: - is-property "^1.0.0" - -getpass@^0.1.1: - version "0.1.6" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6" - dependencies: - assert-plus "^1.0.0" - -"gkt@https://tgz.pm2.io/gkt-1.0.0.tgz": - version "1.0.0" - resolved "https://tgz.pm2.io/gkt-1.0.0.tgz#405502b007f319c3f47175c4474527300f2ab5ad" - -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - dependencies: - is-glob "^2.0.0" - -glob@^7.0.0, glob@^7.0.5, glob@^7.1.1: +glob@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" dependencies: @@ -457,54 +42,6 @@ glob@^7.0.0, glob@^7.0.5, glob@^7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" -graceful-fs@^4.1.2: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - -"graceful-readlink@>= 1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" - -har-validator@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" - dependencies: - chalk "^1.1.1" - commander "^2.9.0" - is-my-json-valid "^2.12.4" - pinkie-promise "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - dependencies: - ansi-regex "^2.0.0" - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - -hawk@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" - dependencies: - boom "2.x.x" - cryptiles "2.x.x" - hoek "2.x.x" - sntp "1.x.x" - -hoek@2.x.x: - version "2.16.3" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" - -http-signature@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" - dependencies: - assert-plus "^0.2.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -512,160 +49,19 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1: +inherits@2: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" -ini@~1.3.0: - version "1.3.4" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" - -interpret@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c" - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - dependencies: - binary-extensions "^1.0.0" - -is-buffer@^1.0.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b" - -is-dotfile@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - dependencies: - is-primitive "^2.0.0" - -is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - dependencies: - number-is-nan "^1.0.0" - -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - dependencies: - is-extglob "^1.0.0" - -is-my-json-valid@^2.12.4: - version "2.15.0" - resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz#936edda3ca3c211fd98f3b2d3e08da43f7b2915b" - dependencies: - generate-function "^2.0.0" - generate-object-property "^1.1.0" - jsonpointer "^4.0.0" - xtend "^4.0.0" - -is-number@^2.0.2, is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - dependencies: - kind-of "^3.0.2" - -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - -is-property@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - -isarray@1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - dependencies: - isarray "1.0.0" - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - -jodid25519@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" - dependencies: - jsbn "~0.1.0" - -jsbn@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.0.tgz#650987da0dd74f4ebf5a11377a2aa2d273e97dfd" - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - -json-stringify-safe@^5.0, json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - -jsonpointer@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" - -jsprim@^1.2.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.3.1.tgz#2a7256f70412a29ee3670aaca625994c4dcff252" - dependencies: - extsprintf "1.0.2" - json-schema "0.2.3" - verror "1.3.6" - -kind-of@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47" - dependencies: - is-buffer "^1.0.2" - -lazy@~1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/lazy/-/lazy-1.0.11.tgz#daa068206282542c088288e975c297c1ae77b690" - linkify-it@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.0.3.tgz#d94a4648f9b1c179d64fa97291268bdb6ce9434f" dependencies: uc.micro "^1.0.1" -lodash.findindex@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.findindex/-/lodash.findindex-4.6.0.tgz#a3245dee61fb9b6e0624b535125624bb69c11106" - -lodash.isequal@^4.0.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" - -markdown-it@^8.0.1: - version "8.2.2" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.2.2.tgz#e39593d976f9c4b7ee7f338a3a1e9e10c3db4e36" +markdown-it@^8.3.0: + version "8.3.1" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.3.1.tgz#2f4b622948ccdc193d66f3ca2d43125ac4ac7323" dependencies: argparse "^1.0.7" entities "~1.1.1" @@ -673,573 +69,40 @@ markdown-it@^8.0.1: mdurl "^1.0.1" uc.micro "^1.0.3" -markdownlint@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.3.1.tgz#8bc5ad5bad8a24b3fcfa5aa5cd1ceb8e063c49c6" +markdownlint@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.4.0.tgz#5be8a342c4ab4d5c6cfe8702db30c63bbed01589" dependencies: - markdown-it "^8.0.1" + markdown-it "^8.3.0" mdurl@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" -methods@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - -micromatch@^2.1.5: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - -mime-db@~1.26.0: - version "1.26.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.26.0.tgz#eaffcd0e4fc6935cf8134da246e2e6c35305adff" - -mime-types@^2.1.12, mime-types@~2.1.7: - version "2.1.14" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.14.tgz#f7ef7d97583fcaf3b7d282b6f8b5679dab1e94ee" - dependencies: - mime-db "~1.26.0" - -minimatch@^3.0.0, minimatch@^3.0.2: +minimatch@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" dependencies: brace-expansion "^1.0.0" -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - -minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - -mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@~0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - dependencies: - minimist "0.0.8" - -moment-timezone@^0.5.x: - version "0.5.11" - resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.11.tgz#9b76c03d8ef514c7e4249a7bbce649eed39ef29f" - dependencies: - moment ">= 2.6.0" - -"moment@>= 2.6.0", moment@^2.15: - version "2.17.1" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.17.1.tgz#fed9506063f36b10f066c8b59a144d7faebe1d82" - -ms@0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" - -ms@0.7.2: - version "0.7.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" - -nan@^2.3.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.5.1.tgz#d5b01691253326a97a2bbee9e61c55d8d60351e2" - -node-pre-gyp@^0.6.29: - version "0.6.33" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.33.tgz#640ac55198f6a925972e0c16c4ac26a034d5ecc9" - dependencies: - mkdirp "~0.5.1" - nopt "~3.0.6" - npmlog "^4.0.1" - rc "~1.1.6" - request "^2.79.0" - rimraf "~2.5.4" - semver "~5.3.0" - tar "~2.2.1" - tar-pack "~3.3.0" - -nopt@~3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - dependencies: - abbrev "1" - -normalize-path@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" - -npmlog@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f" - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.1" - set-blocking "~2.0.0" - -nssocket@0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/nssocket/-/nssocket-0.6.0.tgz#59f96f6ff321566f33c70f7dbeeecdfdc07154fa" - dependencies: - eventemitter2 "~0.4.14" - lazy "~1.0.11" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - -oauth-sign@~0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - -object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: wrappy "1" -once@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" - dependencies: - wrappy "1" - -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" -pidusage@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pidusage/-/pidusage-1.1.1.tgz#5a46184da84549cc03c8380e0aeb68248fd214b3" - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - -pm2-axon-rpc@0.4.5: - version "0.4.5" - resolved "https://registry.yarnpkg.com/pm2-axon-rpc/-/pm2-axon-rpc-0.4.5.tgz#fb62e9a53f3e2b7bed1afe16e3b0d1b06fe8ba69" - dependencies: - debug "*" - fclone "1.0.8" - -pm2-axon@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/pm2-axon/-/pm2-axon-3.0.2.tgz#53de1d34edbf266d58f6b1dea2d8244c71ad24b9" - dependencies: - amp "~0.3.1" - amp-message "~0.1.1" - debug "~2.2.0" - escape-regexp "0.0.1" - -pm2-deploy@^0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/pm2-deploy/-/pm2-deploy-0.3.5.tgz#d434bec7bcb1d3c8386a1234af5a3b6794016c1c" - dependencies: - async "^1.5" - tv4 "^1.2" - -pm2@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/pm2/-/pm2-2.4.0.tgz#d570f53118989828d0b8e0b1c0dc4f4be3e9f24a" - dependencies: - async "1.5" - blessed "^0.1.81" - chalk "^1.1" - chokidar "^1.6.1" - cli-table "0.3.1" - commander "^2.9" - cron "1.2.1" - debug "^2.3.2" - eventemitter2 "1.0.5" - fclone "1.0.10" - mkdirp "0.5.1" - moment "^2.15" - nssocket "0.6.0" - pidusage "^1.1.0" - pm2-axon "3.0.2" - pm2-axon-rpc "0.4.5" - pm2-deploy "^0.3.5" - pmx "^1.0.1" - semver "^5.2" - shelljs "0.7.5" - source-map-support "^0.4.6" - sprintf-js "~1.0.2" - vizion "^0.2" - yamljs "0.2.8" - optionalDependencies: - gkt "https://tgz.pm2.io/gkt-1.0.0.tgz" - -pmx@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/pmx/-/pmx-1.0.1.tgz#dd097401947f0f273865dbeabaafa63fb6f40779" - dependencies: - debug "^2.6" - json-stringify-safe "^5.0" - vxx "^1.0.3" - -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - -process-nextick-args@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - -qs@~6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.0.tgz#f403b264f23bc01228c74131b407f18d5ea5d442" - -randomatic@^1.1.3: - version "1.1.6" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" - dependencies: - is-number "^2.0.2" - kind-of "^3.0.2" - -rc@~1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.1.6.tgz#43651b76b6ae53b5c802f1151fa3fc3b059969c9" - dependencies: - deep-extend "~0.4.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~1.0.4" - -"readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.2.tgz#a9e6fec3c7dda85f8bb1b3ba7028604556fc825e" - dependencies: - buffer-shims "^1.0.0" - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - string_decoder "~0.10.x" - util-deprecate "~1.0.1" - -readable-stream@~2.1.4: - version "2.1.5" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" - dependencies: - buffer-shims "^1.0.0" - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - string_decoder "~0.10.x" - util-deprecate "~1.0.1" - -readdirp@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" - dependencies: - graceful-fs "^4.1.2" - minimatch "^3.0.2" - readable-stream "^2.0.2" - set-immediate-shim "^1.0.1" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - dependencies: - resolve "^1.1.6" - -regex-cache@^0.4.2: - version "0.4.3" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" - dependencies: - is-equal-shallow "^0.1.3" - is-primitive "^2.0.0" - -repeat-element@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" - -repeat-string@^1.5.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - -request@^2.79.0: - version "2.79.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - caseless "~0.11.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~2.1.1" - har-validator "~2.0.6" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - oauth-sign "~0.8.1" - qs "~6.3.0" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "~0.4.1" - uuid "^3.0.0" - -resolve@^1.1.6: - version "1.2.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.2.0.tgz#9589c3f2f6149d1417a40becc1663db6ec6bc26c" - -rimraf@2, rimraf@~2.5.1, rimraf@~2.5.4: - version "2.5.4" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" - dependencies: - glob "^7.0.5" - -semver@^5.0.1, semver@^5.2, semver@~5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" - -set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - -shelljs@0.7.5: - version "0.7.5" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.5.tgz#2eef7a50a21e1ccf37da00df767ec69e30ad0675" - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -shimmer@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.0.0.tgz#49c2d71c678360b802be18b278382d1cbb805c39" - -shimmer@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.1.0.tgz#97d7377137ffbbab425522e429fe0aa89a488b35" - -signal-exit@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - -sntp@1.x.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" - dependencies: - hoek "2.x.x" - -source-map-support@^0.4.6: - version "0.4.11" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.11.tgz#647f939978b38535909530885303daf23279f322" - dependencies: - source-map "^0.5.3" - -source-map@^0.5.3: - version "0.5.6" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" -sshpk@^1.7.0: - version "1.10.2" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.10.2.tgz#d5a804ce22695515638e798dbe23273de070a5fa" - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - dashdash "^1.12.0" - getpass "^0.1.1" - optionalDependencies: - bcrypt-pbkdf "^1.0.0" - ecc-jsbn "~0.1.1" - jodid25519 "^1.0.0" - jsbn "~0.1.0" - tweetnacl "~0.14.0" - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - -stringstream@~0.0.4: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - dependencies: - ansi-regex "^2.0.0" - -strip-json-comments@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" - -supports-color@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - -tar-pack@~3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.3.0.tgz#30931816418f55afc4d21775afdd6720cee45dae" - dependencies: - debug "~2.2.0" - fstream "~1.0.10" - fstream-ignore "~1.0.5" - once "~1.3.3" - readable-stream "~2.1.4" - rimraf "~2.5.1" - tar "~2.2.1" - uid-number "~0.0.6" - -tar@~2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" - dependencies: - block-stream "*" - fstream "^1.0.2" - inherits "2" - -tough-cookie@~2.3.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" - dependencies: - punycode "^1.4.1" - -tunnel-agent@~0.4.1: - version "0.4.3" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" - -tv4@^1.2: - version "1.2.7" - resolved "https://registry.yarnpkg.com/tv4/-/tv4-1.2.7.tgz#bd29389afc73ade49ae5f48142b5d544bf68d120" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - uc.micro@^1.0.1, uc.micro@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192" -uid-number@~0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - -uuid@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" - -uuid@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" - -verror@1.3.6: - version "1.3.6" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" - dependencies: - extsprintf "1.0.2" - -vizion@^0.2: - version "0.2.13" - resolved "https://registry.yarnpkg.com/vizion/-/vizion-0.2.13.tgz#1314cdee2b34116f9f5b1248536f95dbfcd6ef5f" - dependencies: - async "1.5" - -vxx@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/vxx/-/vxx-1.0.3.tgz#b16df362e07352948bdb49c869ebe139d11cc264" - dependencies: - continuation-local-storage "^3.1.4" - debug "^2.2.0" - lodash.findindex "^4.4.0" - lodash.isequal "^4.0.0" - methods "^1.1.1" - semver "^5.0.1" - shimmer "^1.0.0" - uuid "^2.0.1" - -wide-align@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.0.tgz#40edde802a71fea1f070da3e62dcda2e7add96ad" - dependencies: - string-width "^1.0.1" - wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - -xtend@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - -yamljs@0.2.8: - version "0.2.8" - resolved "https://registry.yarnpkg.com/yamljs/-/yamljs-0.2.8.tgz#ef23fb006e62f6ae07b406aa2a949561f336ea5c" - dependencies: - argparse "^1.0.7" - glob "^7.0.5" From 8329f6ec4a2500f429923d7d0371029e21a7ee0b Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Wed, 15 Mar 2017 11:08:08 +0800 Subject: [PATCH 24/29] Update CHANGELOG --- CHANGELOG.md | 30 +++++++++++++++++++++--------- how-to-translate.md | 2 +- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6590a81..c6fd6825 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,18 +1,30 @@ # Change Log -## V2 (currently v2.4.3) +## v2.4.5 + +- Add `babel-plugin-flow-react-proptypes`. +- Add `eslint-plugin-compat`. +- Add JSS `composes` example. + +## v2.4.4 + +- Update Immutable to remove the `import * as Immutable from 'immutable'` syntax. +- Declare Flow types outside of function params for React components. +- Improve Webpack `publicPath`. + +## V2, up to v2.4.3 - Gulp is gone, replaced by NPM (Yarn) scripts. - Express has been added, with template strings for static HTML. Gzip compression enabled. - Support for development environment with Nodemon and production environment with PM2. - Minification or sourcemaps depending on the environment via Webpack. -- Webpack Dev Server added, with Hot Module Replacement and `react-hot-loader`. -- Added an asynchronous call example with `redux-thunk`. +- Add Webpack Dev Server, with Hot Module Replacement and `react-hot-loader`. +- Add an asynchronous call example with `redux-thunk`. - Linting / type checking / testing is not launched at every file change anymore, but triggered by Git Hooks via Husky. - Some chapters have been combined to make it easier to maintain the tutorial. -- Replaced Chai and Mocha by Jest. -- Added React-Router, Server-Side rendering, `react-helmet`. -- Renamed all "dog" things and replaced it by "hello" things. It's a Hello World app after all. -- Added Twitter Bootstrap, JSS, and `react-jss` for styling. -- Added a Websocket example with Socket.IO. -- Added optional Heroku, Travis, and Coveralls integrations. +- Replace Chai and Mocha by Jest. +- Add React-Router, Server-Side rendering, `react-helmet`. +- Rename all "dog" things and replaced it by "hello" things. It's a Hello World app after all. +- Add Twitter Bootstrap, JSS, and `react-jss` for styling. +- Add a Websocket example with Socket.IO. +- Add optional Heroku, Travis, and Coveralls integrations. diff --git a/how-to-translate.md b/how-to-translate.md index d2ef5fb1..5ce1c92e 100644 --- a/how-to-translate.md +++ b/how-to-translate.md @@ -35,7 +35,7 @@ Since I want to reward you for your good work as much as possible, you can put a - After your original one-shot translation, if you want to update your repo with the latest change from the main English repo, [sync your fork](https://help.github.com/articles/syncing-a-fork/) with my repo. To make it easy to see what changed since your initial translation, you can use Github's feature to [compare commits](https://help.github.com/articles/comparing-commits-across-time/#comparing-commits). Set the **base** to the last commit from the English repo you used to translate, and compare it to **master**, like so: -https://github.com/verekia/js-stack-from-scratch/compare/9b3852fcdf8f3000e7513abfcb26e0e58b33b230...master +https://github.com/verekia/js-stack-from-scratch/compare/c65dfa65d02c21063d94f0955de90947ba5273ad...master That should give you a easy-to-read diff to see exactly what changed in `README.md` files since your translation! From bf90846fef49b92470d4f34285a93b1a03f4cf49 Mon Sep 17 00:00:00 2001 From: Adam Goldman Date: Sun, 19 Mar 2017 14:15:17 +0800 Subject: [PATCH 25/29] Update 06-react-router-ssr-helmet.md I'm following the tutorial by coding everything by hand from memory, and I didn't know the order was relevant here. Here's 15 minutes I'll never see again ;) --- tutorial/06-react-router-ssr-helmet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial/06-react-router-ssr-helmet.md b/tutorial/06-react-router-ssr-helmet.md index cb215abb..98f6e1e2 100644 --- a/tutorial/06-react-router-ssr-helmet.md +++ b/tutorial/06-react-router-ssr-helmet.md @@ -442,7 +442,7 @@ import Helmet from 'react-helmet' const renderApp = (/* [...] */) => { const appHtml = ReactDOMServer.renderToString(/* [...] */) - const head = Helmet.rewind() + const head = Helmet.rewind() // must come AFTER appHtml! return ( ` From 742e4446136de63cc2d5c6e86173fcdd18d82782 Mon Sep 17 00:00:00 2001 From: Jonathan Verrecchia Date: Mon, 20 Mar 2017 13:19:49 +0800 Subject: [PATCH 26/29] Add note about Helmet.rewind() --- tutorial/06-react-router-ssr-helmet.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorial/06-react-router-ssr-helmet.md b/tutorial/06-react-router-ssr-helmet.md index 98f6e1e2..4eec3550 100644 --- a/tutorial/06-react-router-ssr-helmet.md +++ b/tutorial/06-react-router-ssr-helmet.md @@ -442,7 +442,7 @@ import Helmet from 'react-helmet' const renderApp = (/* [...] */) => { const appHtml = ReactDOMServer.renderToString(/* [...] */) - const head = Helmet.rewind() // must come AFTER appHtml! + const head = Helmet.rewind() return ( ` @@ -458,7 +458,7 @@ const renderApp = (/* [...] */) => { } ``` -React Helmet uses [react-side-effect](https://github.com/gaearon/react-side-effect)'s `rewind` to pull out some data from the rendering of our app, which will soon contain some `` components. Those `` components are where we set the `title` and other `head` details for each page. +React Helmet uses [react-side-effect](https://github.com/gaearon/react-side-effect)'s `rewind` to pull out some data from the rendering of our app, which will soon contain some `` components. Those `` components are where we set the `title` and other `head` details for each page. Note that `Helmet.rewind()` *must* come after `ReactDOMServer.renderToString()`. - Edit `src/shared/app.jsx` like so: From 02e4136ad4d6392ce05f2b7bb64479c84969b2e6 Mon Sep 17 00:00:00 2001 From: "Marco A. Rojas" Date: Sat, 25 Mar 2017 05:31:27 -0600 Subject: [PATCH 27/29] =?UTF-8?q?Correci=C3=B3n=20de=20errores=20de=20tipa?= =?UTF-8?q?do=20y=20gram=C3=A1ticales?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Ajustes en la traducci贸n para una lectura mas natural - Se evita mezclar may煤sculas y min煤sculas - Escrito en segunda persona como la publicaci贸n original --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1b2397da..15950eb8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Stack JavaScript desde Cero +# Stack JavaScript desde cero [![Build Status](https://travis-ci.org/verekia/js-stack-from-scratch.svg?branch=master)](https://travis-ci.org/verekia/js-stack-from-scratch) [![Release](https://img.shields.io/github/release/verekia/js-stack-from-scratch.svg?style=flat-square)](https://github.com/verekia/js-stack-from-scratch/releases) @@ -18,21 +18,21 @@ Bienvenido a mi tutorial (@verekia) sobre el stack javascript: ** Stack Javascript desde Cero**. -> 馃帀 **Esta es la V2 del tutorial, con grandes cambios desde la edici贸n de 2016. Puede ver la [Lista de Cambios](/CHANGELOG.md)!** +> 馃帀 **Esta es la V2 del tutorial, con grandes cambios desde la edici贸n de 2016. Puedes ver la [Lista de Cambios](/CHANGELOG.md)!** -Esta es una gu铆a orientada a ensamblar un stack JavaScript. Requiere algunos conocimientos de programaci贸n general, y b谩sicos de JavaScript. **Se centra en herramientas que abordaremos juntos** y ofreciendole el **ejemplo m谩s simple posible** para cada herramientas. Puede ver este tutorial como *una manera de escribir su propia boilerplate desde cero*. Debido a que, el objetivo de este tutorial es ensamblar varias herramientas, no voy a entrar en detalles sobre como cada una trabaja individualmente. Consulte su documentaci贸n o encuentre otros tutoriales si desea adquirir un conocimiento m谩s profundo en ellos. +Esta es una gu铆a orientada directamente a ensamblar un stack JavaScript. Requieres de algunos conocimientos generales de programaci贸n, y conceptos b谩sicos de JavaScript. **Se centra en acoplar varias herramientas** y ofrecerle el **ejemplo m谩s simple posible** para cada herramienta. Puedes ver este tutorial como *una manera de escribir tu propia boilerplate desde cero*. Debido a que el objetivo de este tutorial es ensamblar varias herramientas, no voy a entrar en detalles sobre como funciona cada una individualmente. Consulta la documentaci贸n o encuentra otros tutoriales si deseas adquirir un conocimiento m谩s profundo en estas. -No necesita usar este stack entero si va a construir una simple p谩gina web con una pocas interacciones de JS interactions obviamente (una combinaci贸n de Browserify/Webpack + Babel + jQuery es suficiente para poder escribir c贸digo ES6 en archivos diferentes), pero si quieres crear una aplicaci贸n web que sea escalable, y necesitas ayuda para configurar las cosas, este tutorial ser谩 muy bueno para ti. +No necesitas usar este stack entero si vas a construir una simple p谩gina web con pocas interacciones de JS (una combinaci贸n de Browserify/Webpack + Babel + jQuery es suficiente para poder escribir c贸digo ES6 en archivos diferentes), pero si quieres crear una aplicaci贸n web que sea escalable, y necesitas ayuda para configurar las cosas, este tutorial ser谩 muy bueno para ti. -Una gran parte de lo descrito en este tutorial usa React. Si estas comenzando y quieres aprender React, [create-react-app](https://github.com/facebookincubator/create-react-app) le permitir谩 levantar y correr r谩pidamente un entorno de React ya preconfigurado. Recomiendo este enfoque para quien se este incorporando a un equipo que este usando React y necesite ponerse al d铆a con un ambiente de pruebas. En este tutorial no lo usaremos, porque quiero que entienda lo que esta sucede debajo de todo. +Una gran parte de lo descrito en este tutorial usa React. Si estas comenzando y s贸lo quieres aprender React, [create-react-app](https://github.com/facebookincubator/create-react-app) te permitir谩 levantar y ejecutar r谩pidamente un entorno de React ya preconfigurado. Recomiendo este enfoque para quien se est茅 incorporando a un equipo que utilice React y necesite ponerse al d铆a con un ambiente de pruebas. En este tutorial no utilizaremos React preconfigurado, porque quiero que entiendas todo lo que hay detr谩s de su funcionamiento. -Los c贸digos de ejemplos estan disponibles en cada cap铆tulo, puedes correlos todos usando `yarn && yarn start`. Sin embargo, recomiendo que escriba todo desde cero siguiendo las **instrucciones paso a paso**. +Los c贸digos de los ejemplos estan disponibles en cada cap铆tulo, puedes ejecutarlos usando `yarn && yarn start`. Sin embargo, te recomiendo que escribas todo desde cero siguiendo las **instrucciones paso a paso**. -El c贸digo final esta disponible en el [repositorio JS-Stack-Boilerplate](https://github.com/verekia/js-stack-boilerplate), en el [releases](https://github.com/verekia/js-stack-from-scratch/releases). As铆 como tambi茅n un [demo en vivo](https://js-stack.herokuapp.com/). +El c贸digo final esta disponible en el [repositorio JS-Stack-Boilerplate](https://github.com/verekia/js-stack-boilerplate), en [releases](https://github.com/verekia/js-stack-from-scratch/releases). As铆 como tambi茅n un [demo en vivo](https://js-stack.herokuapp.com/). Funciona en Linux, macOS, y Windows. -## Tabla de Contenidos +## Tabla de contenidos [01 - Node, Yarn, `package.json`](/tutorial/01-node-yarn-package-json.md#readme) @@ -52,9 +52,9 @@ Funciona en Linux, macOS, y Windows. [09 - Travis, Coveralls, Heroku](/tutorial/09-travis-coveralls-heroku.md#readme) -## Proximamente +## Pr贸ximamente -Configurando tu editor (Atom), MongoDB, Progressive Web App. +Configura tu editor (Atom), MongoDB, Progressive Web App. ## Traducciones From b3c4d04e097cff092c69ea2189573dfec0069957 Mon Sep 17 00:00:00 2001 From: "Marco A. Rojas" Date: Sat, 25 Mar 2017 06:32:27 -0600 Subject: [PATCH 28/29] =?UTF-8?q?Corregidos=20errores=20de=20tipado=20-=20?= =?UTF-8?q?Uso=20de=20segunda=20persona=20-=20Links=20a=20sitios=20en=20es?= =?UTF-8?q?pa=C3=B1ol(es)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tutorial/01-node-yarn-package-json.md | 69 +++++++++++++-------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/tutorial/01-node-yarn-package-json.md b/tutorial/01-node-yarn-package-json.md index 0beb7ea7..ab4d3375 100644 --- a/tutorial/01-node-yarn-package-json.md +++ b/tutorial/01-node-yarn-package-json.md @@ -2,38 +2,38 @@ El c贸digo para este cap铆tulo esta disponible [aqu铆](https://github.com/verekia/js-stack-walkthrough/tree/master/01-node-yarn-package-json). -en esta secci贸n configuraremos Node, Yarn, un archivo `package.json` b谩sico y probaremos un paquete. +En esta secci贸n configuraremos Node, Yarn, un archivo `package.json` b谩sico y probaremos un paquete. ## Node -> 馃挕 **[Node.js](https://nodejs.org/)** es un entorno de ejecuci贸n Javascript. Es mayormente usado para desarrollo Back-End, pero tambi茅n para scripting en general. En el contexto de desarrollo Front-End, puede ser usado para realizar una gran cantidad de tareas como linting, pruebas y ensamblamiento de archivos. +> 馃挕 **[Node.js](https://nodejs.org/es/)** es un entorno de ejecuci贸n para Javascript. Es mayormente usado para desarrollo Back-End, pero tambi茅n para scripting en general. En el contexto de desarrollo Front-End, puede ser usado para realizar una gran cantidad de tareas como linting, pruebas y ensamblamiento de archivos. -Usaremos Nodo a lo largo de este tutorial, por tanto va a necesitarlo. Dir铆jase a la [p谩gina de descarga](https://nodejs.org/en/download/current/) para los binarios de **macOS** o **Windows**, o la [p谩gina de instalaci贸n de manejador de paquetes](https://nodejs.org/en/download/package-manager/) para su distribuciones Linux. +Usaremos Node b谩sicamente para todo a lo largo de este tutorial, por tanto vas a necesitarlo. Dir铆gete a la [p谩gina de descargas](https://nodejs.org/es/download/current/) para obtener los binarios para **macOS** o **Windows**, o a la [p谩gina de instalaci贸n mediante manejador de paquetes](https://nodejs.org/es/download/package-manager/) para distribuciones Linux. -Por ejemplo, en **Ubuntu / Debian**, correr铆a el siguiente comando para instalar Node: +Por ejemplo, en **Ubuntu / Debian**, ejecutar铆as los siguientes comandos para instalar Node: ```sh curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash - sudo apt-get install -y nodejs ``` -Si desea cualquier versi贸n de Node > 6.5.0. +Si deseas cualquier versi贸n de Node > 6.5.0. -## NVM +## Herramientas para gestionar distintas versiones de Node -Si Node esta ya instalado, o si desea m谩s flexibilidad, instale NVM ([Node Version Manager](https://github.com/creationix/nvm)), y gracias a NVM instale y use la versi贸n m谩s reciente de Node. +Si necesitas flexibilidad para utilizar m煤ltiples versiones de Node, checa [Node Version Manager](https://github.com/creationix/nvm), o [tj/n](https://github.com/tj/n). ## NPM -NPM es el manejador de paquetes por defecto de Node. El cual se instala automaticametne con Node. Los manejadores de paquetes son usados para instalar y manejar paquetes (modulos del c贸digo que t煤 o alguien m谩s escribi贸). Vamos a usar un mont贸n de paquetes en este tutorial, pero usaremos Yarn, otro manejador de paquetes. +NPM es el manejador de paquetes por defecto de Node. El cual se instala autom谩ticamente con Node. Los manejadores de paquetes son usados para instalar y manejar paquetes (m贸dulos de c贸digo que t煤 o alguien m谩s escribi贸). Vamos a usar un mont贸n de paquetes en este tutorial, pero usaremos Yarn, otro manejador de paquetes. ## Yarn > 馃挕 **[Yarn](https://yarnpkg.com/)** es un manejador de paquetes de Node.js que destaca por ser m谩s r谩pido que NPM, tiene soporte offline y obtiene dependencias [m谩s previsiblemente](https://yarnpkg.com/en/docs/yarn-lock). -Desde su [llegada](https://code.facebook.com/posts/1840075619545360) en Octubre de 2016, ha recivido una r谩pida adopci贸n y en poco tiempo se convirti贸 en el manejador de paquetes por preferencia de la comunidad JavaScript. Si desea en cambio usar NPM puede simplemente reemplazar todos los comandos `yarn add` y `yarn add --dev` de este tutorial por `npm install --save` y `npm install --save-dev`. +Desde su [llegada](https://code.facebook.com/posts/1840075619545360) en Octubre de 2016, se ha adoptado r谩pidamente y en poco tiempo se convirti贸 en el manejador de paquetes preferido en la comunidad JavaScript. Si deseas en cambio usar NPM puedes simplemente reemplazar todos los comandos `yarn add` y `yarn add --dev` de este tutorial, por `npm install --save` y `npm install --save-dev`. -Puede instalar Yarn con las siguientes [instrucciones](https://yarnpkg.com/en/docs/install) para tu Sistema Operativp. Recomiendo usar el **Script de instalaci贸n** desde la tab de *Alternativas* si esta usando macOS o Unix, para [evitar](https://github.com/yarnpkg/yarn/issues/1505) confiar en otros manejadores de paquetes: +Puede instalar Yarn con las siguientes [instrucciones](https://yarnpkg.com/en/docs/install) para tu sistema operativo. Recomiendo usar el **script de instalaci贸n** desde la pesta帽a *Alternatives* si estas usando macOS o Unix, para [evitar](https://github.com/yarnpkg/yarn/issues/1505) confiar en otros manejadores de paquetes: ```sh curl -o- -L https://yarnpkg.com/install.sh | bash @@ -41,13 +41,12 @@ curl -o- -L https://yarnpkg.com/install.sh | bash ## `package.json` -> 馃挕 **[package.json](https://yarnpkg.com/en/docs/package-json)** es el archivo usado para describir y configurar tu proyecto JavaScript. Contiene informaci贸n general (nombre del proyecto, versi贸n, contribuidores, licencia, entre otros), opciones de configuraci贸n para las herramientas que use e incluso una secci贸n para correr *tareas*. +> 馃挕 **[package.json](https://yarnpkg.com/en/docs/package-json)** es el archivo usado para describir y configurar tu proyecto JavaScript. Contiene informaci贸n general (nombre del proyecto, versi贸n, contribuidores, licencia, entre otros), opciones de configuraci贸n para las herramientas que uses e incluso una secci贸n para ejecutar *tareas*. -- Cree una nueva carpeta para trabajar, y entre en ella con `cd`. -- Corra `yarn init` y responda las preguntas (`yarn init -y` para saltarse todas las preguntas), para generar un archivo `package.json` automaticamente. +- Crea un nuevo directorio para trabajar, y entra en este con `cd`. +- Ejecuta `yarn init` y responde las preguntas (`yarn init -y` permite saltarse todas las preguntas), para generar un archivo `package.json` autom谩ticamente. -Aqu铆 puede ver un `package.json` b谩sico que usaremos en este tutorial: -) para tu Sistema Operativp. Recomiendo usar el **Script de instalaci贸n** desde la tab de *Alternativas* si esta usando macOS o Unix, para [evitar](https://github.com/yarnpkg/yarn/issues/1505) confiar en otros manejadores de paquetes: +Aqu铆 puedes ver un `package.json` b谩sico que usaremos en este tutorial: ```json { @@ -61,13 +60,13 @@ Aqu铆 puede ver un `package.json` b谩sico que usaremos en este tutorial: - Crea un archivo `index.js` que contenga `console.log('Hello world')` -馃弫 Corre `node .` en esta carpeta (`index.js` es el archivo que Node buscar谩 por defecto dentro de la carpeta). Deber铆a imprimir "Hello world". +馃弫 Ejecuta `node .` en esta carpeta (`index.js` es el archivo que Node buscar谩 por defecto dentro del directorio). Deber谩 imprimir "Hello world". -**Nota**: ves es emoji de bandera de carrera 馃弫? Lo usar茅 cada vez que llegues a un **punto de control**. Algunas veces vamos a hacer muchos cambios en algunas lineas y su c贸digo no funcionar谩 hasta llegar al siguiente punto de control. +**Nota**: ves este emoji de bandera de carrera 馃弫? Lo usar茅 cada vez que llegues a un **punto de control**. Algunas veces vamos a hacer muchos cambios en algunas lineas y tu c贸digo no funcionar谩 hasta llegar al siguiente punto de control. ## Script `start` -Usar `node .` para ejecutar nuestro programa es ir a muy bajo-nivel. Vamos a usar una script NPM/Yarn en su lugar para disparar la ejecuci贸n del c贸digo. Esto nos brindar谩 una buena abstraci贸n para poder siempre usar `yarn start`, aun cuando nuestro programa se vuelva mas complejo. +Usar `node .` para ejecutar nuestro programa es ir a muy bajo-nivel. Vamos a usar un script NPM/Yarn en su lugar para disparar la ejecuci贸n del c贸digo. Esto nos brindar谩 una buena abstraci贸n para poder usar siempre `yarn start`, aun cuando nuestro programa se vuelva mas complejo. - En `package.json`, agrega un objeto `scripts` de la siguiente forma: @@ -82,11 +81,11 @@ Usar `node .` para ejecutar nuestro programa es ir a muy bajo-nivel. Vamos a usa } ``` -`start` es el nombre que le daemos a la *tarea* que correr nuestro programa. Vamos a crear un mont贸n de diferentes tareas en este objeto `scripts` a lo largo de este tutorial. `start` es tipicamente el nombre que le damos a la tarea por defecto de una aplicaci贸n. Algunas otras tareas estandard son llamadas `stop` y `test`. +`start` es el nombre que le daremos a la *tarea* que ejecutar谩 nuestro programa. Vamos a crear un mont贸n de diferentes tareas en este objeto `scripts` a lo largo de este tutorial. `start` es tipicamente el nombre que le damos a la tarea por defecto de una aplicaci贸n. Algunas otras tareas est谩ndar son `stop` y `test`. -`package.json` debe ser un archivo JSON valido, lo cual significa que no puede tener comillas. Tenga mucho cuidado cuando edite manualmente tu archivo `package.json`. +`package.json` debe ser un archivo JSON valido, lo cual significa que no puede tener comas finales. Ten mucho cuidado cuando edites manualmente tu archivo `package.json`. -馃弫 Corre `yarn start`. Deber铆a imprimir `Hello world`. +馃弫 Ejecuta `yarn start`. Debe `Hello world`. ## Git y `.gitignore` @@ -99,25 +98,25 @@ Usar `node .` para ejecutar nuestro programa es ir a muy bajo-nivel. Vamos a usa /*.log ``` -Los archivos `.DS_Store` son auto-generados en macOS que nunca deberias tener dentro de tu repositorio. +Los archivos `.DS_Store` son auto-generados en macOS, que nunca deberias tener dentro de tu repositorio. `npm-debug.log` y `yarn-error.log` son archivos que son creados cuando tu manejador de paquetes encuentra un error, no queremos que esten versionados en nuestro repositorio. -## Instalando y udando un paquete +## Instalando y usando un paquete -En esta secci贸n intalaremos y usaremos un paquete. Un "paquete" es simplemente una pieza de c贸digo que alguien mas escribi贸 y puede ser usado en tu propio c贸digo. Pueden ser cualquier cosa. Aqu铆, vamos a probar un paquete que le ayudar谩 a manipular los colores por ejemplo. +En esta secci贸n instalaremos y usaremos un paquete. Un "paquete" es simplemente una pieza de c贸digo que alguien mas escribi贸 y puede ser usado en tu propio c贸digo. Puede ser cualquier cosa. Aqu铆 por ejemplo, vamos a probar un paquete que te ayudar谩 a manipular colores. - Instala el paquete hecho por la comunidad llamado `color` usando `yarn add color` -Abre `package.json` y veras como Yarn automaticamente a帽adi贸 `color` en `dependencies`. +Abre `package.json` y veras como Yarn automaticamente a帽adi贸 `color` en `dependencies`. Una carpeta `node_modules` ha sido creada para almacenar los paquetes. - Agrega `node_modules/` a tu `.gitignore` -Tambi茅n notar谩 que un archivo `yarn.lock` fue generado por Yarn. Deber铆as agregar de este archivo a tu repositorio, con esto te aseguras que todo en tu equipo usen la misma versi贸n que tus paquetes. Si estas usando NPM en vez de Yarn, el equivalente de este archivo es el *shrinkwrap*. +Tambi茅n notar谩s que un archivo `yarn.lock` fue generado por Yarn. Deberas agregar este archivo a tu repositorio, con esto te aseguras que todo en tu equipo usen la misma versi贸n que tus paquetes. Si estas usando NPM en vez de Yarn, el equivalente de este archivo es el *shrinkwrap*. -- Escribe los siguiente en tu archivo `index.js`: +- Escribe lo siguiente en tu archivo `index.js`: ```js const color = require('color') @@ -127,22 +126,22 @@ const redHexa = color({ r: 255, g: 0, b: 0 }).hex() console.log(redHexa) ``` -馃弫 Correo `yarn start`. Deber铆a imprimir `#FF0000`. +馃弫 Ejecuta `yarn start`. Deber谩 imprimir `#FF0000`. -隆Felicitaciones, instal贸 y uso un paquete! +隆Felicitaciones, instalaste y usaste un paquete! -`color` es usado en esta secci贸n para ense帽arle como usar un simple paquete. No lo necesitaremos mas, as铆 que puedes desintalarlo: +`color` es usado en esta secci贸n para ense帽arte como usar un simple paquete. No lo necesitaremos mas, as铆 que puedes desintalarlo: -- Usa `yarn remove color` +- Ejecuta `yarn remove color` ## Dos tipos de dependecias -Hay dos tipo sde dependencias de paquetes, `"dependencies"` y `"devDependencies"`: +Hay dos tipos de dependencias de paquetes, `"dependencies"` y `"devDependencies"`: -**Dependencias** son librerias que necesita tu aplicaci贸n para funcionar (React, Redux, Lodash, jQuery, etc). Las instala usando `yarn add [paquete]`. +**Dependencias** son librerias que necesita tu aplicaci贸n para funcionar (React, Redux, Lodash, jQuery, etc). Se instalan usando `yarn add [paquete]`. -**Dependencias De Desarrollo** son libreias usadas durante el desarrollo o para contruir tu aplicaci贸n (Webpack, SASS, linters, frameworks de pruebas, etc). La instala usando `yarn add --dev [paquete]`. +**Dependencias De Desarrollo** son librer铆as usadas durante el desarrollo o contruci贸n de tu aplicaci贸n (Webpack, SASS, linters, frameworks de pruebas, etc). Se instalan usando `yarn add --dev [paquete]`. -Siguiente Secci贸n: [02 - Babel, ES6, ESLint, Flow, Jest, Husky](02-babel-es6-eslint-flow-jest-husky.md#readme) +Siguiente secci贸n: [02 - Babel, ES6, ESLint, Flow, Jest, Husky](02-babel-es6-eslint-flow-jest-husky.md#readme) Volver a la [tabla de contenidos](https://github.com/JMEspiz/js-stack-from-scratch#table-of-contents). From 123bfc97b5de593a4f5c04e2fc42fddd214e09a2 Mon Sep 17 00:00:00 2001 From: "Marco A. Rojas" Date: Sat, 25 Mar 2017 07:14:07 -0600 Subject: [PATCH 29/29] =?UTF-8?q?Traducci=C3=B3n=20actualizada=20-=20Compa?= =?UTF-8?q?t=20-=20Comentario=20en=20Git=20Hooks=20con=20Husky?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tutorial/02-babel-es6-eslint-flow-jest-husky.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tutorial/02-babel-es6-eslint-flow-jest-husky.md b/tutorial/02-babel-es6-eslint-flow-jest-husky.md index a5e03ec5..77aea17f 100644 --- a/tutorial/02-babel-es6-eslint-flow-jest-husky.md +++ b/tutorial/02-babel-es6-eslint-flow-jest-husky.md @@ -154,17 +154,17 @@ Soy consciente de que algunos de ustedes querr谩n seguir utilizando puntos y com ### Compat -[Compat](https://github.com/amilajack/eslint-plugin-compat) is a neat ESLint plugin that warns you if you use some JavaScript APIs that are not available in the browsers you need to support. It uses [Browserslist](https://github.com/ai/browserslist), which relies on [Can I Use](http://caniuse.com/). +[Compat](https://github.com/amilajack/eslint-plugin-compat) es un plugin de ESLint que te advierte si estas utilizando algunas APIs de Javascript que no est谩n disponibles en los navegadores que quieres soportar. Utiliza [Browserslist](https://github.com/ai/browserslist), que est谩 basado en [Can I Use](http://caniuse.com/). -- Run `yarn add --dev eslint-plugin-compat` +- Ejecuta `yarn add --dev eslint-plugin-compat` -- Add the following to your `package.json`, to indicate that we want to support browsers that have more than 1% market share: +- Agrega lo siguiente a tu `package.json`, para indicar que queremos dar soporte a navegadores con mas del 1% de la cuota de mercado. ```json "browserslist": ["> 1%"], ``` -- Edit your `.eslintrc.json` file like so: +- Edita tu archivvvvo `.eslintrc.json`: ```json { @@ -180,7 +180,7 @@ Soy consciente de que algunos de ustedes querr谩n seguir utilizando puntos y com } ``` -You can try the plugin by using `navigator.serviceWorker` or `fetch` in your code for instance, which should raise an ESLint warning. +Puedes probar el plugin utilizando `navigator.serviceWorker` o `fetch` en tu c贸digo, lo que deber谩 generar una advertencia en ESLint. ### ESLint en tu Editor @@ -355,7 +355,7 @@ Todo lo que tenemos que hacer es crear dos nuevas tareas en `scripts`,` precommi 馃弫 Si ahora intenta hacer commit o push de su c贸digo, deber铆a automaticamente correr la tarea `test`. -If it does not work, it is possible that `yarn add --dev husky` did not install the Git Hooks properly. I never encountered this issue but it happens for some people. If that's your case, run `yarn add --dev husky --force`, and maybe post a note describing your situation in [this issue](https://github.com/typicode/husky/issues/84). +Si esto no funciona, es posible que `yarn add --dev husky` no haya instalado los Git Hooks apropiadamente. Nunca he tenido este problema, pero a algunos les sucede. Si es tu caso, ejecuta `yarn add --dev husky --force`, y si te es posible escribe un comentario para describir tu situaci贸n [en este issue](https://github.com/typicode/husky/issues/84). **Nota**: Si est谩 haciendo push justo despu茅s de un commit, puede utilizar `git push --no-verify` para evitar ejecutar todas las pruebas de nuevo.