Node Package Manager: 자바스크립트 패키지 관리 모듈
- hpmjs.xom에서 node_modules 폴더에 라이브러리를 받고 package.json에 명세하여 관리해줌
npx: npm에서 제공하는 실행 도구 (node.js기반 파일들의 설치와 실행을 돕는 도구)
- 1회성 패키지 실행 시, 특정 노드 버전의 스크립트 실행 시 유용
yarn: 페이스북에서 npm을 개선하여 만든 것으로 npm과 비슷한 역할
node.js: 자바스크립트 런타임 (런타임: 프로그램이 구동되는 환경)
npm install 패키지명
: 패키지 설치
npm init
: node.js 프로젝트를 실행
webpack: 기본 웹 문서 파일인 html/css/js가 아닌 다른 스타일의 웹 문서를 해석해주는
컴파일러 같은 역할
별도의 서버를 구축하지 않고 static 파일을 다루는 웹 서버를 열고 hot-loader 기능을
제공하여 수정된 코드를 자동 반영
npm install --save react react-dom
npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
npm install --save-dev react-hot-loader webpack webpack-dev-server
--save-dev
: 개발 과정에만 필요하기 때문에 패키지 관리를 용이하게 하기 위해
babel: es6 문법을 프로젝트에서 사용할 수 있게, jsx코드를 인식하기 위해 babel-preset-react
react-hot-loader: 리액트를 호환하지 않는 개발 서버가 실행 중에 변경된 리액트 컴포넌트만 업데이트 -> state를 유지시키기 때문에 코드가 변경되어도 constructor를 실행하지 않는다
-> constructor가 변경된다면 직접 새로고침 해줘야함
webpack, webpack-dev-server를 global로 설치했어도 local에서 다시 설치해줘야 함
webpack.config.js
생성var webpack = require('webpack'); // webpack 불러오기 (es6 부터는 import)
// 객체를 모듈로 만들어서 내보내기 (다른 파일에서 가져가 쓸 수 있음)
module.exports = {
entry: './src/index.js',
// index.js를 시작으로 import된 모든 파일들을 재귀적으로 불러온다
// 배열로 만들어서 여러 파일을 전달 가능
output: {
path: __dirname + '/public/',
filename: 'bundle.js'
},
// entry에서 불러온 파일들을 합쳐 /public/bunlde.js로 저장한다
// 개발 서버 설정
devServer: {
hot: ture, // 파일 수정시 실시간 리로딩
inline: true, // dev server의 클라이언트를 bundle.js에 같이 넣어줌
host: '0.0.0.0', // 기본 값은 localhost (외부 접속 불가)
port: 4000,
contentBase: __dirname + '/public/' // index 파일의 위치
},
// 웹팩의 핵심 기능
// 현재 설정은 loader를 통하여 es6와 react 코드 형식을 JavaScript 기본 문법으로 변경해줌
// css 로더를 사용하면 css를 불러와 사용 가능
// html 압축 가능 등..
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
cacheDirectory: true,
presets: ['es2015', 'react']
}
}
]
},
plugins: [
new webpack.HotModulereplacementPlugin()
]
// 플러그인: 현재 설정은 hot loader를 사용
// 자바스크립트 압축 등 많은 기능과 서드파티 플러그인이 존재함
};
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>React App</title>
</head>
<body>
<div id="root"></div> <!-- React Component의 root로 사용할 엘리먼트 -->
<script src="bundle.js"></script> <!-- webpack의 output -->
</body>
</html>
import React from 'react'; // es6 문법
// const React = require('react');
class App extends React.Component{
render(){
return(
<>
</>
);
}
}
export default App; // es6 문법
// module.export = App;
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App'; // .js 확장자 생략 가능
const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement); // 1. react root 컴포넌트, 2. html root 엘리먼트
// react-dom을 실제 렌더링
"scripts": {
"dev-server": "webpack-dev-server"
} // 내부에 추가
// npm run dev-server 명령어로 react 개발 서버를 실행
//webpack dev server는 꼭 root디렉토리에서 실행돼야하지만, 적어주면 root가 아니어도 실행 가능
npm run dev-server로 실행
npm run dev-server 실행 시 오류가 났다.
Cannot find module 'webpack-cli/bin/config-yargs'
webpack과 webpack-dev-server 간 버전이 안맞아서 나는 오류라고 하는데,
버전을 맞춰도 실행이 안됨..
webpack 설치 과정에서 오류가 났던 것.. 🤦🏻
No Xcode or CLT version detected!
Xcode 버전이 안맞다는 것 같은데
삭제 후 재설치 하면 된다고 한다.
정말 놀랍게도 거짓말 처럼 된다.
mac os version 업데이트를 할 때 마다 Xcode 버전을 같이 맞춰줘야 하는듯 하다.
xcode-select --print-path
sudo rm -r -f /Library/Developer/CommandLineTools
xcode-select --install
JavaScript 문법 힌트를 주는 패키지
{"esversion":6}
작성 해줌우선 babel관련 친구들 babel-loader빼고 다 삭제하시고
npm install -D @babel/core @babel/preset-env @babel/preset-react
webpack.config.js
var webpack = require('webpack')
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: __dirname + '/public/',
filename: 'bundle.js'
},
devServer: {
hot: true,
// inline: true,
host: '0.0.0.0',
port: 4000,
static: __dirname + '/public/',
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
options: {
cacheDirectory: true,
presets: ['@babel/preset-env', '@babel/preset-react']
}
},
]
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
}
index.js 에서 react-hot-loader 설정
import React from 'react'
import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import App from './components/App'
ReactDOM.render(
<AppContainer>
<App/>
</AppContainer>,
document.getElementById('root')
);
// Hot Module Replacement API
if (module.hot) {
module.hot.accept('./components/App', () => {
const NextApp = require('./components/App').default;
ReactDOM.render(
<AppContainer>
<NextApp/>
</AppContainer>
,
document.getElementById('root')
);
});
}