setting
λ Έλ νλ‘μ νΈμ μμ
npm init
리μνΈ , 리μνΈλ₯Ό μΉμμ κ·Έλ €μ€ λ¦¬μνΈλ μ€μΉ
npm i react react-dom
νμ μ€ν¬λ¦½νΈ μ€μΉ
npm i typescript
eslint μ€μΉ (μ½λ κ²μ¬λꡬ [μ€ν,μμ°λλ³μ...])
npm i -D eslint
ν리ν°μ΄ μ€μΉ (μ½λ μ λ ¬λꡬ) , eslint μ ν리ν°μ΄ μ°κ²° νλ¬κ·ΈμΈ μ€μΉ
npm i -D prettier eslint-plugin-prettier eslint-config-prettier
ν리ν°μ΄ μ€μ νμΌ .prettierrc μ΅μμν΄λ νμμμ±
{
"printWidth": 80, //νμ€ μ΅λκΈμμ
"tabWidth": 2,
"singleQuote": true, //μμλ°μ΄ν
"trailingComma": "all", //μ½€λ§λ€μ
"semi": true
}
eslint μ€μ νμΌ .eslintrc μ΅μμν΄λ νμμμ±
{
"extends": ["plugin:prettier/recommended"]
}
ts μ€μ μ μν tsconfig.json μ΅μμν΄λ νμμμ±
{
"compilerOptions": {
"esModuleInterop": true, //import * as (x)
"sourceMap": true, //λ°νμμμ μλ¬ μμΉ μ°Ύμμ€
"lib": ["ES2020", "DOM"],
"jsx": "react",
"module": "esnext",
"moduleResolution": "Node",
"target": "es5",
"strict": true, // any νμ
λ°©μ§
"resolveJsonModule": true,
"baseUrl": ".",
"paths": { // import ../../../ => @src/...
"@hooks/*": ["hooks/*"],
"@components/*": ["components/*"],
"@layouts/*": ["layouts/*"],
"@pages/*": ["pages/*"],
"@utils/*": ["utils/*"],
"@typings/*": ["typings/*"]
}
},
//webpack μ΄ ts λ₯Ό μΈμνκΈ°μν μ½λ
"ts-node": {
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "Node",
"target": "es5",
"esModuleInterop": true
}
}
}
webpack
webpack κ΄λ ¨ μ€μ npm λ€μ΄
npm i -D webpack @babel/core babel-loader @babel/preset-env @babel/preset-react
webpack κ΄λ ¨ TypeScript μ€μ λ€μ΄
npm i -D @types/webpack @types/node @babel/preset-typescript
npm i ts-node
webpack κ΄λ ¨ css loader λ€μ΄
npm i style-loader css-loader
webpack μ€μ μ μν webpack.config.ts μ΅μμν΄λ νμμμ±(jsλ νμ₯μ ts->js)
ππ»ββοΈ webpack.config.ts => λ
Έλ λ°νμμ μ€νλλ€
import path from 'path';
import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin';
import webpack, { Configuration as WebpackConfiguration } from "webpack";
import { Configuration as WebpackDevServerConfiguration } from "webpack-dev-server";
interface Configuration extends WebpackConfiguration {
devServer?: WebpackDevServerConfiguration;
}
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
const isDevelopment = process.env.NODE_ENV !== 'production';
const config: Configuration = {
name: 'μ¬μ©μ λͺ
λͺ
',
mode: isDevelopment ? 'development' : 'production',
devtool: !isDevelopment ? 'hidden-source-map' : 'eval',
resolve: {
//λ°λ²¨μ΄ μ²λ¦¬ν νμ₯μ λͺ©λ‘
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
alias: {
'@hooks': path.resolve(__dirname, 'hooks'),
'@components': path.resolve(__dirname, 'components'),
'@layouts': path.resolve(__dirname, 'layouts'),
'@pages': path.resolve(__dirname, 'pages'),
'@utils': path.resolve(__dirname, 'utils'),
'@typings': path.resolve(__dirname, 'typings'),
},
},
//κ²°κ³Όλ¬Ό μ΄λ¦ './client
entry: {
app: './client',
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
targets: { browsers: ['IE 10'] },
debug: isDevelopment,
},
],
'@babel/preset-react',
'@babel/preset-typescript',
],
env: {
development: {
plugins: [require.resolve('react-refresh/babel')],
},
},
},
exclude: path.join(__dirname, 'node_modules'),
},
{
test: /\.css?$/,
use: ['style-loader', 'css-loader'],
},
],
},
plugins: [
new ForkTsCheckerWebpackPlugin({
async: false,
// eslint: {
// files: "./src/**/*",
// },
}),
new webpack.EnvironmentPlugin({ NODE_ENV: isDevelopment ? 'development' : 'production' }),
],
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js',
publicPath: '/dist/',
},
devServer: {
historyApiFallback: true, // react router
port: 3090,
devMiddleware: { publicPath: '/dist/' },
static: { directory: path.resolve(__dirname) },
},
};
if (isDevelopment && config.plugins) {
config.plugins.push(new webpack.HotModuleReplacementPlugin());
config.plugins.push(new ReactRefreshWebpackPlugin());
}
if (!isDevelopment && config.plugins) {
}
export default config;
package.json
{
"name": "settings",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack serve --env development",
"build": "cross-env NODE_ENV=production webpack"
},
"author": "ZeroCho",
"license": "MIT",
"dependencies": {
"@types/react": "^17.0.2",
"@types/react-dom": "^17.0.1",
"ajv": "^8.11.0",
"axios": "^0.26.1",
"core-js": "^3.15.1",
"cross-env": "^7.0.3",
"react": "^17.0.1",
"react-dom": "^17.0.2",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"typescript": "^4.4.2"
},
"devDependencies": {
"@babel/core": "^7.13.8",
"@babel/preset-env": "^7.13.8",
"@babel/preset-react": "^7.12.13",
"@babel/preset-typescript": "^7.13.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.9",
"@types/fork-ts-checker-webpack-plugin": "^0.4.5",
"@types/node": "^16.11.26",
"@types/react-router-dom": "^5.1.7",
"@types/webpack": "^5.28.0",
"@types/webpack-dev-server": "^4.0.3",
"babel-loader": "^8.2.2",
"css-loader": "^6.2.0",
"eslint": "^8.13.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-prettier": "^4.0.0",
"fork-ts-checker-webpack-plugin": "^7.2.3",
"prettier": "^2.2.1",
"react-refresh": "^0.12.0",
"style-loader": "^3.2.1",
"ts-node": "^10.9.1",
"webpack": "^5.24.2",
"webpack-cli": "^4.5.0",
"webpack-dev-server": "^4.11.1"
}
}
directory file μ€μ
(μλ¨ λλ ν 리 μ΄λ―Έμ§μ°Έμ‘°)
μ΅μμ index.html νμΌ μμ±
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>hello world</title>
</head>
<body>
<div id="app"></div>
<script src="/dist/app.js"></script>
</body>
</html>
μ΅μμ νμ src/index.tsx νμΌ μμ±
import React from 'react';
import {render} from 'react-dom';
import App from './layout/App'
render (<App/>, document.querySelector('#app'));
μ΅μμ νμ layout λλ ν 리μμ± layout/App.tsx νμΌ μμ±
import React from 'react';
const App = () => {
return <div>setting</div>;
};
export default App;
link
νκ²½μ€μ μ΄ν΄λ₯Ό λνμ£Όλ λ§ν¬
- νλ‘ νΈμλ λΉλ μμ€ν : https://www.hyojae.info/db57bc7b-0fbd-46bc-a71b-e45bcbfad26e