diff --git a/.babelrc.js b/.babelrc.js
index 666c1a0efb70a..4eb42997a778d 100644
--- a/.babelrc.js
+++ b/.babelrc.js
@@ -6,10 +6,8 @@ if (process.env.NODE_ENV !== `test`) {
ignore.push(`**/__tests__`)
}
-const presetAbsPath = require(`path`).join(__dirname, '.babel-preset.js')
-
module.exports = {
sourceMaps: true,
- presets: [presetAbsPath],
+ presets: ["babel-preset-gatsby-package"],
ignore,
}
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 8e5e9075adf57..731f713bc9d93 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -1,38 +1,34 @@
-aliases:
- node6: &node6
- docker:
- - image: circleci/node:6
-
- node8: &node8
- docker:
- - image: circleci/node:8
-
- node10: &node10
+executors:
+ node:
+ parameters:
+ image:
+ type: string
+ default: "10"
docker:
- - image: circleci/node:10
+ - image: circleci/node:<< parameters.image >>
- node10_browsers: &node10_browsers
+aliases:
+ e2e-executor: &e2e-executor
docker:
- - image: circleci/node:10-browsers
+ - image: cypress/browsers:chrome69
- restore_node_modules: &restore_node_modules
+ restore_cache: &restore_cache
restore_cache:
name: Restore node_modules cache
keys:
- - node-modules-{{ checksum "yarn.lock" }}
+ - yarn-cypress-cache-{{ checksum "yarn.lock" }}
install_node_modules: &install_node_modules
run:
name: Install node modules
- command: |
- yarn
+ command: yarn --frozen-lockfile
- persist_node_modules: &persist_node_modules
+ persist_cache: &persist_cache
save_cache:
name: Save node modules cache
- key: node-modules-{{ checksum "yarn.lock" }}
+ key: yarn-cypress-cache-{{ checksum "yarn.lock" }}
paths:
- - node_modules
+ - ~/.cache
attach_to_bootstrap: &attach_to_bootstrap
attach_workspace:
@@ -44,32 +40,61 @@ aliases:
ignore:
- master
+ ignore_docs: &ignore_docs
+ filters:
+ branches:
+ ignore:
+ - /docs.+/
+ - /blog.+/
+
test_template: &test_template
steps:
- checkout
- - run: ./scripts/assert-changed-files.sh "packages/*|integration-tests/*"
- - <<: *restore_node_modules
+ - run: ./scripts/assert-changed-files.sh "packages/*|.circleci/*"
+ - <<: *restore_cache
- <<: *install_node_modules
- - <<: *persist_node_modules
+ - <<: *persist_cache
- <<: *attach_to_bootstrap
- run: yarn jest -w 1
- integration_test_workflow: &integration_test_workflow
- <<: *ignore_master
+ e2e-test-workflow: &e2e-test-workflow
+ filters:
+ branches:
+ ignore:
+ - master
+ - /docs.+/
+ - /blog.+/
requires:
- bootstrap
-version: 2
+commands:
+ e2e-test:
+ parameters:
+ trigger_pattern:
+ type: string
+ default: "packages/*|.circleci/*"
+ test_path:
+ type: string
+ steps:
+ - checkout
+ - run: ./scripts/assert-changed-files.sh "<< parameters.trigger_pattern >>|<< parameters.test_path >>/*"
+ - <<: *restore_cache
+ - <<: *install_node_modules
+ - <<: *persist_cache
+ - <<: *attach_to_bootstrap
+ - run: ./scripts/e2e-test.sh "<< parameters.test_path >>"
+
+version: 2.1
jobs:
bootstrap:
- <<: *node10
+ executor: node
steps:
- checkout
- - run: ./scripts/assert-changed-files.sh "packages/*|integration-tests/*"
- - <<: *restore_node_modules
+ - run: ./scripts/assert-changed-files.sh "packages/*|(e2e|integration)-tests/*|.circleci/*"
+ - <<: *restore_cache
- <<: *install_node_modules
- - <<: *persist_node_modules
+ - <<: *persist_cache
- run: yarn bootstrap
- persist_to_workspace:
root: packages
@@ -77,75 +102,64 @@ jobs:
- "*"
lint:
- <<: *node10
+ executor: node
steps:
- checkout
- - <<: *restore_node_modules
+ - <<: *restore_cache
- <<: *install_node_modules
- - <<: *persist_node_modules
+ - <<: *persist_cache
- run: yarn lint
unit_tests_node6:
- <<: *node6
+ executor:
+ name: node
+ image: "6"
<<: *test_template
unit_tests_node8:
- <<: *node8
+ executor:
+ name: node
+ image: "8"
<<: *test_template
unit_tests_node10:
- <<: *node10
+ executor: node
<<: *test_template
integration_tests:
- <<: *node10
+ executor: node
steps:
- checkout
- - run: ./scripts/assert-changed-files.sh "packages/*|integration-tests/*"
- - <<: *restore_node_modules
+ - run: ./scripts/assert-changed-files.sh "packages/*|integration-tests/*|.circleci/*"
+ - <<: *restore_cache
- <<: *install_node_modules
- - <<: *persist_node_modules
+ - <<: *persist_cache
+ - <<: *attach_to_bootstrap
- run: yarn test:integration
e2e_tests_gatsbygram:
- <<: *node10_browsers
+ <<: *e2e-executor
steps:
- - checkout
- - run: ./scripts/assert-changed-files.sh "packages/*|integration-tests/*|examples/gatsbygram/*"
- - <<: *restore_node_modules
- - <<: *install_node_modules
- - <<: *attach_to_bootstrap
- - run: ./scripts/integration-test.sh examples/gatsbygram
+ - e2e-test:
+ test_path: examples/gatsbygram
e2e_tests_path-prefix:
- <<: *node10_browsers
+ <<: *e2e-executor
steps:
- - checkout
- - run: ./scripts/assert-changed-files.sh "packages/*|integration-tests/*"
- - <<: *restore_node_modules
- - <<: *install_node_modules
- - <<: *attach_to_bootstrap
- - run: ./scripts/integration-test.sh integration-tests/path-prefix
+ - e2e-test:
+ test_path: e2e-tests/path-prefix
e2e_tests_gatsby-image:
- <<: *node10_browsers
+ <<: *e2e-executor
steps:
- - checkout
- - run: ./scripts/assert-changed-files.sh "packages/*|integration-tests/*"
- - <<: *restore_node_modules
- - <<: *install_node_modules
- - <<: *attach_to_bootstrap
- - run: ./scripts/integration-test.sh integration-tests/gatsby-image
+ - e2e-test:
+ test_path: e2e-tests/gatsby-image
e2e_tests_runtime:
- <<: *node10_browsers
+ <<: *e2e-executor
steps:
- - checkout
- - run: ./scripts/assert-changed-files.sh "packages/*|integration-tests/*"
- - <<: *restore_node_modules
- - <<: *install_node_modules
- - <<: *attach_to_bootstrap
- - run: ./scripts/integration-test.sh integration-tests/production-runtime
+ - e2e-test:
+ test_path: e2e-tests/production-runtime
workflows:
version: 2
@@ -154,20 +168,24 @@ workflows:
- bootstrap
- lint
- unit_tests_node6:
+ <<: *ignore_docs
requires:
- bootstrap
- unit_tests_node8:
+ <<: *ignore_docs
requires:
- bootstrap
- unit_tests_node10:
+ <<: *ignore_docs
requires:
- bootstrap
- - integration_tests
+ - integration_tests:
+ <<: *ignore_docs
- e2e_tests_gatsbygram:
- <<: *integration_test_workflow
+ <<: *e2e-test-workflow
- e2e_tests_path-prefix:
- <<: *integration_test_workflow
+ <<: *e2e-test-workflow
- e2e_tests_gatsby-image:
- <<: *integration_test_workflow
+ <<: *e2e-test-workflow
- e2e_tests_runtime:
- <<: *integration_test_workflow
+ <<: *e2e-test-workflow
diff --git a/.editorconfig b/.editorconfig
index 1e48203106beb..ae10a5cce3b26 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -7,4 +7,4 @@ end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
-trim_trailing_whitespace = true
\ No newline at end of file
+trim_trailing_whitespace = true
diff --git a/.eslintrc.json b/.eslintrc.json
index a049b127e7747..4efa02222c841 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -9,7 +9,7 @@
"prettier/flowtype",
"prettier/react"
],
- "plugins": ["flowtype", "react"],
+ "plugins": ["flowtype", "prettier", "react"],
"parserOptions": {
"ecmaVersion": 2016,
"sourceType": "module",
@@ -27,36 +27,22 @@
"spyOn": true
},
"rules": {
- "no-console": "off",
- "no-inner-declarations": "off",
- "valid-jsdoc": "off",
- "require-jsdoc": "off",
- "quotes": ["error", "backtick"],
- "consistent-return": ["error"],
"arrow-body-style": [
"error",
"as-needed",
{ "requireReturnForObjectLiteral": true }
],
- "jsx-quotes": ["error", "prefer-double"],
- "semi": ["error", "never"],
- "object-curly-spacing": ["error", "always"],
- "comma-dangle": [
- "error",
- {
- "arrays": "always-multiline",
- "objects": "always-multiline",
- "imports": "always-multiline",
- "exports": "always-multiline",
- "functions": "ignore"
- }
- ],
- "react/prop-types": [
- "error",
- {
- "ignore": ["children"]
- }
- ]
+ "consistent-return": ["error"],
+ "no-console": "off",
+ "no-inner-declarations": "off",
+ "prettier/prettier": "error",
+ "quotes": ["error", "backtick"],
+ "react/display-name": "off",
+ "react/jsx-key": "warn",
+ "react/no-unescaped-entities": "warn",
+ "react/prop-types": "off",
+ "require-jsdoc": "off",
+ "valid-jsdoc": "off"
},
"overrides": [
{
@@ -71,6 +57,18 @@
"___loader": false,
"___emitter": false
}
+ },
+ {
+ "files": ["**/cypress/integration/**/*", "**/cypress/support/**/*"],
+ "globals": {
+ "cy": false,
+ "Cypress": false
+ }
+ }
+ ],
+ "settings": {
+ "react": {
+ "version": "16.4.2"
}
- ]
+ }
}
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000000..a0e422d6c6037
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,4 @@
+**/*.js.snap text eol=lf
+**/__testfixtures__/** text eol=lf
+**/__tests__/fixtures/** text eol=lf
+**/*.md text eol=lf
\ No newline at end of file
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 0d1a73256da08..a4111dfee5abb 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,12 +1,6 @@
Belongs in the docs (to make sure we don’t have to maintain docs about core dependencies and third-party software, we will focus on linking to their docs as much as possible)
+
+> **No** --> Belongs in blog, marketing, Twitter, podcast, starter library, plugin library, etc.
+
+2. Helps further something on the [developer journey](https://pronovix.com/blog/analyzing-api-docs-and-dx-patterns-best-banking-developer-portals):
+
+ - Discover
+ - Evaluate
+ - Get Started
+ - Implement & Troubleshoot
+ - Celebrate & Share
+ - Contribute & Maintain
+
+> **Yes** --> Belongs in the docs
+
+> **No** --> Does not belong in the docs
+
+## Handling proposed doc changes
+
+### Someone wants to create a new doc
+
+Does doc already exist?
+
+> **Yes** --> Is there a discovery problem? If so, solve it
+
+> **No** --> move ahead
+
+Is there a demand to create the doc?
+
+> **Yes** --> move ahead
+
+> **No** --> don't create it
+
+Does the doc qualify to be in the /docs/?
+
+> **Yes** --> Create it
+
+> **No** --> Don't create it
+
+### Someone wants to create new categories in the docs sidebar
+
+Is there a category that the doc(s) could fit in that has more than 5-7 docs in it?
+
+> **Yes** --> Put in existing category
+
+> **No** --> Move on
+
+Would the new category have more than 2 docs in it?
+
+> **Yes** --> Create new category
+
+> **No** --> consider waiting to create the category until there is more than 2 docs
+
+### Someone wants to reorder the categories in the sidebar or shift docs to new categories
+
+Is there evidence that the reorganization would help further one of the steps on the developer journey?
+
+> **Yes** --> Reorder them and do usability testing to measure the value of the change
+
+> **No** --> Don't reorder the categories
+
+## Naming criteria
+
+Names categories in the .org site should:
+
+- be SEO-friendly (common google search term, easy-to-remember URL that is not likely to change anytime soon)
+- communicate a core concept of Gatsby (TBD) and/or a core value (TBD)
+- be a noun, like "plugins, styling, guides, core concepts" etc.
+
+Names for guides, tutorial sections, and sub-headings in the .org site should:
+
+- be SEO friendly (common google search term, easy-to-remember URL that is not likely to change anytime soon)
+- nearly always start with an -ing verb, like "adding", since all tasks are action-oriented.
+
+## Thanks and keep Hacktoberfesting with Gatsby
+
+It’s been incredible to see how many hard-working contributors have gotten PR’s merged with us so far! Don't forget to check out [how to participate in Gatsby Hacktoberfest!](/blog/2018-10-09-hacktoberfest-kickoff/)
+
+And don’t forget to also read the [Docs Decision Tree RFC](https://github.com/gatsbyjs/rfcs/pull/14) and leave your comments before October 31st, when the commenting period will be closed.
diff --git a/docs/blog/2018-10-15-beyond-static-intro/images/dynamic.jpg b/docs/blog/2018-10-15-beyond-static-intro/images/dynamic.jpg
new file mode 100644
index 0000000000000..498bdf59fedaa
Binary files /dev/null and b/docs/blog/2018-10-15-beyond-static-intro/images/dynamic.jpg differ
diff --git a/docs/blog/2018-10-15-beyond-static-intro/index.md b/docs/blog/2018-10-15-beyond-static-intro/index.md
new file mode 100644
index 0000000000000..32e787a8e3afa
--- /dev/null
+++ b/docs/blog/2018-10-15-beyond-static-intro/index.md
@@ -0,0 +1,61 @@
+---
+title: "Beyond Static: Building Dynamic Apps with Gatsby"
+date: 2018-10-15
+author: Dustin Schau
+image: images/dynamic.jpg
+showImageInArticle: false
+tags: ["apps", "beyond static", "webinar"]
+---
+
+We hear it regularly. Gatsby is for static sites, Next.js (or similar) is for when your data changes regularly and/or you need an "app." This raises a question... what actually _is_ an app?
+
+If this question interests you, consider attending [the upcoming webinar][webinar] where we'll focus on shedding some light on this very question as well as talk about how to build dynamic web apps with Gatsby.
+
+Until then, I’d like to offer some brief teasers of some of the content we’ll be discussing during the webinar and some introductory information in _how_ Gatsby enables app development.
+
+> My first impression of Gatsby is that it is more of a static site generator which I interpret as being aimed at content or marketing websites and not as focused on web apps. That is a complete assumption so please correct me if I am wrong.
+>
+> - [Triptcip][reddit-thread]
+
+## What is an app?
+
+It's surprisingly challenging to define what separates an app from a static site.
+
+- Authentication?
+- Reacting to remote data changes?
+- A shopping cart?
+
+It's surprisingly murky where that line is drawn and why exactly many seem to clearly delineate the two _separate_ concepts.
+
+In fact, I contend that the line between these two concepts is extremely blurry. There isn't some magic percentage threshold that, when crossed, indicates that a static site is now an application. Nor is the inverse true, that an "app" is somehow static because some percentage of its content never or rarely changes.
+
+From this perspective, it's fair to consider dynamic content as the key determinant between static sites and apps. The more dynamic content an application has, the more app-like that application feels. From this basis, Gatsby is an excellent choice because it enables dynamic functionality just as easily as it enables static site generation.
+
+## How does Gatsby enable app functionality?
+
+Gatsby is great for static sites and for truly maximizing performance, while also maintaining a great developer experience and enabling fast feature development with tools developers actually _want_ to use. React, GraphQL, headless CMSes, and the list goes on and on. We enable these, and more, in an easy-to-use package that gets blazing-fast performance, by _default_. It's possible you've heard us talk about these things before 😅 We've honed in on this message and initially focused on this core functionality of building static sites. However, that's only one side of the coin. Gatsby's flexibility and one of its **core** ideas enable building apps on top of this solid static base.
+
+### Hydration
+
+One of the central ideas of Gatsby is that we statically generate our HTML content--using React DOM server-side APIs. A less-often illustrated feature is that this static HTML content can then be _enhanced_ with client-side JavaScript via React hydration. The general approach is as follows:
+
+1. Build and render static HTML, creating content and pages with data injected at build time
+1. Invoke [ReactDOM.hydrate method][hydrate] to pick up just where we left our static HTML
+1. Transfer rendering to the [React reconciler][reconciler]
+
+It's this last phase that bridges the gap between static sites and full-fledged applications. In this phase you can make data calls, authenticate users, and perform all the app-like functionality you desire.
+
+It's really that easy.
+
+## Use cases
+
+Gatsby enables these hooks to deliver app-like functionality, just as it does for static site generation. However, it's not as clear when it makes sense to reach for something purely server rendered (Next.js, Nuxt, etc.) or a hybrid approach, like we offer in Gatsby. In the webinar, I'll go over a number of examples of various types of web apps, including e-commerce apps, apps which utilize authentication, and apps that connect to a remote data source (e.g. a GraphQL API), among others! You'll leave having a clear mental model of the types of apps that **you** can build with Gatsby.
+
+## Wrap Up
+
+If these briefly described topics and use cases sound interesting to you then please consider [signing up for the Webinar][webinar]. I can't wait to share some practical advice, excellent tooling, and a live demo to show you how you can #BuildWithGatsby in more ways than _just_ static. I hope to see you there!
+
+[reddit-thread]: https://www.reddit.com/r/reactjs/comments/992n2r/next_vs_gatsby/?st=jn6cojmr&sh=1a53fac1
+[webinar]: https://www.gatsbyjs.com/build-web-apps-webinar
+[hydrate]: https://reactjs.org/docs/react-dom.html#hydrate
+[reconciler]: https://reactjs.org/docs/reconciliation.html
diff --git a/docs/blog/2018-10-16-why-mobile-performance-is-crucial/index.md b/docs/blog/2018-10-16-why-mobile-performance-is-crucial/index.md
new file mode 100644
index 0000000000000..cb6a47cc3d678
--- /dev/null
+++ b/docs/blog/2018-10-16-why-mobile-performance-is-crucial/index.md
@@ -0,0 +1,164 @@
+---
+title: "Journey to the Content Mesh Part 4: Why Mobile Performance Is Crucial"
+author: "Sam Bhagwat"
+"date": 2018-10-16
+tags: ["content-mesh"]
+---
+
+_This is Part 4 of a series. Part 1 is_ [The Journey to a Content Mesh](/blog/2018-10-04-journey-to-the-content-mesh)_; Part 2 is_ [Unbundling of the CMS](/blog/2018-10-10-unbundling-of-the-cms)_; Part 3 is_ [The Rise of Modern Web Development](/blog/2018-10-11-rise-of-modern-web-development).
+
+Mobile traffic now makes up over half of all site visits, and more than half of mobile site visits are abandoned if a page takes [over 3 seconds to load](https://www.thinkwithgoogle.com/data-gallery/detail/mobile-site-abandonment-three-second-load/).
+
+With the Fortune 500 spending millions of marketing dollars on marketing initiatives aimed at driving traffic to their site, the business impact of bouncing visitors is clear -- [every 100ms of latency costs 1% of sales.](https://www.digitalrealty.com/blog/the-cost-of-latency/)
+
+Unfortunately, in practice, great performance is surprisingly hard to achieve -- average page load times _haven’t improved_ over several years of increasing connection speed.
+
+Why is that? Increased site complexity often distributes bottlenecks across multiple code points and teams of stakeholders. While performance checklists exist, they’ve ballooned to 40+ items -- making them costly and time-consuming for teams to implement.
+
+As Gatsby's co-founder Kyle Mathews likes to say (paraphrasing Tolstoy):
+
+> "All fast websites are alike, but all slow websites are slow in different ways."
+
+Ultimately, we’ll argue, performance must be solved _at the framework level_ -- that is, in the content mesh.
+
+## The rise of smartphone usage
+
+Between 2014 and 2017, mobile usage (including tablets) rose from 20% of site visits to 50% of site visits.
+
+
+
+
+Source: [StatCounter](http://gs.statcounter.com/platform-market-share/desktop-mobile-tablet/worldwide/2011)
+
+When smartphones were first created, the first key challenge of website teams was to offer a responsive version of their site that worked on mobile devices _at all._
+
+As mobile has grown to half of internet traffic, the key challenge has shifted to performance.
+
+## Faster connections haven’t translated to faster sites
+
+While average phone connection speed, as well as processing power, has increased over the last several years, sites haven’t gotten faster. In fact, load times **have increased**.
+
+Data from the HTTPArchive shows how long it's taken for the average page on the Internet to completely load all content (including images, script files, CSS files, etc.):
+
+
+
+Source: [HTTPArchive](https://httparchive.org/reports/loading-speed?start=2014_02_01&end=latest&view=list#ol)
+
+Why is that?
+
+Connection speeds for mobile device have increased, while Moore's Law has made devices faster. However, these speed dividends have been eaten up by two things.
+
+First, **[heavier page weights](https://www.keycdn.com/support/the-growth-of-web-page-size/)**.
+
+This has generally driven by increased page complexity driven by increased user expectations.
+
+Second, the **growing complexity of websites**. Non-critical images, CSS, JS libraries, and 3rd party tracking software will often unintentionally end up on the critical path to page load:
+
+- A marketing analyst drops a `