diff --git a/.travis.yml b/.travis.yml index 24e4651bcd3a3..ae0c7ec16721e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,40 @@ -language: node_js -node_js: - - "6" - - "8" +sudo: required + +services: + - docker + +os: + - linux -os: [linux] dist: trusty sudo: required -cache: - yarn: true -before_install: - - curl -o- -L https://yarnpkg.com/install.sh | bash - - export PATH=$HOME/.yarn/bin:$PATH +jobs: + include: + - stage: build and test + if: type = pull_request + language: node_js + node_js: + - '6' + - '8' + cache: + yarn: true + before_install: + - curl -o- -L https://yarnpkg.com/install.sh | bash + - export PATH=$HOME/.yarn/bin:$PATH + install: + - yarn run bootstrap + script: + - yarn test + + - stage: www graphql docker image build and push + if: (NOT type = pull_request) AND branch = master + env: + - DOCKER_USER=mikeallanson + - secure: J8daWiar248dPWwrutZd83CeSif/+rMjB9hSOjq0pQDNj7QcOKjUwLsv6yMDJAcQCAAyobwRQTNYANGXmvQsi5ZppZe/P/enDPD/ZEPz3XkvxYYbXC7TNKVp8bnvYTWu6qO9ljkMsKGttsqaz+MyTx2MjV9pJhkmw2rfQ5iVn/80bORaCCMDcSB2ud/jLN+AVBFNMDUVEL9RnAXTq+CyQmSLvlvmJNCu9CXnb/Kt+IcbqswTjre/V2lVkzcXEvUYd0F9la3bsGVVQ9vBd3IumSIGnSOxD91DLUOeuh5K7FJxPoqqwM+bCn4zZWtQMOGpPDoYYllVejFHC16g/FBa6uC455OvqeS6fSCRXr9bqDxDLPhn7IyDAuG2jXps++sbd2RA8eXq8IGA4AqtTf4smiIXbOu3p3d2n9ww4Z/NgRpLHYRFcVwjG92okVN4by7n1+kr7wGx+alCkHTMDrLkkeZ0AEJphaxAH+TxP+SvCFY1z/OyNM0YzICrLXjf2w60Xz4wE563yUM8OLFm4GbeM33eQYRErTLADG9JtGDev+L5tS/Vo8+KGkL3creY7f9BgsNyfxbQbv84X7f+vSPlzl6u8V9EuVA80+5hE7artRtM+BxiT5pGM1983+QK2CPv4EptMYRa0EjlVbxyrfVYF22lsAqqgVApZGGneUxB0cQ= # DOCKER_PASS + before_install: + - chmod +x scripts/www-graphql-docker-push.sh + script: + - ./scripts/www-graphql-docker-push.sh -install: - - yarn run bootstrap -script: - - yarn test diff --git a/README.md b/README.md index 1171790fc1954..32db07bb0256f 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,6 @@ Websites built with Gatsby: * [Formidable](https://formidable.com/) * [openFDA](https://open.fda.gov/) ([source](https://github.com/FDA/open.fda.gov)) -* [ReasonML Docs](https://reasonml.github.io/) - ([source](https://github.com/reasonml/reasonml.github.io)) * [Bricolage.io](https://www.bricolage.io/) ([source](https://github.com/KyleAMathews/blog)) * [Hack Club](https://hackclub.com/) @@ -159,6 +157,8 @@ Websites built with Gatsby: * [LaserTime Clinic](https://lasertime.ru) ([source](https://github.com/oleglegun/lasertime)) * [Gatsby Manor - themes for GatsbyJS](https://gatsbymanor.com) * [Darren Britton's Portfolio](https://darrenbritton.com) ([source](https://github.com/darrenbritton/darrenbritton.github.io)) +* [Portfolio / Blog of Preston Richey](https://prestonrichey.com/) ([source](https://github.com/prichey/prestonrichey.com)) +* [Beach Hut Poole](https://www.beachhutpoole.co.uk/) ## Docs diff --git a/docs/blog/2018-02-09-announcing-gatsby-manor-themes-for-gatsbyjs/index.md b/docs/blog/2018-02-09-announcing-gatsby-manor-themes-for-gatsbyjs/index.md index fe9399ae05039..2863b7290ee00 100644 --- a/docs/blog/2018-02-09-announcing-gatsby-manor-themes-for-gatsbyjs/index.md +++ b/docs/blog/2018-02-09-announcing-gatsby-manor-themes-for-gatsbyjs/index.md @@ -6,7 +6,7 @@ author: "Steven Natera" --- I am proud to announce [Gatsby Manor](https://www.gatsbymanor.com/), a gallery -of themes for [Gatsby](https://www.Gatsby.org/). After 5 months of +of themes for Gatsby. After 5 months of development, Gatsby Manor is now in public beta. Check out our [themes](https://www.gatsbymanor.com/themes) then use our [getting started](https://www.gatsbymanor.com/docs/quick-start/getting-started) guide to kickstart your Gatsby project. diff --git a/docs/blog/2018-02-16-bright-future-for-the-web/bright-future.jpg b/docs/blog/2018-02-16-bright-future-for-the-web/bright-future.jpg new file mode 100644 index 0000000000000..83ea089d2c595 Binary files /dev/null and b/docs/blog/2018-02-16-bright-future-for-the-web/bright-future.jpg differ diff --git a/docs/blog/2018-02-16-bright-future-for-the-web/final-product.jpg b/docs/blog/2018-02-16-bright-future-for-the-web/final-product.jpg new file mode 100644 index 0000000000000..83a9ac5ec06e3 Binary files /dev/null and b/docs/blog/2018-02-16-bright-future-for-the-web/final-product.jpg differ diff --git a/docs/blog/2018-02-16-bright-future-for-the-web/index.md b/docs/blog/2018-02-16-bright-future-for-the-web/index.md new file mode 100644 index 0000000000000..eea976f9094dd --- /dev/null +++ b/docs/blog/2018-02-16-bright-future-for-the-web/index.md @@ -0,0 +1,38 @@ +--- +title: Gatsby And The JAMstack - A Bright Future For The Web +date: "2018-02-16" +image: "bright-future.jpg" +author: "Ryan Wiemer" +--- + +_This article was originally published on +[Medium](https://medium.com/@ryanwiemer/gatsby-and-the-jam-stack-91e31508f364) +on January 31, 2018._ + +Recently I relaunched my wife’s photography portfolio, [KNW Photography](https://www.knw.io/), using a combination of Gatsby, [Contentful](https://www.contentful.com/) and [Netlify](https://www.netlify.com/). This particular group of tools represents a new and exciting web development architecture known as the [JAMstack](https://jamstack.org/) (Javascript, APIs and Markup). In this post I will be sharing my personal thoughts on each of these new tools and why together they represent the “holy grail” of the static website world. + +## Why Other Static Site Generators Didn’t Work For Me + +In case you hadn’t noticed the web moves at an insane speed. With new frameworks and tools being introduced almost daily it can be intimidating even for the most experienced developers. Perhaps you have jumped on the bandwagon too early only to regret it later. Or maybe you have given up on new tools and are happy to settle with outdated …err I mean... trusted solutions. 😉 Admittedly it’s a balancing act but I believe that in order to stay relevant we need to evolve with the web while ensuring that selected tools are robust enough to last. + +It was for those reasons that I was hesitant to pull the trigger on a static site generator. I feared that picking the wrong one would result in wasted time either immediately or later down the road. While static site generators have existed in some form for a while, see [Hugo](https://gohugo.io/), [Jekyll](https://jekyllrb.com/) and [Middleman](https://middlemanapp.com/), they have mostly been used by developers or code-savvy bloggers. Although these tools offer benefits such as greater speed, better security and simpler code what most of them lack in my opinion is a good solution for non technical users to update website content. Asking a non developer to edit a markdown file and commit it to GitHub is simply not realistic for most clients. Some businesses were even started to fill this niche such as [Siteleaf](https://www.siteleaf.com/) and [Forestry](https://forestry.io/) which provide a CMS for static sites built with Jekyll. Although those solutions solve part of the problem they felt too limiting for my taste and creating anything other than a simple blog is like fitting a square peg into a round hole. + +## Gatsby And The Road To Success + +![Road To Success](road-to-success.jpg) + +One day after airing my grievances about the current state of static site generators on Slack a fellow developer recommend that I check out Gatsby. Gatsby is yet another static site generator but what really set it apart for me was how it was built with [React](https://reactjs.org/) and emphasized a rich plugin system. This was a big plus for me as I was itching to learn more about React and the plugin system alleviated some initial pain that I would have had dealing with mundane tasks. Out of the box you get a fantastic development environment with live reloading that required almost no configuration. With Gatsby specific plugins and React components it can handle pretty much anything you throw at it. + +Next came integrating the statically generated site with data stored in a CMS. Again Gatsby was well suited for this and I was able to easily integrate with Contentful via the [gatsby-source-contentful](https://www.gatsbyjs.org/packages/gatsby-source-contentful/) plugin. Contentful is an example of a headless CMS, meaning that is is not tied to any particular technology or language. Contentful allows you to store content using a pleasant user interface and it can then output the data via an API. Best of all Contentful puts you in the driver seat and lets you define your own content model however you see fit. Think [WordPress Advanced Custom Fields](https://www.advancedcustomfields.com/) on steroids. With the content stored in Contentful Gatsby then uses the Contenful API along with the awesome power of [GraphQL](http://graphql.org/) to query data at build time. Cool stuff! + +The final piece of the puzzle was determining where to host the website. I had recently experimented with Netlify on a somewhat [pointless website for my dog](https://www.doggoforhire.com/) and I was impressed by its ease of use and how they offered a fully featured developer tier for free. In no time I was able to get my Gatsby powered website up and running on Netlify. Then with the help of webhooks I was able to have Contentful tell Netlify to “rebuild” the website whenever a new post was published. Finally with Netlify’s form handling functionality I hooked up a contact form all without a single line of backend code or even a database. + +## The Final Product + +![Final Product](final-product.jpg) + +After a little over a month of tinkering on the design during nights and weekends I had a fully functional website ready to be launched. During this process I learned a fair bit of how to code with React and the Gatsby community seemed genuinely nice and happy to help me to learn. The final product was a website that felt like it belonged in 2018 while still allowing my wife to easily update content with no assistance. Not only that the website was immensely faster than the previous WordPress version, served over HTTPS, utilized a CDN and cost me $0 dollars a month thanks to the extremely generous free tiers offered by Netlify and Contentful. 😍 + +If you are currently on the fence about static site generators or the JAMstack in general there has never been a better time to jump in. In my humble opinion with these tools it has finally reached the level of maturity to not just be feasible for client work but actually pretty darn amazing. + +For those interested the source code for the website I built is available on GitHub: https://github.com/ryanwiemer/knw diff --git a/docs/blog/2018-02-16-bright-future-for-the-web/road-to-success.jpg b/docs/blog/2018-02-16-bright-future-for-the-web/road-to-success.jpg new file mode 100644 index 0000000000000..06983d724624c Binary files /dev/null and b/docs/blog/2018-02-16-bright-future-for-the-web/road-to-success.jpg differ diff --git a/docs/blog/2018-2-16-how-to-build-a-website-with-react/index.md b/docs/blog/2018-2-16-how-to-build-a-website-with-react/index.md new file mode 100644 index 0000000000000..c9afad7f5c6da --- /dev/null +++ b/docs/blog/2018-2-16-how-to-build-a-website-with-react/index.md @@ -0,0 +1,54 @@ +--- +title: How to Build a Website with React +date: "2018-02-16" +author: Shannon Soper +--- + +# What is React? + +React is a fantastic and wildly popular tool for building websites and apps, and it creates a world where JavaScript and HTML live in happy harmony in the same files and efficiently renders your ever-changing data to the browser. + +## Declarative + +With React, you can create reusable components that will always render the same data in the same way, which wasn't always the case pre-React. Let’s say you’re a huge Olympics fan and you build a React website for tracking scores. Users who visit your site won’t need to wait for the entire tree to deconstruct and reconstruct when they click a button on your site or when the newest data on the half-pipe is available. React components will efficiently update to accommodate the changing data. + +## Reactive + +React uses a virtual tree reconciliation method to _react_ to changes in input data. Whenever any data changes, instead of rebuilding the whole DOM tree (which would be slow) — it decides what changed in its virtual DOM and then makes the smallest number of DOM changes necessary. + +Almost all frameworks nowadays (e.g. Angular, Vue, etc.) are approaching similar mechanisms. The virtual tree is in contrast to something like vanilla JS or jQuery where you are setting/updating DOM nodes directly. + +## Easy to add to the rest of your stack + +Switching your site(s) to new technologies optimally involves incrementally transferring your site over, page by page, to the new technology. This is difficult to do with some new frontend technologies which want to control the entire page. These technologies are like your friend who wants to take over every social event they get invited to. + +React is not picky; it is happy to be used in only parts of your site, so you can incrementally refactor your code in React. It's more like an easy-going friend who is happy to help with just part of the party you're throwing. It plays nicely with others! + +## Component-Based + +React components and subcomponents tend to come from breaking your website down into the smallest bits possible, using the [single responsibility principle](https://en.wikipedia.org/wiki/Single_responsibility_principle). + +For example, in a To-Do list, the hierarchy of components would include: + +* Whole list + * Title + * add a to-do line + * to-do line + * subtasks within to-dos + * show completed to-dos button + +![To-Do List](to-do-list.png) + +The [Reactjs.org website recommends](https://reactjs.org/docs/thinking-in-react.html) that you work with your designer(s) when creating a hierarchy of React components and subcomponents, because the designers probably already have names for each small piece of the design, and you can make sure your components have the same names. + +React components work just like other functions in any programming language because we call components with some input (called “property” in React) and spit out an output (a chunk of UI in React). Also, components are reusable and can contain other components. All these things are the same as other functions in other programming languages. + +## Using React with Gatsby + +GatsbyJS is a great way to build websites with React and actually solves some unique problems by making the following things more straightforward: + +* _Pulling in data:_ In Gatsby, GraphQL and plugins help you use data from nearly any source (including both traditional CMSs and headless CMSs. Some people I’ve talked to recently even built their Gatsby sites with Google sheets as the data source. +* _Creating pages and routes:_ Gatsby also gives you an intuitive interface for creating pages and routes. So intuitive, in fact, that when I talked to a coworker, I said, “I remember creating pages and links to those pages from other pages, but I don’t remember creating any routes in Gatsby.” They responded, “Yeah, Gatsby took care of that for you.” +* _Solving performance problems:_ Gatsby sites rarely have performance problems due to Gatsby’s way of loading static files. + +Gatsby combines the awesomeness of React with all the friendly helpfulness you’d hope for in a modern PWA framework. Happy coding, and let us know how it goes by joining us on [Twitter](https://twitter.com/gatsbyjs) and [Github](https://github.com/gatsbyjs/gatsby)! diff --git a/docs/blog/2018-2-16-how-to-build-a-website-with-react/to-do-list.png b/docs/blog/2018-2-16-how-to-build-a-website-with-react/to-do-list.png new file mode 100644 index 0000000000000..472f5479b8991 Binary files /dev/null and b/docs/blog/2018-2-16-how-to-build-a-website-with-react/to-do-list.png differ diff --git a/docs/blog/author.yaml b/docs/blog/author.yaml index 41585ec2b689e..1d147f0e27793 100644 --- a/docs/blog/author.yaml +++ b/docs/blog/author.yaml @@ -89,3 +89,7 @@ bio: Founder of Gatsby Manor. Site Reliability Engineer. Open source addict. Writer at Hackernoon. avatar: avatars/steven-natera.jpg twitter: "@stevennatera" +- id: Ryan Wiemer + bio: Oakland based account manager that enjoys working on web and interactive projects - https://www.ryanwiemer.com + avatar: avatars/ryan-wiemer.jpg + twitter: "@ryanwiemer" diff --git a/docs/blog/avatars/ryan-wiemer.jpg b/docs/blog/avatars/ryan-wiemer.jpg new file mode 100644 index 0000000000000..6ac4d296c2c08 Binary files /dev/null and b/docs/blog/avatars/ryan-wiemer.jpg differ diff --git a/docs/docs/adding-tags-and-categories-to-blog-posts.md b/docs/docs/adding-tags-and-categories-to-blog-posts.md index 733f0853443ee..3a6e9ffa899f4 100644 --- a/docs/docs/adding-tags-and-categories-to-blog-posts.md +++ b/docs/docs/adding-tags-and-categories-to-blog-posts.md @@ -104,61 +104,80 @@ const Tags = ({ pathContext, data }) => { All tags ); -}; +==== BASE ==== +} +``` -Tags.propTypes = { - pathContext: PropTypes.shape({ - tag: PropTypes.string.isRequired, - }), - data: PropTypes.shape({ - allMarkdownRemark: PropTypes.shape({ - totalCount: PropTypes.number.isRequired, - edges: PropTypes.arrayOf( - PropTypes.shape({ - node: PropTypes.shape({ - frontmatter: PropTypes.shape({ - path: PropTypes.string.isRequired, - title: PropTypes.string.isRequired, - }), - }), - }).isRequired, - ), - }), - }), -}; +Now we'll instruct Gatsby to create the tag pages. In the site's `gatsby-node.js` file we'll call the the [`createPages`](/docs/node-apis/#createPages) API to make a page for every tag. -export default Tags; +First create a function called `createTagPages`: -export const pageQuery = graphql` - query TagPage($tag: String) { - allMarkdownRemark( - limit: 2000 - sort: { fields: [frontmatter___date], order: DESC } - filter: { frontmatter: { tags: { in: [$tag] } } } - ) { - totalCount - edges { - node { - frontmatter { - title - path - } - } - } - } - } -`; -``` +```javascript +const path = require("path"); -**Note**: `propTypes` are included in this example to help you ensure you're getting all the data you need in the component, and to help serve as a guide while destructuring / using those props. +const createTagPages = (createPage, edges) => { + // Tell it to use our tags template. + const tagTemplate = path.resolve(`src/templates/tags.js`); + // Create an empty object to store the posts. + const posts = {}; + console.log("creating posts"); +==== BASE ==== -## Modify `gatsby-node.js` to render pages using that template +==== BASE ==== + // Loop through all nodes (our markdown posts) and add the tags to our post object. +==== BASE ==== -Now we've got a template. Great! I'll assume you followed the tutorial for [Adding Markdown Pages](/docs/adding-tags-and-categories-to-blog-posts/) and provide a sample `createPages` that generates post pages as well as tag pages. In the site's `gatsby-node.js` file, include `lodash` (`const _ = require('lodash')`) and then make sure your [`createPages`](/docs/node-apis/#createPages) looks something like this: +==== BASE ==== + edges.forEach(({ node }) => { + if (node.frontmatter.tags) { + node.frontmatter.tags.forEach(tag => { + if (!posts[tag]) { + posts[tag] = []; +==== BASE ==== + } +==== BASE ==== + posts[tag].push(node); + }); +==== BASE ==== + } +==== BASE ==== + }); +==== BASE ==== + +==== BASE ==== + // Create the tags page with the list of tags from our posts object. + createPage({ + path: "/tags", + component: tagTemplate, + context: { + posts, + }, + }); +==== BASE ==== + +==== BASE ==== + // For each of the tags in the post object, create a tag page. + + Object.keys(posts).forEach(tagName => { + const post = posts[tagName]; + createPage({ + path: `/tags/${tagName}`, + component: tagTemplate, + context: { + posts, + post, + tag: tagName, + }, + }); + }); +}; +``` ```js -exports.createPages = ({ boundActionCreators, graphql }) => { - const { createPage } = boundActionCreators; +const path = require("path"); + +exports.createPages = ({ actions, graphql }) => { + const { createPage } = actions; const blogPostTemplate = path.resolve('src/templates/blog.js'); const tagTemplate = path.resolve('src/templates/tags.js'); @@ -177,42 +196,26 @@ exports.createPages = ({ boundActionCreators, graphql }) => { } } } +==== BASE ==== } - } - `).then(result => { - if (result.errors) { - return Promise.reject(result.errors); - } - - const posts = result.data.allMarkdownRemark.edges; - - // Create post detail pages - posts.forEach(({ node }) => { - createPage({ - path: node.frontmatter.path, - component: blogPostTemplate, - }); - }); - - // Tag pages: - let tags = []; - // Iterate through each post, putting all found tags into `tags` - _.each(posts, edge => { - if (_.get(edge, 'node.frontmatter.tags')) { - tags = tags.concat(edge.node.frontmatter.tags); - } - }); - // Eliminate duplicate tags - tags = _.uniq(tags); - - // Make tag pages - tags.forEach(tag => { - createPage({ - path: `/tags/${_.kebabCase(tag)}/`, - component: tagTemplate, - context: { - tag, - }, +==== BASE ==== + `).then(result => { + console.log(result); + const posts = result.data.allMarkdownRemark.edges; + + // call createTagPages with the result of posts + createTagPages(createPage, posts); + + // this is the original code used to create the pages from markdown posts + result.data.allMarkdownRemark.edges.map(({ node }) => { + createPage({ + path: node.fields.slug, + component: path.resolve(`./src/templates/blog-post.js`), + context: { + slug: node.fields.slug, + }, + }); +==== BASE ==== }); }); }); diff --git a/docs/docs/api-specification.md b/docs/docs/api-specification.md index af796934b8a53..398dfdf725770 100644 --- a/docs/docs/api-specification.md +++ b/docs/docs/api-specification.md @@ -19,7 +19,7 @@ Plugins can extend Gatsby in many ways: with URLs derived from their file names). * Modifying webpack config (e.g. for styling options, adding support for other compile-to-js languages) -* Adding things to the rendered HTML (e.g. meta tags, analytics JS snippits like +* Adding things to the rendered HTML (e.g. meta tags, analytics JS snippets like Google Analytics) * Writing out things to build directory based on site data (e.g. service worker, sitemap, RSS feed) diff --git a/docs/docs/awesome-gatsby.md b/docs/docs/awesome-gatsby.md index de4a112d06811..276ae59851d38 100644 --- a/docs/docs/awesome-gatsby.md +++ b/docs/docs/awesome-gatsby.md @@ -16,6 +16,10 @@ See the [list of official and community starters](/docs/gatsby-starters/) See the [list of official and community plugins](/docs/plugins/) +## Tools + +* [Develop & Build GatsbyJS static sites within Docker](https://github.com/aripalo/gatsby-docker/) + ## Videos * [Static Site Generation with Gatsby.js v0 — Scott Nonnenberg](https://blog.scottnonnenberg.com/static-site-generation-with-gatsby-js/) diff --git a/docs/docs/gatsby-config.md b/docs/docs/gatsby-config.md index 456e9a78b612d..fead62d5e3717 100644 --- a/docs/docs/gatsby-config.md +++ b/docs/docs/gatsby-config.md @@ -35,7 +35,7 @@ This way you can store it in one place, and pull it whenever you need it. If you See a fuller description and sample usage in [Gatsby.js Tutorial Part Four](/tutorial/part-four/#data-in-gatsby). -## plugins +## Plugins Plugins are Node.js packages that implement Gatsby APIs. The config file accepts an array of plugins. Some plugins may need only to be listed by name, while others may take options (see the docs for individual plugins). @@ -69,7 +69,7 @@ module.exports = { See more about [Adding a Path Prefix](/docs/path-prefix/). -## polyfill +## Polyfill Gatsby uses the ES6 Promise API. Because some browsers don't support this, Gatsby includes a Promise polyfill by default. @@ -83,11 +83,63 @@ module.exports = { See more about [Browser Support](/docs/browser-support/#polyfills) in Gatsby. -## mapping +## Mapping node types -TODO +Gatsby includes an advanced feature that lets you create "mappings" between node types. -## proxy +For instance, imagine you have a multi-author markdown blog where you want to "link" from each blog post to the author information stored in a yaml file named `author.yaml`: + +```markdown +--- +title: A blog post +author: Kyle Mathews +--- + +A treatsie on the efficacy of bezoar for treating agricultural pesticide poisoning. +``` + +author.yaml + +```yaml +- id: Kyle Mathews + bio: Founder @ GatsbyJS. Likes tech, reading/writing, founding things. Blogs at bricolage.io. + twitter: "@kylemathews" +``` + +You can map between the `author` field in `frontmatter` to the id in the `author.yaml` objects by adding to your `gatsby-config.js`: + +```javascript +module.exports = { + plugins: [...], + mapping: { + "MarkdownRemark.frontmatter.author": `AuthorYaml`, + }, +} +``` + +Gatsby then uses this mapping when creating the GraphQL schema to enable you to query data from both sources: + +```graphql +query BlogPost($slug: String!) { + markdownRemark(fields: { slug: { eq: $slug } }) { + html + fields { + slug + } + frontmatter { + title + author { + # This now links to the author object + id + bio + twitter + } + } + } +} +``` + +## Proxy Setting the proxy config option will tell the development server to proxy any unknown requests to your specified server. For example: diff --git a/docs/docs/gatsby-starters.md b/docs/docs/gatsby-starters.md index 2d5f4b5f9317a..d08961b3d90a2 100644 --- a/docs/docs/gatsby-starters.md +++ b/docs/docs/gatsby-starters.md @@ -462,3 +462,13 @@ Community: * Automatic Favicons * Typography.js * Part of a german tutorial series on Gatsby. The starter will change over time to use more advanced stuff (feel free to express your ideas) + +* [gatsby-starter-redux](https://github.com/caki0915/gatsby-starter-redux) + [(demo)](https://caki0915.github.io/gatsby-starter-redux/) + + Features: + + * [Redux](https://github.com/reactjs/redux) and [Redux-devtools](https://github.com/gaearon/redux-devtools). + * [Emotion](https://github.com/emotion-js/emotion) with a basic theme and SSR + * [Typography.js](https://kyleamathews.github.io/typography.js/) + * Eslint rules based on [Prettier](https://prettier.io/) and [Airbnb](https://www.npmjs.com/package/eslint-config-airbnb) diff --git a/docs/docs/plugins.md b/docs/docs/plugins.md index 6fb1bde958fc8..c8b25ffa0ae7b 100644 --- a/docs/docs/plugins.md +++ b/docs/docs/plugins.md @@ -206,6 +206,7 @@ root. * [gatsby-source-unsplash](https://github.com/vacas5/gatsby-source-unsplash) * [gatsby-source-workable](https://github.com/tumblbug/gatsby-source-workable) * [gatsby-transformer-orga](https://github.com/xiaoxinghu/orgajs/tree/master/packages/gatsby-transformer-orga) +* [gatsby-source-dribbble](https://github.com/smakosh/gatsby-source-dribbble) ## Community Library diff --git a/docs/tutorial/part-four/index.md b/docs/tutorial/part-four/index.md index 125245fefe78b..778852b8355c4 100644 --- a/docs/tutorial/part-four/index.md +++ b/docs/tutorial/part-four/index.md @@ -230,7 +230,7 @@ module.exports = { }, }, ], -} +}; ``` Restart the development server. @@ -405,7 +405,7 @@ module.exports = { }, }, ], -} +}; ``` Save that and restart the gatsby development server. Then open up Graph_i_QL diff --git a/docs/tutorial/part-one/index.md b/docs/tutorial/part-one/index.md index c7adb5536f2f4..bb830a52b6b08 100644 --- a/docs/tutorial/part-one/index.md +++ b/docs/tutorial/part-one/index.md @@ -28,7 +28,7 @@ You should see something like: ![Check if node.js/npm is installed](check-versions.png) -Gatsby supports versions of Node back to v4 and npm to v3. +Gatsby supports versions of Node back to v6 and npm to v3. If you don't have Node.js installed, go to https://nodejs.org/ and install the recommended version for your operating system. diff --git a/docs/tutorial/part-two/index.md b/docs/tutorial/part-two/index.md index d3bdbaf9c4db6..6d7c47052f10e 100644 --- a/docs/tutorial/part-two/index.md +++ b/docs/tutorial/part-two/index.md @@ -197,7 +197,7 @@ Let's make a quick improvement. Many sites have a single column of text centered in the middle of the page. To create this, add the following styles to the `
` in `src/pages/index.js`. -```jsx{4} +```jsx{4,23} import React from "react"; export default () => @@ -322,6 +322,7 @@ While we won't cover CSS-in-JS in this initial tutorial, we encourage you to exp as well as [Mark Dalgleish's more recent post "A Unified Styling Language"](https://medium.com/seek-blog/a-unified-styling-language-d0c208de2660). + ### CSS Modules Let's explore **CSS Modules**. @@ -422,8 +423,8 @@ Paste the following into the file: } ``` -Now import that file into the `about-css-modules.js` page we created earlier. -Also log the resulting import so we can see what the processed file looks like. +Now import that file into the `about-css-modules.js` page we created earlier, by adding the following on lines 2 and 3. +(The `console.log(styles)` code logs the resulting import so we can see what the processed file looks like). ```javascript import styles from "./about-css-modules.module.css"; @@ -453,6 +454,7 @@ Modify `about-css-modules.js` so it looks like the following: ```jsx{6-17,23-30} import React from "react"; import styles from "./about-css-modules.module.css"; +console.log(styles); import Container from "../components/container"; diff --git a/packages/gatsby-1-config-css-modules/package.json b/packages/gatsby-1-config-css-modules/package.json index eebf218bcbfef..dfc2c8bfa1aee 100644 --- a/packages/gatsby-1-config-css-modules/package.json +++ b/packages/gatsby-1-config-css-modules/package.json @@ -18,6 +18,7 @@ "keywords": [ "gatsby" ], + "author": "Ming Aldrich-Gan ", "license": "MIT", "main": "index.js", "repository": { diff --git a/packages/gatsby-plugin-sharp/src/index.js b/packages/gatsby-plugin-sharp/src/index.js index 953e3cda8abdb..38fc03c4ebc1f 100644 --- a/packages/gatsby-plugin-sharp/src/index.js +++ b/packages/gatsby-plugin-sharp/src/index.js @@ -13,6 +13,7 @@ const path = require(`path`) const duotone = require(`./duotone`) const { boundActionCreators } = require(`gatsby/dist/redux/actions`) +const report = require(`gatsby-cli/lib/reporter`) // Promisify the sharp prototype (methods) to promisify the alternative (for // raw) callback-accepting toBuffer(...) method @@ -42,7 +43,15 @@ const processFile = (file, jobs, cb) => { // Wait for each job promise to resolve. Promise.all(jobs.map(job => job.finishedPromise)).then(() => cb()) - const pipeline = sharp(file).rotate() + let pipeline + try { + pipeline = sharp(file).rotate() + } catch (err) { + report.error(`Failed to process image ${file}`, err) + jobs.forEach(job => job.outsideReject(err)) + return + } + jobs.forEach(async job => { const args = job.args let clonedPipeline @@ -75,6 +84,10 @@ const processFile = (file, jobs, cb) => { quality: args.quality, force: args.toFormat === `webp`, }) + .tiff({ + quality: args.quality, + force: args.toFormat === `tiff`, + }) // grayscale if (args.grayscale) { @@ -95,76 +108,70 @@ const processFile = (file, jobs, cb) => { ) } + const onFinish = err => { + imagesFinished += 1 + bar.tick() + boundActionCreators.setJob( + { + id: `processing image ${job.file.absolutePath}`, + imagesFinished, + }, + { name: `gatsby-plugin-sharp` } + ) + + if (err) { + report.error(`Failed to process image ${file}`, err) + job.outsideReject(err) + } else { + job.outsideResolve() + } + } + if ( - (job.file.extension.match(/^jp/) && args.toFormat === ``) || - args.toFormat === `jpg` - ) { - clonedPipeline.toFile(job.outputPath, (err, info) => { - imagesFinished += 1 - bar.tick() - boundActionCreators.setJob( - { - id: `processing image ${job.file.absolutePath}`, - imagesFinished, - }, - { name: `gatsby-plugin-sharp` } - ) - job.outsideResolve(info) - }) - // Compress pngs - } else if ( (job.file.extension === `png` && args.toFormat === ``) || args.toFormat === `png` ) { - clonedPipeline.toBuffer().then(sharpBuffer => { - imagemin - .buffer(sharpBuffer, { - plugins: [ - imageminPngquant({ - quality: `${args.quality}-${Math.min(args.quality + 25, 100)}`, // e.g. 40-65 - }), - ], - }) - .then(imageminBuffer => { - fs.writeFile(job.outputPath, imageminBuffer, () => { - imagesFinished += 1 - bar.tick() - boundActionCreators.setJob( - { - id: `processing image ${job.file.absolutePath}`, - imagesFinished, - }, - { name: `gatsby-plugin-sharp` } - ) - job.outsideResolve() + clonedPipeline + .toBuffer() + .then(sharpBuffer => { + imagemin + .buffer(sharpBuffer, { + plugins: [ + imageminPngquant({ + quality: `${args.quality}-${Math.min( + args.quality + 25, + 100 + )}`, // e.g. 40-65 + }), + ], }) - }) - }) + .then(imageminBuffer => { + fs.writeFile(job.outputPath, imageminBuffer, onFinish) + }) + .catch(onFinish) + }) + .catch(onFinish) // Compress webp } else if ( (job.file.extension === `webp` && args.toFormat === ``) || args.toFormat === `webp` ) { - clonedPipeline.toBuffer().then(sharpBuffer => { - imagemin - .buffer(sharpBuffer, { - plugins: [imageminWebp({ quality: args.quality })], - }) - .then(imageminBuffer => { - fs.writeFile(job.outputPath, imageminBuffer, () => { - imagesFinished += 1 - bar.tick() - boundActionCreators.setJob( - { - id: `processing image ${job.file.absolutePath}`, - imagesFinished, - }, - { name: `gatsby-plugin-sharp` } - ) - job.outsideResolve() + clonedPipeline + .toBuffer() + .then(sharpBuffer => { + imagemin + .buffer(sharpBuffer, { + plugins: [imageminWebp({ quality: args.quality })], }) - }) - }) + .then(imageminBuffer => { + fs.writeFile(job.outputPath, imageminBuffer, onFinish) + }) + .catch(onFinish) + }) + .catch(onFinish) + // any other format (jpeg, tiff) - don't compress it just handle output + } else { + clonedPipeline.toFile(job.outputPath, onFinish) } }) } @@ -268,9 +275,10 @@ function queueImageResizing({ file, args = {} }) { const filePath = path.join(process.cwd(), `public`, `static`, imgSrc) // Create function to call when the image is finished. - let outsideResolve - const finishedPromise = new Promise(resolve => { + let outsideResolve, outsideReject + const finishedPromise = new Promise((resolve, reject) => { outsideResolve = resolve + outsideReject = reject }) let width @@ -300,6 +308,7 @@ function queueImageResizing({ file, args = {} }) { args: options, finishedPromise, outsideResolve, + outsideReject, inputPath: file.absolutePath, outputPath: filePath, } @@ -331,7 +340,13 @@ async function notMemoizedbase64({ file, args = {} }) { toFormat: ``, } const options = _.defaults(args, defaultArgs) - let pipeline = sharp(file.absolutePath).rotate() + let pipeline + try { + pipeline = sharp(file.absolutePath).rotate() + } catch (err) { + report.error(`Failed to process image ${file.absolutePath}`, err) + return null + } pipeline .resize(options.width, options.height) @@ -400,7 +415,15 @@ async function responsiveSizes({ file, args = {} }) { // Account for images with a high pixel density. We assume that these types of // images are intended to be displayed at their native resolution. - const { width, height, density } = await sharp(file.absolutePath).metadata() + let metadata + try { + metadata = await sharp(file.absolutePath).metadata() + } catch (err) { + report.error(`Failed to process image ${file.absolutePath}`, err) + return null + } + + const { width, height, density } = metadata const pixelRatio = options.sizeByPixelDensity && typeof density === `number` && density > 0 ? density / 72 @@ -620,7 +643,13 @@ async function notMemoizedtraceSVG({ file, args, fileArgs }) { toFormat: ``, } const options = _.defaults(fileArgs, defaultFileResizeArgs) - let pipeline = sharp(file.absolutePath).rotate() + let pipeline + try { + pipeline = sharp(file.absolutePath).rotate() + } catch (err) { + report.error(`Failed to process image ${file.absolutePath}`, err) + return null + } pipeline .resize(options.width, options.height) diff --git a/packages/gatsby-source-filesystem/README.md b/packages/gatsby-source-filesystem/README.md index 40e726d73a891..5046b55704490 100644 --- a/packages/gatsby-source-filesystem/README.md +++ b/packages/gatsby-source-filesystem/README.md @@ -58,3 +58,65 @@ You can query file nodes like the following: } } ``` + +## Helper functions + +`gatsby-source-filesystem` exports two helper functions: + +* `createFilePath` +* `createRemoteFileNode` + +### createFilePath + +When building pages from files, you often want to create a URL from a file's path on the file system. E.g. if you have a markdown file at `src/content/2018-01-23-an-exploration-of-the-nature-of-reality/index.md`, you might want to turn that into a page on your site at `example.com/2018-01-23-an-exploration-of-the-nature-of-reality/`. `createFilePath` is a helper function to make this task easier. + +```javascript +createFilePath({ + // The node you'd like to convert to a path + // e.g. froom a markdown, JSON, YAML file, etc + node: + // Method used to get a node + // The parameter from `onCreateNode` should be passed in here + getNode: + // The base path for your files. + // Defaults to `src/pages`. For the example above, you'd use `src/contents`. + basePath: + // Whether you want your file paths to contain a trailing `/` slash + // Defaults to true + trailingSlash: +}) +``` + +#### Example usage + +The following is taken from [Gatsby Tutorial, Part Four](https://www.gatsbyjs.org/tutorial/part-four/#programmatically-creating-pages-from-data) and is used to create URL slugs for markdown pages. + +```javascript +const { createFilePath } = require(`gatsby-source-filesystem`); + +exports.onCreateNode = ({ node, getNode, boundActionCreators }) => { + const { createNodeField } = boundActionCreators; + // Ensures we are processing only markdown files + if (node.internal.type === "MarkdownRemark") { + // Use `createFilePath` to turn markdown files in our `data/faqs` directory into `/faqs/slug` + const relativeFilePath = createFilePath({ + node, + getNode, + basePath: "data/faqs/", + }); + + // Creates new query'able field with name of 'slug' + createNodeField({ + node, + name: "slug", + value: `/faqs${relativeFilePath}`, + }); + } +}; +``` + +### createRemoteFileNode + +```javascript +TO DO +``` diff --git a/packages/gatsby/src/bootstrap/get-config-file.js b/packages/gatsby/src/bootstrap/get-config-file.js index 89619b0070a72..aa5734df119af 100644 --- a/packages/gatsby/src/bootstrap/get-config-file.js +++ b/packages/gatsby/src/bootstrap/get-config-file.js @@ -4,6 +4,7 @@ const fs = require(`fs-extra`) const testRequireError = require(`../utils/test-require-error`).default const report = require(`gatsby-cli/lib/reporter`) const chalk = require(`chalk`) +const path = require(`path`) function isNearMatch( fileName: string, @@ -18,7 +19,7 @@ module.exports = async function getConfigFile( configName: string, distance: number = 3 ) { - const configPath = `${rootDir}/${configName}` + const configPath = path.join(rootDir, configName) let configModule try { configModule = require(configPath) @@ -41,6 +42,13 @@ module.exports = async function getConfigFile( ) console.log(``) process.exit(1) + } else if (fs.existsSync(path.join(rootDir, `src`, configName))) { + console.log(``) + report.error( + `Your gatsby-config.js file is in the wrong place. You've placed in the src/ directory. It must instead be at the root of your site next to your package.json file.` + ) + console.log(``) + process.exit(1) } } diff --git a/packages/gatsby/src/internal-plugins/dev-404-page/gatsby-node.js b/packages/gatsby/src/internal-plugins/dev-404-page/gatsby-node.js index 1204fa110c985..5763c254d5028 100644 --- a/packages/gatsby/src/internal-plugins/dev-404-page/gatsby-node.js +++ b/packages/gatsby/src/internal-plugins/dev-404-page/gatsby-node.js @@ -2,7 +2,11 @@ const path = require(`path`) const fs = require(`fs-extra`) const chokidar = require(`chokidar`) -exports.createPagesStatefully = async ({ store, actions }, options, done) => { +exports.createPagesStatefully = async ( + { store, actions }, + options, + done +) => { if (process.env.NODE_ENV !== `production`) { const { program } = store.getState() const { createPage } = actions diff --git a/packages/gatsby/src/schema/infer-graphql-type.js b/packages/gatsby/src/schema/infer-graphql-type.js index fcdccdaa53b2b..bc9e296282787 100644 --- a/packages/gatsby/src/schema/infer-graphql-type.js +++ b/packages/gatsby/src/schema/infer-graphql-type.js @@ -246,9 +246,10 @@ function inferFromFieldName(value, selector, types): GraphQLFieldConfig<*, *> { // If there's more than one type, we'll create a union type. if (fields.length > 1) { type = new GraphQLUnionType({ - name: `Union_${key}_${fields.map(f => f.name).join(`__`)}`, + name: `Union_${key}_${fields.map(f => f.name).sort().join(`__`)}`, description: `Union interface for the field "${key}" for types [${fields .map(f => f.name) + .sort() .join(`, `)}]`, types: fields.map(f => f.nodeObjectType), resolveType: data => diff --git a/scripts/www-graphql-docker-push.sh b/scripts/www-graphql-docker-push.sh new file mode 100644 index 0000000000000..7dbe0fb99122a --- /dev/null +++ b/scripts/www-graphql-docker-push.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# Path to here +DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) + +# Prepare +docker login -u "$DOCKER_USER" -p "$DOCKER_PASS" +export REPO=mikeallanson/gatsby-graphql +export TAG=latest + +# Build +# Build the Dockerfile located at ../, using ../ as the context directory +docker build -t "$REPO":"$TRAVIS_COMMIT" -f "$DIR"/../Dockerfile "$DIR"/../ + +docker tag "$REPO":"$TRAVIS_COMMIT" "$REPO":"$TAG" +docker tag "$REPO":"$TRAVIS_COMMIT" "$REPO":travis-"$TRAVIS_BUILD_NUMBER" + +# Push +docker push "$REPO" diff --git a/www/.travis.yml b/www/.travis.yml deleted file mode 100644 index 7ea1540678ec3..0000000000000 --- a/www/.travis.yml +++ /dev/null @@ -1,38 +0,0 @@ -# back to language cpp to try to bypass osx node failure -language: cpp -sudo: false -env: - - export NODE_VERSION="0.12" - - export NODE_VERSION="4" - - export NODE_VERSION="5" -os: - - linux - - osx -# pre-install to bring in the correct version of node via nvm -before_install: - - git submodule update --init --recursive - - git clone https://github.com/creationix/nvm.git ./.nvm - - source ./.nvm/nvm.sh - - nvm install $NODE_VERSION - - nvm use $NODE_VERSION - - npm config set python `which python` - - if [ $TRAVIS_OS_NAME == "linux" ]; then - export CC="gcc-4.8"; - export CXX="g++-4.8"; - export LINK="gcc-4.8"; - export LINKXX="g++-4.8"; - fi - - gcc --version - - g++ --version -# node 4 depends on gcc 4.8 -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-4.8 - - gcc-4.8 -# script needed to test, because defaults don't work on osx -script: - - npm install - - npm run lint diff --git a/yarn.lock b/yarn.lock index b2488e0029295..7ae5038eadb88 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3274,6 +3274,14 @@ compare-func@^1.3.1: array-ify "^1.0.0" dot-prop "^3.0.0" +compass-vertical-rhythm@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/compass-vertical-rhythm/-/compass-vertical-rhythm-1.4.0.tgz#41cff92ef369d27e295d685f1ff420ff410e9883" + dependencies: + convert-css-length "^1.0.1" + object-assign "^4.1.0" + parse-unit "^1.0.1" + component-bind@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" @@ -3353,6 +3361,10 @@ 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" +console-polyfill@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/console-polyfill/-/console-polyfill-0.1.2.tgz#96cfed51caf78189f699572e6f18271dc37c0e30" + console-stream@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/console-stream/-/console-stream-0.1.1.tgz#a095fe07b20465955f2fafd28b5d72bccd949d44" @@ -3553,6 +3565,13 @@ conventional-recommended-bump@^1.0.1: meow "^3.3.0" object-assign "^4.0.1" +convert-css-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/convert-css-length/-/convert-css-length-1.0.1.tgz#f3ecec664f2e873a0570e6afdd3e1ae4f92444b7" + dependencies: + console-polyfill "^0.1.2" + parse-unit "^1.0.1" + convert-hrtime@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/convert-hrtime/-/convert-hrtime-2.0.0.tgz#19bfb2c9162f9e11c2f04c2c79de2b7e8095c627" @@ -3961,7 +3980,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.2, debug@^2.3.3, debug@^2.6.0, debug@^2.6. dependencies: ms "2.0.0" -decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: +decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -5691,15 +5710,6 @@ fuzzy@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/fuzzy/-/fuzzy-0.1.3.tgz#4c76ec2ff0ac1a36a9dccf9a00df8623078d4ed8" -gatsby-module-loader@^2.0.0-alpha.1: - version "2.0.0-alpha.f5c1df61" - resolved "https://registry.yarnpkg.com/gatsby-module-loader/-/gatsby-module-loader-2.0.0-alpha.f5c1df61.tgz#54d82114ccb9a9e73f27cb7f8c4633973315e97c" - dependencies: - babel-runtime "^6.26.0" - common-tags "^1.4.0" - dedent "^0.7.0" - loader-utils "^1.0.2" - gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -6113,6 +6123,10 @@ gray-matter@^3.0.0, gray-matter@^3.0.6: kind-of "^5.0.2" strip-bom-string "^1.0.0" +gray-percentage@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gray-percentage/-/gray-percentage-2.0.0.tgz#b72a274d1b1379104a0050b63b207dc53fe56f99" + growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" @@ -7432,33 +7446,21 @@ istanbul-api@^1.1.14: mkdirp "^0.5.1" once "^1.4.0" -istanbul-lib-coverage@^1.0.0-alpha.4, istanbul-lib-coverage@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.2.tgz#4113c8ff6b7a40a1ef7350b01016331f63afde14" - -istanbul-lib-coverage@^1.1.1: +istanbul-lib-coverage@^1.0.0-alpha.4, istanbul-lib-coverage@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da" +istanbul-lib-coverage@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.2.tgz#4113c8ff6b7a40a1ef7350b01016331f63afde14" + istanbul-lib-hook@^1.0.0-alpha.4, istanbul-lib-hook@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz#8538d970372cb3716d53e55523dd54b557a8d89b" dependencies: append-transform "^0.4.0" -istanbul-lib-instrument@^1.1.0-alpha.3: - version "1.9.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.2.tgz#84905bf47f7e0b401d6b840da7bad67086b4aab6" - dependencies: - babel-generator "^6.18.0" - babel-template "^6.16.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - babylon "^6.18.0" - istanbul-lib-coverage "^1.1.2" - semver "^5.3.0" - -istanbul-lib-instrument@^1.7.5, istanbul-lib-instrument@^1.8.0, istanbul-lib-instrument@^1.9.1: +istanbul-lib-instrument@^1.1.0-alpha.3, istanbul-lib-instrument@^1.7.5, istanbul-lib-instrument@^1.8.0, istanbul-lib-instrument@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz#250b30b3531e5d3251299fdd64b0b2c9db6b558e" dependencies: @@ -7470,16 +7472,7 @@ istanbul-lib-instrument@^1.7.5, istanbul-lib-instrument@^1.8.0, istanbul-lib-ins istanbul-lib-coverage "^1.1.1" semver "^5.3.0" -istanbul-lib-report@^1.0.0-alpha.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.3.tgz#2df12188c0fa77990c0d2176d2d0ba3394188259" - dependencies: - istanbul-lib-coverage "^1.1.2" - mkdirp "^0.5.1" - path-parse "^1.0.5" - supports-color "^3.1.2" - -istanbul-lib-report@^1.1.2: +istanbul-lib-report@^1.0.0-alpha.3, istanbul-lib-report@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz#922be27c13b9511b979bd1587359f69798c1d425" dependencies: @@ -7488,17 +7481,7 @@ istanbul-lib-report@^1.1.2: path-parse "^1.0.5" supports-color "^3.1.2" -istanbul-lib-source-maps@^1.0.0-alpha.10: - version "1.2.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.3.tgz#20fb54b14e14b3fb6edb6aca3571fd2143db44e6" - dependencies: - debug "^3.1.0" - istanbul-lib-coverage "^1.1.2" - mkdirp "^0.5.1" - rimraf "^2.6.1" - source-map "^0.5.3" - -istanbul-lib-source-maps@^1.2.1, istanbul-lib-source-maps@^1.2.2: +istanbul-lib-source-maps@^1.0.0-alpha.10, istanbul-lib-source-maps@^1.2.1, istanbul-lib-source-maps@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz#750578602435f28a0c04ee6d7d9e0f2960e62c1c" dependencies: @@ -7508,13 +7491,7 @@ istanbul-lib-source-maps@^1.2.1, istanbul-lib-source-maps@^1.2.2: rimraf "^2.6.1" source-map "^0.5.3" -istanbul-reports@^1.0.0-alpha.8: - version "1.1.4" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.4.tgz#5ccba5e22b7b5a5d91d5e0a830f89be334bf97bd" - dependencies: - handlebars "^4.0.3" - -istanbul-reports@^1.1.3: +istanbul-reports@^1.0.0-alpha.8, istanbul-reports@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.3.tgz#3b9e1e8defb6d18b1d425da8e8b32c5a163f2d10" dependencies: @@ -8422,6 +8399,10 @@ lodash.isequal@^4.0.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" +lodash.isnumber@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + lodash.iteratee@^4.5.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.iteratee/-/lodash.iteratee-4.7.0.tgz#be4177db289a8ccc3c0990f1db26b5b22fc1554c" @@ -9097,6 +9078,12 @@ modify-values@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.0.tgz#e2b6cdeb9ce19f99317a53722f3dbf5df5eaaab2" +modularscale@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/modularscale/-/modularscale-1.0.2.tgz#4a8f13af32a5e5214fc6e2cfc529064abfd7d877" + dependencies: + lodash.isnumber "^3.0.0" + module-deps-sortable@4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/module-deps-sortable/-/module-deps-sortable-4.0.6.tgz#1251a4ba2c44a92df6989bd029da121a4f2109b0" @@ -9999,6 +9986,10 @@ parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" +parse-unit@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-unit/-/parse-unit-1.0.1.tgz#7e1bb6d5bef3874c28e392526a2541170291eecf" + parse-url@^1.3.0: version "1.3.11" resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-1.3.11.tgz#57c15428ab8a892b1f43869645c711d0e144b554" @@ -14163,6 +14154,10 @@ typescript@^2.2.1: version "2.7.1" resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.1.tgz#bb3682c2c791ac90e7c6210b26478a8da085c359" +typography-normalize@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/typography-normalize/-/typography-normalize-0.14.0.tgz#1d77c1fe2aaf4a51b3673c4c85c85a65a2d4b573" + ua-parser-js@^0.7.9: version "0.7.17" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"