1. 1. Introduce Next.js 1. Introduce Next.js
    1. 1-1. Configure next.config.js 1-1. Configure next.config.js
  2. 2. Support TypeScript 2. Support TypeScript
    1. 2-1. Modify TypeScript configuration 2-1. Modify TypeScript configuration
    2. 2-2. Support TypeScript in src dir 2-2. Support TypeScript in src dir
  3. 3. Override App and Document components in Next.js 3. Override App and Document components in Next.js
    1. 3-1. Override App component 3-1. Override App component
    2. 3-2. Override Document component 3-2. Override Document component
  4. 4. Support PWA 4. Support PWA
    1. 4-1. Modify next.js configuration 4-1. Modify next.js configuration
    2. 4-2. Create manifest.json 4-2. Create manifest.json
    3. 4-3. Create favicon 4-3. Create favicon
  5. 5. Introduce Styled Component 5. Introduce Styled Component
    1. 5-1. Modify Babel configuration 5-1. Modify Babel configuration
    2. 5-2. Modify override of app component 5-2. Modify override of app component
  6. 5-3. Add to document component override 5-3. Add to document component override
    1. 5-4. Add sample code of Styled Component 5-4. Add sample code of Styled Component
  7. 6. Recoil 6. Recoil
    1. 6-1. Adding settings to app component 6-1. Adding settings to app component
    2. 6-2. Add sample code of Recoil 6-2. Add sample code of Recoil
  8. 7. Add EditorConfig / ESLint / Prettier 7. Add EditorConfig / ESLint / Prettier
    1. 7-1. Modify EditorConfig 7-1. Modify EditorConfig
    2. 7-2. Modify configuration of ESlint 7-2. Modify configuration of ESlint
    3. 7-3. Modify configuration of Prettier 7-3. Modify configuration of Prettier
    4. 7-3. Modify npm-scripts of package.json 7-3. Modify npm-scripts of package.json
  9. 8. Add Jest 8. Add Jest
    1. 8-1. Configure Jest 8-1. Configure Jest
    2. 8-2. create sample test 8-2. create sample test
    3. 8-3. Modify npm-scripts of package.json 8-3. Modify npm-scripts of package.json
  10. 9. Add Husky 9. Add Husky
    1. 9-1. Modify npm-scripts of package.json 9-1. Modify npm-scripts of package.json
  11. 10. Add react-aria and react-stately 10. Add react-aria and react-stately
  12. Conclution Conclution
質問
Here are the steps for building a front-end environment based on Next.js. We have chosen popular libraries as of September 2020 with the goal of being able to prototype efficiently.
Update: 

Here are the steps for building a front-end environment based on Next.js.
We have chosen popular libraries as of September 2020 with the goal of being able to prototype efficiently.
We will use the following as our primary libraries

1. Introduce Next.js

Please execute the following commands on your terminal:

# create project folder
mkdir PROJECT_NAME_DIR; cd PROJECT_NAME_DIR

# setup Next.js
npm init next-app .

# move pages to src/pages
mkdir src ; mv pages/ src/pages

# create configuration file for Next.js
touch next.config.js

1-1. Configure next.config.js

Configure next.config.js as follows:

/* eslint-disable
    @typescript-eslint/no-var-requires
*/

const { resolve } = require('path');

const nextConfig = {
  webpack: (config) => {
    // Set the src directory to the root of the alias
    config.resolve.alias['~'] = resolve(__dirname, 'src');
    return config;
  },
};

module.exports = nextConfig;
Write a comment

2. Support TypeScript

Please execute the following commands on your terminal to support TypeScript:

# install TypeScript libs
yarn add --dev typescript @types/react @types/react-dom @types/node

# create a configuration file for TypeScript
touch tsconfig.json

# automatically create some nessesary files with Next.js dev mode
yarn dev
# once it's generated, it's finished.

# convert js and jsx files to ts and tsx under the src directory
find src -name "*.js" | sed 'p;s/.js$/.tsx/' | xargs -n2 mv

2-1. Modify TypeScript configuration

Please modify tsconfig.json as follows:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "~/*": ["./src/*"]
    }
  }
}

2-2. Support TypeScript in src dir

Please modify src/pages/index.tsx as follows:

import React from 'react';

export default function Home(): ReactElement {
  return (
    <>
      <h1>My page</h1>
    </>
  );
}
Write a comment

3. Override App and Document components in Next.js

Please execute the following commands on your terminal:

# Create _app.tsx and _document.tsx
touch src/pages/_app.tsx && touch src/pages/_document.tsx

# Install sanitize.css
yarn add sanitize.css

3-1. Override App component

Please modify src/pages/_app.tsx as follows:

import * as React from 'react';
import App, { AppProps } from 'next/app';
import 'sanitize.css';

class MyApp extends App {
  render(): JSX.Element {
    const { Component, pageProps }: AppProps = this.props;

    return (
      <React.Fragment>
        <Component {...pageProps} />
      </React.Fragment>
    );
  }
}

export default MyApp;

3-2. Override Document component

Please modify src/pages/_document.tsx as follows:

import Document, { Html, Head, Main, NextScript } from 'next/document';
import {
  DocumentContext,
  DocumentInitialProps,
} from 'next/dist/next-server/lib/utils';

export default class MyDocument extends Document {
  render(): JSX.Element {
    return (
      <Html lang="ja">
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}
Write a comment

4. Support PWA

Please execute the following commands on your terminal:

# Install PWA module
yarn add next-pwa

4-1. Modify next.js configuration

Please modify next.config.js as follows:

/* eslint-disable
    @typescript-eslint/no-var-requires
*/

const { resolve } = require('path');
const withPWA = require('next-pwa');
const runtimeCaching = require('next-pwa/cache');

const nextConfig = {
  pwa: {
    dest: 'public',
    runtimeCaching,
  },
  webpack: (config) => {
    // set the src directory to the root of the alias
    config.resolve.alias['~'] = resolve(__dirname, 'src');
    return config;
  },
};

module.exports = withPWA(nextConfig);

4-2. Create manifest.json

Please create public/manifest.json by https://app-manifest.firebaseapp.com/.

Please execute the following commands on your terminal:

mkdir public && mkdir public/images

4-3. Create favicon

Create public/favicon.ico by https://favicon.io/.

Write a comment

5. Introduce Styled Component

Please execute the following commands on your terminal:

yarn add styled-components @babel/plugin-proposal-optional-chaining

touch babel.config.js

5-1. Modify Babel configuration

Please modify babel.config.js as follows:

// eslint-disable-next-line no-undef
module.exports = function (api) {
  api.cache(true);

  const presets = ['next/babel'];
  const plugins = [
    // eslint-disable-next-line no-undef
    [
      'styled-components',
      { displayName: process.env.NODE_ENV !== 'production', ssr: true },
    ],
    '@babel/plugin-proposal-optional-chaining',
  ];

  return {
    plugins,
    presets,
  };
};

5-2. Modify override of app component

Modify src/pages/_app.tsx as follows:

import * as React from 'react';
import App, { AppProps } from 'next/app';
import 'sanitize.css';
import { ThemeProvider } from 'styled-components';

const theme = {};

class MyApp extends App {
  render(): JSX.Element {
    const { Component, pageProps }: AppProps = this.props;

    return (
      <ThemeProvider theme={theme}>
        <Component {...pageProps} />
      </ThemeProvider>
    );
  }
}

export default MyApp;
Write a comment

5-3. Add to document component override

Add to src/pages/_document.tsx as follows:

import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheet } from 'styled-components';
import {
  DocumentContext,
  DocumentInitialProps,
} from 'next/dist/next-server/lib/utils';

export default class MyDocument extends Document {
  static async getInitialProps(
    ctx: DocumentContext
  ): Promise<DocumentInitialProps> {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            sheet.collectStyles(<App {...props} />),
        });

      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      };
    } finally {
      sheet.seal();
    }
  }

  render(): JSX.Element {
    return (
      <Html lang="ja">
        <Head>
          <link rel="shortcut icon" href="/favicon.png" />
          <link rel="manifest" href="/manifest.json" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

5-4. Add sample code of Styled Component

Add sample code of Styled Component to src/pages/index.tsx as follows:

import styled from 'styled-components';
import React from 'react';

export default function Home(): ReactElement {
  return (
    <>
      <Title>My page</Title>
    </>
  );
}

const Title = styled.h1`
  color: red;
  font-size: 50px;
`;
Write a comment

6. Recoil

Execute the following commands on your terminal:

# Install Recoil module
yarn add recoil

6-1. Adding settings to app component

Adding Recoil settings to src/pages/_app.tsx as follows:

import * as React from 'react';
import App, { AppProps } from 'next/app';
import 'sanitize.css';
import { RecoilRoot } from 'recoil';
import { ThemeProvider } from 'styled-components';

const theme = {};

class MyApp extends App {
  render(): JSX.Element {
    const { Component, pageProps }: AppProps = this.props;

    return (
      <RecoilRoot>
        <ThemeProvider theme={theme}>
          <Component {...pageProps} />
        </ThemeProvider>
      </RecoilRoot>
    );
  }
}

export default MyApp;

6-2. Add sample code of Recoil

Add sample code of Recoil to src/pages/index.tsx as follows:

import styled from 'styled-components';
import React, { ReactElement } from 'react';
import { atom, useRecoilState } from 'recoil';

const textState = atom({
  default: '', // default value (aka initial value)
  key: 'textState', // unique ID (with respect to other atoms/selectors)
});

export default function Home(): ReactElement {
  const [text, setText] = useRecoilState(textState);

  const onChange = (event: {
    target: { value: string | ((currVal: string) => string) };

  }) => {
    setText(event.target.value);
  };

  return (
    <>
      <Title>My page</Title>
      <input type="text" value={text} onChange={onChange} />
      <br />
      Echo: {text}
    </>
  );
}

const Title = styled.h1`
  color: red;
  font-size: 50px;
`;
Write a comment

7. Add EditorConfig / ESLint / Prettier

Execute the following commands on your terminal:

# Install Eslint and prettier module
yarn add --dev eslint eslint-plugin-react prettier eslint-config-prettier eslint-plugin-prettier

# Install Eslint with TypeScript
yarn add --dev @typescript-eslint/parser @typescript-eslint/eslint-plugin

# Create some configuration files for EditorConfig / ESLint / Prettier
touch .editorconfig && touch .eslintrc.js && touch .prettierrc.js

7-1. Modify EditorConfig

Modify .editorconfig as follows:

# editorconfig.org
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false

7-2. Modify configuration of ESlint

Modify .eslintrc.js as follows:

module.exports = {
  env: {
    browser: true,
    es6: true,
    jest: true,
    node: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:prettier/recommended',
    'prettier/@typescript-eslint',
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 2020,
    sourceType: 'module',
  },
  plugins: ['react', '@typescript-eslint'],
  rules: {
    '@typescript-eslint/ban-ts-ignore': 'off',
    eqeqeq: ['error', 'always', { null: 'ignore' }],
    'no-console': 'error',
    'no-debugger': 'error',
    'react/jsx-no-bind': [
      'error',
      {
        allowArrowFunctions: true,
        allowBind: false,
        allowFunctions: false,
        ignoreDOMComponents: false,
        ignoreRefs: false,
      },
    ],
    'react/prop-types': 'off',
    'react/react-in-jsx-scope': 'off',
    'sort-keys': [
      'error',
      'asc',
      { caseSensitive: true, minKeys: 2, natural: false },
    ],
  },
  settings: {
    react: {
      version: 'detect',
    },
  },
};

7-3. Modify configuration of Prettier

Modify .prettierrc.js as follows:

module.exports = {
  arrowParens: 'always',
  trailingComma: 'all',
};

7-3. Modify npm-scripts of package.json

Modify npm-scripts of package.json as follows:

{
  "scripts": {
    "eslint": "eslint src --ext .ts,.tsx,.js,.jsx --ignore-path .gitignore .",
    "eslint:fix": "yarn eslint --fix",
    "prettier": "prettier --write \"{,src//,public//}*.{js,jsx,ts,tsx,json,yaml,md}\" --ignore-path .gitignore"
  }
}
Write a comment

8. Add Jest

Execute the following commands on your terminal:

# install jest and related modules
yarn add --dev jest jest-dom jest-css-modules

# install typescript support of jest
yarn add --dev ts-jest @types/jest

# insall React Testing Library
yarn add --dev @testing-library/react

# create configuration files of Jest
touch jest.config.js && mkdir src/__tests__

# create a sample test file
touch src/__tests__/Sample.test.tsx

8-1. Configure Jest

Modify jest.config.js as follows:

module.exports = {
  globals: {
    // configuration to change some TypeScript settings at test time
    'ts-jest': {
      tsConfig: {
        jsx: 'react',
      },
    },
  },
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
  moduleNameMapper: {
    // prevent css files from being read during test
    '\\.css$': '<rootDir>/node_modules/jest-css-modules',
    // set the src directory to the root of the alias
    '^~/(.+)': '<rootDir>/src/$1',
  },
  preset: 'ts-jest',
  roots: ['<rootDir>/src'],
};

8-2. create sample test

Modify src/__tests__/Sample.tset.tsx as follows:

import * as React from 'react';
import { render, cleanup } from '@testing-library/react';
import Index from '~/pages/index';
import { RecoilRoot } from 'recoil';

afterEach(cleanup);

describe('Index page', (): void => {
  it('link to Next.js site', (): void => {
    const { getByText } = render(
      <RecoilRoot>
        <Index />
      </RecoilRoot>
    );
    expect(getByText('My page').getAttribute('class')).toBeDefined();
  });
});

8-3. Modify npm-scripts of package.json

Modify npm-scripts of package.json as follows:

{
  "scripts": {
    "test": "jest src/__tests__/.*/*.test.tsx?$"
  }
}
Write a comment

9. Add Husky

Execute the following commands on your terminal:

yarn add --dev husky

9-1. Modify npm-scripts of package.json

Modify npm-scripts of package.json as follows:

{
  "scripts": {
    "pre-commit": "yarn prettier --fix && yarn eslint:fix && yarn build"
  },
  "husky": {
    "hooks": {
      "pre-commit": "yarn pre-commit",
      "pre-push": "yarn test"
    }
  }
}
Write a comment

10. Add react-aria and react-stately

It is recommended to use react-aria and react-stately for the actual implementation of the UI. To help you separate the UI from the logic and to not have to worry about the behavioral differences between devices, we've provided a couple of mechanisms to help you use react-aria and react-stately.

Write a comment

Conclution

Happy Hacking!!

Write a comment
この記事が気に入ったら応援お願いします🙏
9
ツイート
LINE
Developer
Price Rank Dev
I use Next.js (React) and Firebase (Firestore / Auth) for development. We are also developing APIs for Ruby on Rails and GraphQL. Our team members are 6 Vietnamese and Japanese engineers.