Razzle: Typescript์™€ ํ•จ๊ป˜ eslint๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์— ๋งŒ๋“  2019๋…„ 11์›” 12์ผ  ยท  11์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: jaredpalmer/razzle

razzle-eslint-plugin์„ ์ถ”๊ฐ€ํ•˜๊ณ  razzle.config.js์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํฌํ•จํ–ˆ์Šต๋‹ˆ๋‹ค.

plugins: ['scss', 'eslint']

๋ฌธ์ œ๋Š” ์ฝ˜์†”์ด typescript ํŒŒ์ผ์— ๋Œ€ํ•œ Lint ๊ฒฝ๊ณ ๋ฅผ ํ‘œ์‹œํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฝ˜์†”์—์„œ eslint๋ฅผ ์ˆ˜๋™์œผ๋กœ ์‹คํ–‰ํ•˜๋ฉด Lint ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋˜์ง€๋งŒ razzle start ์‹คํ–‰ ์ค‘์—๋Š” ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

razzle-eslint-plugin ์†Œ์Šค๋ฅผ ํ™•์ธํ•˜๋ฉด ๊ทœ์น™์ด ์•„๋ž˜์— ํ‘œ์‹œ๋œ๋Œ€๋กœ ํ™•์ธํ•  js ๋ฐ jsx ํŒŒ์ผ ๋งŒ ์–ธ๊ธ‰ํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 config.module.rules = [
    {
      test: /\.(js|jsx|mjs)$/,
      enforce: 'pre',
      loader: require.resolve('eslint-loader'),
      options: mainEslintOptions,
      exclude: /node_modules/,
    },
    ...config.module.rules,
  ]

์œ„์˜ ๊ตฌ์„ฑ์— ts|tsx ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์ฆ‰์‹œ ๊ฒฝ๊ณ ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ๋‚ด๊ฐ€ ํ”ผํ•˜๊ณ  ์‹ถ์€ node_modules ํŒŒ์ผ์„ ์ˆ˜๋™์œผ๋กœ ํŽธ์ง‘ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. razzle.config.js์—์„œ ๊ตฌ์„ฑ์„ ํ™•์žฅ ํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ? module.rules.push ํ†ตํ•ด ์ƒˆ ๊ทœ์น™์„ ํ‘ธ์‹œํ•˜๋ ค๊ณ ํ–ˆ์ง€๋งŒ These relative modules were not found: ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด razzle-eslint-plugin ์ถ”๊ฐ€๋˜์–ด์•ผํ•œ๋‹ค๋ฉด PR์„ ์˜ฌ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ œ์•ˆํ•˜์‹ญ์‹œ์˜ค

question stale

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

Tslint๋Š” 2019 ๋…„ ์–ธ์  ๊ฐ€ ESLint์—์„œ ์‚ฌ์šฉ์ด ์ค‘๋‹จ๋˜๊ณ  11 ์›” ์ค‘์ˆœ ์ฏค์ด๋ฏ€๋กœ razzle์€ ์•„๋งˆ๋„ ESLint๋กœ ์ „ํ™˜ ํ•  ๊ณ„ํš์„ ์„ธ์›Œ์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  11 ๋Œ“๊ธ€

razzle.config.js ํŒŒ์ผ์— ๋‹ค์Œ ์„ค์ •์„ ์ง€์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

'use strict'

module.exports = {
  plugins: [
    {
      name: 'typescript',
      options: {
        useBabel: true,
        useEslint: true,
        forkTsChecker: {
          tsconfig: './tsconfig.json',
          tslint: undefined,
          watch: './src',
          typeCheck: true
        }
      }
    }
  ]
}

๋‹ค์Œ๊ณผ ๊ฐ™์ด .eslintrc.json

{
  "extends": [
    "eslint:recommended",
    "prettier",
    "plugin:jsx-a11y/recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:react/recommended"
  ],
  "plugins": ["@typescript-eslint"],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 6,
    "sourceType": "module",
    "ecmaFeatures": {
      "modules": true,
      "jsx": true
    }
  },
  "env": {
    "browser": true,
    "node": true,
    "jest": true
  },
  "settings": {
    "react": {
      "version": "detect"
    },
    "import/resolver": {
      "node": {
        "extensions": [".js", ".jsx", ".ts", ".tsx"]
      }
    }
  }
}

๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‚ด package.json ์—์„œ ๋‹ค์Œ ํ–‰์— linting์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

"lint": "eslint --ext 'js,jsx,ts,tsx' .",

@andersnylund ์ž…๋ ฅ npm run lint ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋งŽ์€ Lint ๊ฒฝ๊ณ ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. CRA ํ”„๋กœ์ ํŠธ ์—์„œ์ฒ˜๋Ÿผ ์ฝ˜์†”์—์„œ ๋ฐ”๋กœ ๊ฒฝ๊ณ ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค๋ฉด ํ›จ์”ฌ ๋” ๋‚˜์€ ๊ฒฝํ—˜์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‚ด ํ˜„์žฌ ๊ตฌ์„ฑ์ž…๋‹ˆ๋‹ค.

const path = require('path')
module.exports = {
  plugins: ['scss', 'eslint'],
  modify(defaultConfig, { target, dev }, webpack) {
    const config = defaultConfig
    config.resolve.extensions.push('.ts', '.tsx')
    config.module.rules.push({
      test: /\.(ts|js)x?$/,
      exclude: /node_modules/,
      loader: 'babel-loader',
    })

    if (target === 'node' && !dev) {
      config.entry = path.resolve(__dirname, './src/server.tsx')
      config.output.filename = 'server.bundle.js'
      config.output.path = path.resolve(__dirname, './build')
      config.output.libraryTarget = 'commonjs2'
    }
    return config
  }
}

Tslint๋Š” 2019 ๋…„ ์–ธ์  ๊ฐ€ ESLint์—์„œ ์‚ฌ์šฉ์ด ์ค‘๋‹จ๋˜๊ณ  11 ์›” ์ค‘์ˆœ ์ฏค์ด๋ฏ€๋กœ razzle์€ ์•„๋งˆ๋„ ESLint๋กœ ์ „ํ™˜ ํ•  ๊ณ„ํš์„ ์„ธ์›Œ์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ์•„๋ž˜ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ˜์†”์—์„œ Typescript ์˜ค๋ฅ˜์™€ ESLint ๊ฒฝ๊ณ ๋ฅผ ๋ชจ๋‘ ์–ป์„ ์ˆ˜์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

const ForkTSCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
const path = require('path')

module.exports = {
  modify(defaultConfig, { target, dev }, webpack) {
    const config = defaultConfig
    config.resolve.extensions.push('.ts', '.tsx')
    config.plugins.push(
        new ForkTSCheckerWebpackPlugin({
          checkSyntacticErrors: true,
          eslint: true,
        }))
    config.module.rules.push({
      test: /\.(ts|js)x?$/,
      include: [path.resolve(__dirname, 'src')],
      loader: 'babel-loader',
    })
 }
}

๊ทธ๋ฆฌ๊ณ  typescript ํŒŒ์„œ๊ฐ€์žˆ๋Š” ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— .eslintrc ํŒŒ์ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

@ fifn2 @ aswin-s ๋ฌธ์ œ๋Š” razzle-plugin-typescript๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” Fork TS Checker Webpack ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์˜ค๋ž˜๋˜์—ˆ๊ณ  (v0.4.1) eslint๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. # 1174์—์„œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ์œ„ํ•ด PR์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

์ด PR์„ ์‚ฌ์šฉํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๊นŒ?

@ imagine10255 ์ด๊ฒƒ์€ PR์ด ์•„๋‹ˆ์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์„์œ„ํ•œ ๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๋‹ค

๋ช‡ ์ฃผ ์•ˆ์— typescript๋ฅผ ์ง€์›ํ•˜์—ฌ razzle-plugin-eslint ์˜ ์ƒˆ ๋ฒ„์ „์„ ์ถœ์‹œ ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

@ nimaa77 ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ typescript๋ฅผ ํ†ตํ•ฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋จผ์ € ์‚ฌ์šฉํ•  ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@ nimaa77 ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๋˜๋Š” ๋„์šธ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์ด๊ฒƒ์€ ๊ฐ€๋Šฅํ•˜๋‹ค. ์ด์ œ github ํ† ๋ก ์ด ํ™œ์„ฑํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ๋กœ ์ด๋™ํ•˜์‹ญ์‹œ์˜ค :) ๋˜ํ•œ ์ƒˆ๋กœ์šด typescript ํ”Œ๋Ÿฌ๊ทธ์ธ์€ eslint๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰

๊ด€๋ จ ๋ฌธ์ œ

howardya picture howardya  ยท  5์ฝ”๋ฉ˜ํŠธ

JacopKane picture JacopKane  ยท  3์ฝ”๋ฉ˜ํŠธ

MaxGoh picture MaxGoh  ยท  4์ฝ”๋ฉ˜ํŠธ

dizzyn picture dizzyn  ยท  3์ฝ”๋ฉ˜ํŠธ

kkarkos picture kkarkos  ยท  3์ฝ”๋ฉ˜ํŠธ