Skip to content

Commit

Permalink
Merge branch 'typescript-cache-js-ts' of github.com:gatsbyjs/gatsby i…
Browse files Browse the repository at this point in the history
…nto typescript-cache-js-ts
  • Loading branch information
ascorbic committed Jan 16, 2020
2 parents d824c6c + e6ebadf commit 19a1fc0
Show file tree
Hide file tree
Showing 25 changed files with 371 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,17 @@ The exact implementation(s) we integrate into Gatsby will likely evolve as we tr
- Rendering an interactive UI control in each view that becomes visible when the user navigates through the app by keyboard.
- Making it function as a tab stop in a content region for keyboard users and providing a way to skip back to navigation so it is actually operable: a skip link is the most natural choice for this.
- Making the control small in width and height (like a link or icon button) so the focus outline and content aren’t cut off when zoomed way in.
- Putting an `aria-label` or `aria-labelledby` attribute with an indication of the nearby content (like a heading), and what action the control does. E.g. “Portfolio, skip back to navigation”. This would benefit from more user testing.
- Focusing this skip link when a user completes an action that triggers a route change and updates the client-rendered view, both managing focus and notifying users of assistive technology.
- ~~Putting an `aria-label` or `aria-labelledby` attribute with an indication of the nearby content (like a heading), and what action the control does. E.g. “Portfolio, skip back to navigation”. This would benefit from more user testing.~~

**Note:** The advice for labeling a skip link component which also serves as a focus management target has evolved since this article was initially published. Rather than compose a label "with nearby content" to both indicate the link action _and_ the current page on focus, a better approach would be to decouple the two so when the skip link is focused with a screen reader without a route change, its purpose would be more clear: "skip to navigation". Including an ARIA Live Region to make an announcement on route change would notify screen reader users and keep skip link text clear. This would serve assistive technology users with the necessary page and element focus context, while also supporting sighted and low-vision keyboard users.

The technique developed from this article was presented and tested again with Fable Tech Labs at the [Inclusive Design 24 virtual conference](https://www.youtube.com/watch?v=Tr21FqQQv-U) in October 2019. For an example of the most recent research in action, check out these [workshop materials](https://github.com/marcysutton/gatsby-a11y-workshop/blob/master/examples/client-side-routing/).

The advice now looks like this:

- Provide a skip link that takes focus on a route change within the site, with a label that indicates what the link will do when activated: e.g. "skip to main navigation".
- Include an [ARIA Live Region](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions) on page load. On a route change, append text to it indicating the current page, e.g. "Portfolio page".

Part of the challenge with this work is what might be ideal for one user with a disability might not be for another. These recommendations are an attempt at weaving multiple perspectives into one usable pattern, with the historical knowledge of where teams run into conflicts over accessibility in design (e.g. turning off visible focus outlines on container elements).

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ As part of its data layer and [build](#build) process, Gatsby will automatically

## J

### JAMStack
### [JAMStack](/docs/glossary/jamstack)

JAMStack refers to a modern web architecture using [JavaScript](#javascript), [APIs](#api), and ([HTML](#html)) markup. From [JAMStack.org](https://jamstack.org): "It’s a new way of building websites and apps that delivers better performance, higher security, lower cost of scaling, and a better developer experience."

Expand Down
39 changes: 39 additions & 0 deletions docs/docs/glossary/jamstack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: JAMStack
disableTableOfContents: true
---

Learn how to use Gatsby to build websites powered by the JAMStack, a modern architecture that uses JavaScript, APIs and markup without requiring the use of a database or server-side programming language.

## What is the JAMStack?

JAMStack is a modern architecture for building websites and applications. The _<abbr>JAM</abbr>_ in JAMStack stands for [JavaScript](/docs/glossary#javascript), [APIs](/docs/glossary#api), and HTML markup. Unlike websites built using WordPress or Drupal, JAMStack sites do not require a database. You can even skip the webserver, and opt to host your site using an object storage service and a content delivery network (or CDN).

With more traditional websites, such as those built using WordPress or Drupal, content is stored in a database. There's also a presentation layer of template files that mix HTML markup with template tags. Template tags are placeholders for pieces of content, e.g. `{{ title }}` for the title of the page.

A software layer then pulls it all together: it retrieves content from the database, replaces template tags with the appropriate chunks of content, and returns it all to the browser. A single page gets regenerated each time the server receives a request for that URL.

In this type of architecture, the [frontend](/docs/glossary#frontend) (what you see in the browser) and [backend](/docs/glossary#backend) (the database and software layer) are _tightly coupled_. Both the content and how it's presented are part of the same code base &mdash; sometimes called a _monolithic architecture_. Content is only available as HTML and can only be consumed by clients (e.g. web browsers) that can parse HTML.

In a JAMStack architecture, however, the frontend and backend are [decoupled](/docs/glossary#decoupled). A JAMStack frontend consists of JavaScript, HTML, and CSS. Gatsby generates these files during the [build](/docs/glossary#build) process.

A JAMStack backend is a content API that returns JSON or XML. This API can be a [hosted datastore](/docs/sourcing-from-hosted-services/), a [headless CMS](/docs/headless-cms/), or a custom application. It's only concerned with serving JSON or XML, which means you can use the same API for your Gatsby site and native applications.

### Advantages of a JAMStack architecture

JAMStack sites, such as those created with Gatsby, offer four key advantages over other web site architectures.

- **Speed**: JAMStack sites lack the overhead caused by software and database layers. As a result, they render and load more quickly than sites that use monolithic architectures.
- **Hosting flexibility**: Because they're static files, JAMStack sites can be hosted anywhere. You can use traditional web server software, such as Apache or Nginx. For the best performance and security, you can use an object storage service and content delivery network such as [Netlify](/docs/deploying-to-netlify), [Render](/docs/deploying-to-render), or Amazon Web Services' [S3 and Cloudfront](/docs/deploying-to-s3-cloudfront).
- **An improved developer experience**: Frontend developers can build sites without needing to know a server-side language. Backend developers can focus on building APIs. Decoupled development teams can work in parallel, allowing each team to focus on what they do best. Using a third-party [CMS](/docs/glossary#cms) service also means that your developer-operations team doesn't have to manage a separate stack for content.
- **Better security**: No database and no software layer means that JAMStack sites are not vulnerable to [SQL injection](https://www.owasp.org/index.php/SQL_Injection) or server-side [code injection](https://www.owasp.org/index.php/Code_Injection) attacks. Pages are compiled in advance, so they aren't at risk of a [server-side includes injection](<https://www.owasp.org/index.php/Server-Side_Includes_(SSI)_Injection>) attack. Hosting your site on a content delivery network offers protection from [denial of service](https://www.owasp.org/index.php/Denial_of_Service) attacks. Shifting to a JAMStack architecture limits or eliminates entire classes of vulnerabilities.

> **NOTE:** Gatsby and other JAMStack sites can still be affected by [cross-site scripting](https://www.owasp.org/index.php/Types_of_Cross-Site_Scripting) attacks. They can also be compromised if your API endpoints are compromised.
Using Gatsby can help you build faster, more secure websites, with search engine optimization and accessibility features already built in. See how Gatsby [compares](/features/) to other frameworks.

### Learn more about JAMStack architecture

- [JAMStack.org](https://jamstack.org/) website
- [JAMstack WTF](https://jamstack.wtf/), built with Gatsby
- [Deploying and Hosting](/docs/deploying-and-hosting/) from the Gatsby Docs
29 changes: 29 additions & 0 deletions docs/docs/sourcing-from-the-filesystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,35 @@ each time to re-run the query. You'll see something like this:
The result is an array of File "nodes" (node is a fancy name for an object in a
"graph"). Each File object has the fields you queried for.

If you have multiple sets of data, you can query specific ones by specifying the `name` property from the config object in the `gatsby-config.js` file. In this case, `name` is set to `src`.

```javascript:title=gatsby-config.js
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/src`,
name: `src`,
},
},
```

You can then update your query using `sourceInstanceName` and the value of the `name` property in a filter like so.

```graphql
{
allFile(filter: { sourceInstanceName: { eq: "src" } }) {
edges {
node {
relativePath
prettySize
extension
birthTime
}
}
}
}
```

## Transforming File nodes

Once files have been sourced, various "transformer" plugins in the Gatsby ecosystem can then be used to transform File nodes into various other types of data. For example, a JSON file can be sourced using `gatsby-source-filesystem`, and then the resulting File nodes can be transformed into JSON nodes using `gatsby-transformer-json`.
Expand Down
2 changes: 2 additions & 0 deletions docs/tutorial/part-one/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,8 @@ Then finally deploy your site by publishing the generated files to surge.sh.
surge public/
```

> Note that you will have to press the `enter` key after you see the `domain: some-name.surge.sh` information on your command-line interface.
Once this finishes running, you should see in your terminal something like:

![Screenshot of publishing Gatsby site with Surge](surge-deployment.png)
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/writing-documentation-with-docz.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ cd my-gatsby-site-with-docz
And install required packages:

```shell
npm install --save gatsby-theme-docz
npm install --save gatsby-theme-docz docz
```

Add `gatsby-theme-docz` under `plugins` in `gatsby-config.js`:
Expand Down
4 changes: 3 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ module.exports = {
},
},
collectCoverageFrom: coverageDirs,
reporters: [`default`].concat(useCoverage ? `jest-junit` : []),
reporters: process.env.CI
? [[`jest-silent-reporter`, { useDots: true }]]
: [`default`].concat(useCoverage ? `jest-junit` : []),
testEnvironment: `jest-environment-jsdom-fourteen`,
moduleFileExtensions: [`js`, `jsx`, `ts`, `tsx`, `json`],
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"jest-environment-jsdom-fourteen": "^0.1.0",
"jest-junit": "^6.4.0",
"jest-serializer-path": "^0.1.15",
"jest-silent-reporter": "^0.1.2",
"joi": "^14.3.1",
"js-yaml": "^3.13.1",
"lerna": "^3.19.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-plugin-sitemap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The options are as follows:
- `createLinkInHead` (boolean) Whether to populate the `<head>` of your site with a link to the sitemap.
- `serialize` (function) Takes the output of the data query and lets you return an array of sitemap entries.

We _ALWAYS_ exclude the following pages: `/dev-404-page/`,`/404` &`/offline-plugin-app-shell-fallback/`, this cannot be changed.
We _ALWAYS_ exclude the following pages: `/dev-404-page`,`/404` &`/offline-plugin-app-shell-fallback`, this cannot be changed.

Example:

Expand All @@ -50,7 +50,7 @@ plugins: [
// Exclude specific pages or groups of pages using glob parameters
// See: https://github.com/isaacs/minimatch
// The example below will exclude the single `path/to/page` and all routes beginning with `category`
exclude: ["/category/*", `/path/to/page`],
exclude: [`/category/*`, `/path/to/page`],
query: `
{
site {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const path = require(`path`)
const sitemap = require(`sitemap`)

const { onPostBuild } = require(`../gatsby-node`)
const internals = require(`../internals`)
import * as internals from "../internals"
const pathPrefix = ``

beforeEach(() => {
Expand Down
10 changes: 9 additions & 1 deletion packages/gatsby-plugin-sitemap/src/__tests__/internals.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,22 @@ describe(`results using default settings`, () => {
])
})

it(`excludes pages`, async () => {
it(`excludes pages without trailing slash`, async () => {
const graphql = () => Promise.resolve(generateQueryResultsMock())
const queryRecords = await runQuery(graphql, ``, [`/page-2`], pathPrefix)
const urls = serialize(queryRecords)

verifyUrlsExistInResults(urls, [`http://dummy.url${pathPrefix}/page-1`])
})

it(`excludes pages with trailing slash`, async () => {
const graphql = () => Promise.resolve(generateQueryResultsMock())
const queryRecords = await runQuery(graphql, ``, [`/page-2/`], pathPrefix)
const urls = serialize(queryRecords)

verifyUrlsExistInResults(urls, [`http://dummy.url${pathPrefix}/page-1`])
})

it(`should fail when siteUrl is not set`, async () => {
const graphql = () =>
Promise.resolve(generateQueryResultsMock({ siteUrl: null }))
Expand Down
5 changes: 4 additions & 1 deletion packages/gatsby-plugin-sitemap/src/internals.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ export const runQuery = (handler, query, excludes, pathPrefix) =>
r.data.allSitePage.edges = r.data.allSitePage.edges.filter(
page =>
!excludes.some(excludedRoute =>
minimatch(withoutTrailingSlash(page.node.path), excludedRoute)
minimatch(
withoutTrailingSlash(page.node.path),
withoutTrailingSlash(excludedRoute)
)
)
)

Expand Down
2 changes: 1 addition & 1 deletion packages/gatsby/src/query/query-compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const {

const getGatsbyDependents = require(`../utils/gatsby-dependents`)
const { store } = require(`../redux`)
const { actions } = require(`../redux/actions/internal`)
import * as actions from "../redux/actions/internal"
const { default: FileParser } = require(`./file-parser`)
const {
graphqlError,
Expand Down
2 changes: 1 addition & 1 deletion packages/gatsby/src/redux/actions/add-page-dependency.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { store } = require(`../`)
const { actions } = require(`./internal.js`)
import * as actions from "./internal"

function createPageDependency({ path, nodeId, connection }) {
const state = store.getState()
Expand Down
2 changes: 1 addition & 1 deletion packages/gatsby/src/redux/actions/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { bindActionCreators } = require(`redux`)
const { store } = require(`..`)

const { actions: internalActions } = require(`./internal`)
import * as internalActions from "./internal"
const { actions: publicActions } = require(`./public`)
const {
actions: restrictedActions,
Expand Down
Loading

0 comments on commit 19a1fc0

Please sign in to comment.