A gatsby starter with emotion, jest / react-testing-library, and typescript enabled by default
MIT License
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.
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.
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:
and
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