gatsby-starter-emotion-typescript-and-tests

A gatsby starter with emotion, jest / react-testing-library, and typescript enabled by default

MIT License

Stars
3
Committers
1

The purpose of this is to get quickly up and running with a Gatsby site using typescript, emotion, and jest / react-testing-library as well as Cypress (coming later).

I also wanted to keep it as close to the original gatsby starter as possible.

  • Node 12.13 (I have only tested this on 12.13, it could definitely work on lower versions)
  • Docker / Docker-Compose (Optional)
npx gatsby new <YourProjectName> https://github.com/ParamagicDev/gatsby-starter-emotion-typescript-and-tests.git
cd <YourProjectName>
docker-compose up --build

Navigate to localhost:8000 and you will see the site running! You can run the test suite in a seperate terminal and you can run:

docker-compose exec web npm run test # runs jest unit tests
docker-compose exec web npm run test:e2e:ci # runs cypress end to end testing
npm install -g gatsby-cli
gatsby new <YourProjectName> https://github.com/ParamagicDev/gatsby-starter-emotion-typescript-and-tests.git
cd <YourProjectName>
gatsby develop

Navigate to localhost:8000 to see your site running in browser.

To run the test suite:

npm run test

List of additional Gatsby Commands

npm run format

Uses prettier to auto fix .ts[x] .js[x] .json .md files

npm run lint

Lints all .ts[x] files via eslint

npm run type-check

Runs tsc on the project

npm run test Single run of the Jest test suite

npm run test:watch Only watch for changed files

npm run test:watchAll Rerun test suite on file changes

npm run test:e2e Runs Cypress in browser (Local development)

npm run test:e2e:ci Runs Cypress in a headless browser (CI/CD)

Routes are handled the same way as they are in the gatsby default starter.

Simply create a file in the src/pages directory.

IE:

src/pages/my-cool-route.tsx can be navigated via localhost:8000/my-cool-route

  • import x from "~" => import x from "./src"
  • import x from "~components" => import x from "./src/components"
  • import x from "~fixtures" => import x from "./__fixtures__/"

All components are .tsx files by default

Pages are written as .tsx files.

emotion.sh

Jest - jestjs.io

Jest tests are located in the ./__tests__ directory.

React-Testing-Library - https://testing-library.com/docs/react-testing-library/intro

Cypress - cypress.io

Cypress tests are located in the ./cypress directory.

Default Dockerfile and docker-compose.yml included

Gatsby uses react-helmet however, react-helmet uses "unsafe component lifecycles". There is a fork of react-helmet called react-helmet-async which solves the lifecycle method issue.

As a result, src/components/seo/index.tsx uses react-helmet-async.

To change an alias is quite a process. You must change 4 files:

gatsby-node.js

tsconfig.json

jest.config.js

eslintrc.js

Explanation:

gatsby-node.js will affect how gatsby aliases imports. If this is not set, Gatsby itself will throw an error about being unable to find the import.

tsconfig.json tells the typescript compiler where to find an aliased module. If this is not set properly, the typescript compiler will throw an error.

jest.config.js The moduleNameMapper API tells Jest where to import modules from inside of your testing environment. If this is not set properly, jest will throw an error inside of your tests.

eslintrc.js I have installed 2 packages:

eslint-plugin-import

and

eslint-import-resolver-alias

Both of the above are installed when you run npm install. These 2 plugins, combined with the aliases I have already mapped in .eslintrc.js allow you to be able have autocomplete in your text editor of choice if it integrates with eslint.

Here is how the modifications would take place:

// gatsby-node.js
const path = require("path");

exports.onCreateWebpackConfig = ({ actions }) => {
  actions.setWebpackConfig({
    resolve: {
      alias: {
        // Aliased paths go here
        "~$": path.resolve(__dirname, "src/"),
        "~fixtures": path.resolve(__dirname, "__fixtures__"),
      },
    },
  });
};

Further reading on gatsby-node aliased paths can be found here:

https://www.gatsbyjs.org/docs/api-files-gatsby-node/

// tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "~fixtures/*": ["__fixtures__/*"],
      "~*": ["src/*"]
    }
  }
}

"paths" is where you would place your aliases.

Further reading on tsconfig.json can be found here:

https://www.typescriptlang.org/docs/handbook/module-resolution.html

// jest.config.js
module.exports = {
  // ...
  moduleNameMapper: {
    // ...
    // Your aliases here
    "~fixtures(.*)": "<rootDir>/__fixtures__$1",
    "~(.*)$": "<rootDir>/src/$1",
  },
  // ...
};

Further reading on Jest module name mapping can be found here:

https://jestjs.io/docs/en/configuration#modulenamemapper-objectstring-string

// .eslintrc.js
module.exports = {
  // ...
  settings: {
    // ...
    "import/resolver": {
      // Aliases go here
      alias: [
        ["~fixtures", "./__fixtures__"],
        ["~", "./src/"],
      ],
    },
  },
  // ...
};

Further reading about how ESLint handles import can be found here:

https://github.com/johvin/eslint-import-resolver-alias#readme

  • Add Cypress
  • Add more detail to the readme as to capabilities.
  • Finish unit testing of components
  • Add E2E testing