Next app
how to create project with TypeScript, Next, eslint, prettier, Storybook, Mui and translation
- create Next app
- eslint
- prettier
- vscode setting
- test
- storybook
- mui
- translation
reference
environment Version
Node 16.16.0
npm 8.11.0
1. create Next app
1 create your app
npx create-next-app --typescript [project-name]
2 show your app
npm run dev
2. eslint
edit ./.eslintrc.json
file
{
"extends": [
"next/core-web-vitals",
"plugin:import/recommended",
"plugin:import/warnings",
"prettier"
],
"rules": {
"import/order": [
"error",
{
"alphabetize": {
"order": "asc"
}
}
],
"semi": ["error", "always"]
}
}
more about eslint
3. prettier
1 install prettier
npm install --save-dev prettier
2 edit ./.prettierrc
file
{
"trailingComma": "all",
"tabWidth": 2,
"semi": false,
"singleQuote": true,
"jsxSingleQuote": true,
"printWidth": 100
}
3 edit script
of ./package.json
file
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint --dir src",
"lint:fix": "yarn lint --fix",
"format": "prettier --check --ignore-path .gitignore .",
"format:fix": "prettier --write --ignore-path .gitignore .",
},
more about prettier
4. VsCode setting
If you change VsCode setting, you can align format when you save
you need vscode extension(eslint, prettier)
- open
settings.json
file
open command palette(mac :cmd
+shift
+p
/ windows :ctrl
+shift
+p
)
typesettings.json
chooseOpen User Settings(JSON)
- add settings
(add setting tab size of typescript)
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"[typescript]": {
"editor.tabSize": 2
},
"[typescriptreact]": {
"editor.tabSize": 2
}
}
5. test
1 install Jest and React Testing Library
npm install --save-dev jest @testing-library/react @testing-library/jest-dom jest-environment-jsdom
2 create ./jest.setup.js
// Optional: configure or set up a testing framework before each test.
// If you delete this file, remove `setupFilesAfterEnv` from `jest.config.js`
// Used for __tests__/testing-library.js
// Learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom/extend-expect';
3 create ./jest.config.js
const nextJest = require('next/jest');
const createJestConfig = nextJest({
dir: './',
});
const customJestConfig = {
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
moduleDirectories: ['node_modules', '<rootDir>/'],
testEnvironment: 'jest-environment-jsdom',
};
module.exports = createJestConfig(customJestConfig);
4 create ./tests/index/index.test.tsx
import { render, screen } from '@testing-library/react';
import Home from '../../pages/index';
describe('Home', () => {
it('renders a heading', () => {
const { container } = render(<Home />);
const heading = screen.getByRole('heading', {
name: /welcome to next\.js!/i,
});
expect(heading).toBeInTheDocument();
expect(container).toMatchSnapshot();
});
});
5 edit script
of ./package.json
file
"scripts": {
(...)
"test": "jest --watch",
"test:ci": "jest --ci",
6 test
npm test
6. storybook
1 install storybook
npm install --save-dev sb
2 init storybook
npx sb init --builder webpack5
3 edit script
of ./package.json
file
"scripts": {
(...)
"storybook": "start-storybook -p 6006 -s ./public",
"build-storybook": "build-storybook -s public"
4 show storybook
npm run storybook
more about storybook
7. mui
install mui and emotion
npm install --save @mui/material @emotion/react @emotion/styled
more about mui
8. translation
1 install next/translation
npm install --save next-translate
2 edit ./next.config.js
file
add this
const nextTranslate = require('next-translate');
module.exports = nextTranslate();
3 create ./i18n.json
file
{
"locales": ["ja", "en"],
"defaultLocale": "en",
"localeDetection": false,
"pages": {
"*": ["common"]
}
}
4 create ./locales/en/common.json
file
{
"Japanese": "Japanese",
"English": "English",
}
5 create ./locales/ja/common.json
file
{
"Japanese": "日本語",
"English": "英語",
}
6 use translation
like this
import useTranslation from 'next-translate/useTranslation';
...
const { t } = useTranslation('common');
...
{t('Japanese')}