[컴][웹][nodejs] TypeScript + ReacJS + Webpack + Jest


TypeScript +  ReactJS + Webpack + Jest

update, 2020-10

npx create-react-app my-app --typescript
를 이용하자. 
 
 

github



ReactJS 설정

directory 구조 만들기

아래와 같은 구조로 directory 를 만들자.
proj/
├─ dist/
└─ src/
   └─ components/

package.json 만들기


c:\proj>npm init

webpack 설치

c:\proj>npm install webpack --save-dev

ReactJS 설치

npm install --save react react-dom @types/react @types/react-dom
여기서 @types/ 은 react , react-dom 의 typescript 정의(declaration file) 가 들어있는 package 이다.

typescript 과 *-loader 설치

npm install --save-dev typescript awesome-typescript-loader source-map-loader



tsconfig.json

proj folder 에 tsconfig.json 을 만들어 놓자. tsconfig.json 은 아래처럼 하면 된다.
{
    "compilerOptions": {
        "outDir": "./dist/",
        "sourceMap": true,
        "noImplicitAny": true,
        "module": "commonjs",
        "target": "es5",
        "jsx": "react"
    },
    "include": [
        "./src/**/*"
    ],
    "exclude": [
        "**/*.test.tsx"
    ]
}

**/*.test.tsx 를 exclude 시켜놔야 나중에 jest 를 추가한 이후에도 build error 가 나지 않는다.

ts compile

아래처럼 하면 tsconfig.json 을 보고 compile option 을 정하고 compile 하게 된다. compile 이 끝나면 proj/dist 에 .js 가 만들어져 있을 것이다.
c:\proj>node .\node_modules\typescript\bin\tsc -p .



Webpack 설정

webpack.config.js

module.exports = {
    entry: "./src/index.tsx",
    output: {
        filename: "bundle.js",
        path: __dirname + "/dist"
    },

    // Enable sourcemaps for debugging webpack's output.
    devtool: "source-map",

    resolve: {
        // Add '.ts' and '.tsx' as resolvable extensions.
        extensions: [".ts", ".tsx", ".js", ".json"]
    },

    module: {
        rules: [
            // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
            { test: /\.tsx?$/, loader: "awesome-typescript-loader" },

            // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
            { enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
        ]
    },

    // When importing a module whose path matches one of the following, just
    // assume a corresponding global variable exists and use that instead.
    // This is important because it allows us to avoid bundling all of our
    // dependencies, which allows browsers to cache those libraries between builds.
    externals: {
        "react": "React",
        "react-dom": "ReactDOM"
    },
};

externals 로 react, react-dom 을 했기 때문에, 추후에 사용할 때는 react, react-dom 은 script tag 로 불러와야 한다.

webpack 실행

c:\proj>.\node_modules\.bin\webpack.cmd



Jest 사용하기, test framework

jest, ts-jest, enzyme, react-test-renderer 가 필요하다. 아래 명령어를 실행하면 된다.
c:\> npm install --save-dev jest ts-jest enzyme react-test-renderer 


package.json 에 jest 관련 설정 추가

package.json 에 npm test 를 실행하면 jest 를 실행하도록 설정해준다.
{
  "scripts": {
    "test": "jest"
  },
  ...
  "jest": {
    "transform": {
      ".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
    },
    "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js"
    ]
  }
   ...
}

npm test

npm test 를 하면 __tests__ 나 __spec__ 폴더 안의 test 파일들 실행하게 된다.
c:\> npm test

test 작성법

<Hello.tsx>
import * as React from "react";

export interface HelloProps { compiler: string; framework: string; }

// 'HelloProps' describes the shape of props.
// State is never set so we use the 'undefined' type.
export default class Hello extends React.Component<HelloProps, undefined> {
    render() {
        return <h1>Hello from {this.props.compiler} and {this.props.framework}!</h1>;
    }
}

<__tests__/Hello.test.tsx>
import * as React from 'react';
import {shallow} from 'enzyme';

import Hello from '../Hello'


describe('A suite', ()=>{
    it("test hello", ()=>{
        console.log('test');

        const wrapper = shallow(
            <Hello compiler="my compiler" framework='framework' />
        );
        
        expect(
            wrapper.contains(<h1>Hello from my compiler and framework!</h1>)
        ).toBe(true)
    });

})



css loader - typings-for-css-modules-loader

typings-for-css-modules-loader 를 사용해서 tsx 에서 style-loader 를 사용할 수 있다. 방법은 아래 경로를 이용하자.

.css import

.css 를 import 할 때 : How to use css-modules with other global css (discussion please don't merge it) by lapanoid · Pull Request #65 · css-modules/css-modules · GitHub

module: {
    rules: [
      { 
        test: /globalCss\.css$/,
        use:[
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
            }
          }
        ],
      },
      { 
        test: /\.css$/,
        exclude: [
          path.resolve(__dirname, "src/components/common/globalCss.css"),
        ],
        use:[
          {
            loader: 'style-loader'
          },
          {
            // loader: 'css-loader',
            loader: 'typings-for-css-modules-loader',
            options: {
              modules: true,
              importLoaders: 1,
              localIdentName: '[name]__[local]___[hash:base64:5]',
              namedExport: true,
              camelCase: true,
            }
          }
        ],
      },
      { 
        test: /\.scss$/,
        use: [{
            loader: "style-loader" // creates style nodes from JS strings
        }, {
            loader: "typings-for-css-modules-loader", // translates CSS into CommonJS
            options: {
              modules: true,
              importLoaders: 1,
              localIdentName: '[name]__[local]___[hash:base64:5]',
              namedExport: true,
              // camelCase: true,
            }
        }, {
            loader: "sass-loader" // compiles Sass to CSS
        }]
      },
      ..
    ]
}



References

  1. React & Webpack · TypeScript
  2. GitHub - kulshekhar/ts-jest: A preprocessor with sourcemap support to help use Typescript with Jest


댓글 없음:

댓글 쓰기