├── .babelrc ├── .gitignore ├── README.md ├── config └── webpack.config.js ├── package.json ├── postcss.config.js ├── public └── index.html ├── src ├── App.css ├── App.js ├── index.js └── vp.png └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-react"] 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-skeleton-2018 2 | 3 | 2018년에 Babel7 과 Webpack 4 를 사용해서 리액트 프로젝트를 0부터 만든다면? 4 | 5 | 차근차근 해봅시다. 어렵지 않아요. 6 | 7 | ## 1. 디렉토리 생성 8 | 9 | ``` 10 | $ mkdir react-skeleton-2018 11 | $ cd react-skeleton-2018 12 | $ yarn init 13 | ``` 14 | 15 | ## 2. 웹팩 설치 16 | 17 | ``` 18 | $ yarn add --dev webpack webpack-cli 19 | ``` 20 | 21 | 22 | ## 3. babel 관련 모듈 설치 23 | ``` 24 | $ yarn add --dev @babel/core babel-loader @babel/preset-env @babel/preset-react 25 | ``` 26 | 27 | ## 4. .babelrc 파일 생성 28 | ```json 29 | { 30 | "presets": ["@babel/preset-env", "@babel/preset-react"] 31 | } 32 | ``` 33 | 34 | ## 5. webpack.config.js 작성 35 | 36 | #### config/webpack.config.js 37 | ```javascript 38 | module.exports = { 39 | module: { 40 | rules: [ 41 | { 42 | test: /\.js$/, 43 | exclude: /node_modules/, 44 | use: { 45 | loader: 'babel-loader' 46 | } 47 | } 48 | ] 49 | } 50 | }; 51 | ``` 52 | 53 | ## 6. scripts 추가 54 | #### package.json 55 | ``` 56 | "scripts": { 57 | "build": "webpack --mode production --config ./config/webpack.config.js" 58 | } 59 | ``` 60 | 61 | ## 7. 리액트 라이브러리 설치 62 | ``` 63 | $ yarn add react react-dom 64 | ``` 65 | 66 | ## 8. 컴포넌트 만들기 67 | #### src/App.js 68 | ```javascript 69 | import React from 'react'; 70 | 71 | const App = () => { 72 | return ( 73 |
74 |

React Skeleton 2018

75 |

되게 달라졌다...

76 |
77 | ); 78 | }; 79 | 80 | export default App; 81 | ``` 82 | 83 | ## 9. 엔트리 파일 (index.js) 작성 84 | #### src/index.js 85 | ```javascript 86 | import App from './App'; 87 | import ReactDOM from 'react-dom'; 88 | import React from 'react'; 89 | 90 | const rootEl = document.getElementById('root'); 91 | 92 | ReactDOM.render(, rootEl); 93 | ``` 94 | 95 | ## 10. html 파일 작성 96 | #### public/index.html 97 | ```html 98 | 99 | 100 | 101 | 102 | 103 | React Skeleton 2018 104 | 105 | 106 |
107 | 108 | 109 | ``` 110 | 111 | ## 11. html-loader 및 HtmlWebpackPlugin 설정 112 | ``` 113 | $ yarn add --dev html-webpack-plugin html-loader 114 | ``` 115 | 116 | #### config/webpack.config.js 117 | ```javascript 118 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 119 | 120 | module.exports = { 121 | module: { 122 | rules: [ 123 | { 124 | test: /\.js$/, 125 | exclude: /node_modules/, 126 | use: { 127 | loader: 'babel-loader' 128 | } 129 | }, 130 | { 131 | test: /\.html$/, 132 | use: [ 133 | { 134 | loader: "html-loader" 135 | } 136 | ] 137 | } 138 | ] 139 | }, 140 | plugins: [ 141 | new HtmlWebpackPlugin({ 142 | template: "./public/index.html", 143 | filename: "./index.html" 144 | }) 145 | ] 146 | }; 147 | ``` 148 | 149 | 이제 한번 빌드 해보세요 150 | 151 | ``` 152 | $ yarn build 153 | ``` 154 | 155 | ## 12. 개발서버 설정 156 | 157 | ``` 158 | $ yarn add --dev webpack-dev-server 159 | ``` 160 | 161 | 그리고 start 스크립트 추가 162 | 163 | #### package.json 164 | ```javascript 165 | "scripts": { 166 | "build": "webpack --mode production --config ./config/webpack.config.js", 167 | "start": "webpack-dev-server --config ./config/webpack.config.js --open --mode development --port 3000" 168 | } 169 | ``` 170 | 171 | 다음 명령어를 입력하면 개발서버가 뜹니다. 172 | ``` 173 | $ yarn start 174 | ``` 175 | 176 | ## 13. CSS 가 쓰고싶다! 177 | ``` 178 | $ yarn add --dev css-loader style-loader postcss-loader postcss-preset-env cssnano 179 | ``` 180 | 181 | #### postcss.config.js 182 | ```javascript 183 | module.exports = { 184 | plugins: { 185 | "postcss-preset-env": {}, 186 | cssnano: {} 187 | } 188 | } 189 | ``` 190 | 191 | #### config/webpack.config.js 192 | ```javascript 193 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 194 | 195 | module.exports = { 196 | module: { 197 | rules: [ 198 | { 199 | test: /\.js$/, 200 | exclude: /node_modules/, 201 | use: { 202 | loader: 'babel-loader' 203 | } 204 | }, 205 | { 206 | test: /\.html$/, 207 | use: [ 208 | { 209 | loader: "html-loader" 210 | } 211 | ] 212 | }, 213 | { 214 | test: /\.css$/, 215 | use: [ 216 | 'style-loader', 217 | 'css-loader', 218 | ] 219 | } 220 | ] 221 | }, 222 | plugins: [ 223 | new HtmlWebpackPlugin({ 224 | template: "./public/index.html", 225 | filename: "./index.html" 226 | }) 227 | ] 228 | }; 229 | ``` 230 | 231 | #### src/App.css 232 | ```css 233 | .App { 234 | background: black; 235 | padding: 1rem; 236 | color: white; 237 | } 238 | ``` 239 | #### src/App.js 240 | ```javascript 241 | import React from 'react'; 242 | import './App.css'; 243 | 244 | const App = () => { 245 | return ( 246 |
247 |

React Skeleton 2018

248 |

되게 달라졌다...

249 |
250 | ); 251 | }; 252 | 253 | export default App; 254 | ``` 255 | 256 | ### 14. mini-css-extract-plugin 적용 257 | 258 | CSS 를 따로 파일로 추출하고싶다면 이 라이브러리를 사용하세요 259 | 260 | 이전에 사용하던 extract-text-webpack-plugin 는 webpack v4 에서 작동하지 않아요. 261 | 262 | ``` 263 | yarn add --dev mini-css-extract-plugin 264 | ``` 265 | 266 | #### config/webpack.config.js 267 | ```javascript 268 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 269 | const MiniCssExtractPlugin = require("mini-css-extract-plugin"); 270 | 271 | module.exports = { 272 | module: { 273 | rules: [ 274 | { 275 | test: /\.js$/, 276 | exclude: /node_modules/, 277 | use: { 278 | loader: 'babel-loader' 279 | } 280 | }, 281 | { 282 | test: /\.html$/, 283 | use: [ 284 | { 285 | loader: "html-loader" 286 | } 287 | ] 288 | }, 289 | { 290 | test: /\.css$/, 291 | use: [ 292 | 'style-loader', 293 | { 294 | loader: MiniCssExtractPlugin.loader 295 | }, 296 | { loader: 'css-loader', options: { importLoaders: 1 } }, 297 | 'postcss-loader' 298 | ] 299 | } 300 | ] 301 | }, 302 | plugins: [ 303 | new HtmlWebpackPlugin({ 304 | template: "./public/index.html", 305 | filename: "./index.html" 306 | }), 307 | new MiniCssExtractPlugin({ 308 | filename: "[name].css", 309 | chunkFilename: "[id].css" 310 | }) 311 | ] 312 | }; 313 | ``` 314 | 315 | 316 | ### 15. 파일을 불러올까? 317 | 318 | ``` 319 | $ yarn add --dev file-loader 320 | ``` 321 | 322 | #### config/webpack.config.js 323 | ```javascript 324 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 325 | const MiniCssExtractPlugin = require("mini-css-extract-plugin"); 326 | 327 | module.exports = { 328 | module: { 329 | rules: [ 330 | { 331 | test: /\.js$/, 332 | exclude: /node_modules/, 333 | use: { 334 | loader: 'babel-loader' 335 | } 336 | }, 337 | { 338 | test: /\.html$/, 339 | use: [ 340 | { 341 | loader: "html-loader" 342 | } 343 | ] 344 | }, 345 | { 346 | test: /\.css$/, 347 | use: [ 348 | 'style-loader', 349 | { 350 | loader: MiniCssExtractPlugin.loader 351 | }, 352 | { loader: 'css-loader', options: { importLoaders: 1 } }, 353 | 'postcss-loader' 354 | ] 355 | }, 356 | { 357 | test: /\.(png|jpg|gif|svg)$/, 358 | use: [ 359 | { 360 | loader: 'file-loader', 361 | options: { 362 | } 363 | } 364 | ] 365 | } 366 | ] 367 | }, 368 | plugins: [ 369 | new HtmlWebpackPlugin({ 370 | template: "./public/index.html", 371 | filename: "./index.html" 372 | }), 373 | new MiniCssExtractPlugin({ 374 | filename: "[name].css", 375 | chunkFilename: "[id].css" 376 | }) 377 | ] 378 | }; 379 | ``` 380 | 381 | src 디렉토리에 이미지 다운로드 382 | 383 | ``` 384 | $ cd src 385 | $ curl https://avatars0.githubusercontent.com/u/17202261\?s\=460\&v\=4 -o vp.png 386 | ``` 387 | 388 | #### src/App.js 389 | ```javascript 390 | import React from 'react'; 391 | import vp from './vp.png'; 392 | import './App.css'; 393 | 394 | const App = () => { 395 | return ( 396 |
397 |

React Skeleton 2018

398 |

되게 달라졌다...

399 | 400 |
401 | ); 402 | }; 403 | 404 | export default App; 405 | ``` -------------------------------------------------------------------------------- /config/webpack.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 2 | const MiniCssExtractPlugin = require("mini-css-extract-plugin"); 3 | 4 | module.exports = { 5 | module: { 6 | rules: [ 7 | { 8 | test: /\.js$/, 9 | exclude: /node_modules/, 10 | use: { 11 | loader: 'babel-loader' 12 | } 13 | }, 14 | { 15 | test: /\.html$/, 16 | use: [ 17 | { 18 | loader: "html-loader" 19 | } 20 | ] 21 | }, 22 | { 23 | test: /\.css$/, 24 | use: [ 25 | 'style-loader', 26 | { 27 | loader: MiniCssExtractPlugin.loader 28 | }, 29 | { loader: 'css-loader', options: { importLoaders: 1 } }, 30 | 'postcss-loader' 31 | ] 32 | }, 33 | { 34 | test: /\.(png|jpg|gif|svg)$/, 35 | use: [ 36 | { 37 | loader: 'file-loader' 38 | } 39 | ] 40 | } 41 | ] 42 | }, 43 | plugins: [ 44 | new HtmlWebpackPlugin({ 45 | template: "./public/index.html", 46 | filename: "./index.html" 47 | }), 48 | new MiniCssExtractPlugin({ 49 | filename: "[name].css", 50 | chunkFilename: "[id].css" 51 | }) 52 | ] 53 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-skeleton-2018", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "devDependencies": { 7 | "@babel/core": "^7.0.0", 8 | "@babel/preset-env": "^7.0.0", 9 | "@babel/preset-react": "^7.0.0", 10 | "babel-loader": "^8.0.0", 11 | "css-loader": "^1.0.0", 12 | "cssnano": "^4.1.0", 13 | "file-loader": "^2.0.0", 14 | "html-loader": "^0.5.5", 15 | "html-webpack-plugin": "^3.2.0", 16 | "mini-css-extract-plugin": "^0.4.2", 17 | "postcss-import": "^12.0.0", 18 | "postcss-loader": "^3.0.0", 19 | "postcss-preset-env": "^5.3.0", 20 | "style-loader": "^0.23.0", 21 | "sugarss": "^2.0.0", 22 | "webpack": "^4.17.1", 23 | "webpack-cli": "^3.1.0", 24 | "webpack-dev-server": "^3.1.7" 25 | }, 26 | "dependencies": { 27 | "react": "^16.4.2", 28 | "react-dom": "^16.4.2" 29 | }, 30 | "scripts": { 31 | "build": "webpack --mode production --config ./config/webpack.config.js", 32 | "start": "webpack-dev-server --config ./config/webpack.config.js --open --mode development --port 3000" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | "postcss-preset-env": {}, 4 | cssnano: {} 5 | } 6 | } -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React Skeleton 2018 7 | 8 | 9 |
10 | 11 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | background: black; 3 | padding: 1rem; 4 | color: white; 5 | } -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import vp from './vp.png'; 3 | import './App.css'; 4 | 5 | const App = () => { 6 | return ( 7 |
8 |

React Skeleton 2018

9 |

되게 달라졌다...

10 | 11 |
12 | ); 13 | }; 14 | 15 | export default App; -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import App from './App'; 2 | import ReactDOM from 'react-dom'; 3 | import React from 'react'; 4 | 5 | const rootEl = document.getElementById('root'); 6 | 7 | ReactDOM.render(, rootEl); -------------------------------------------------------------------------------- /src/vp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/velopert/react-skeleton-2018/4d03b7b86f1665843277ac325ab702dac546ad11/src/vp.png --------------------------------------------------------------------------------