Can't not resolve 'react-hot' 

에러 해결 방법





또 아래의 포스팅에 이어서 에러 해결 방법이다


예전 강좌(다른 고수님들이 만들었던) 를 보면 모듈 로더 부분이 


1
2
3
4
5
6
7
8
9
10
11
12
    module: {
        loaders: [
            {
                test: /\.js$/,
                loaders: ['react-hot''babel?' + JSON.stringify({
                    cacheDirectory: true,
                    presets: ['es2015''react']
                })],
                exclude: /node_modules/,
            }
        ]
    }
cs



이런식으로 되어 있는데


뒤에 -loader 을 적어야 해당 오류가 나타나지 않는다.


이것도 아마 버전이 달라져서 그런듯 하다


간단히 불러오려는 로더의 뒷부분에 -loader을 붙여주자


react-hot 옆에 있는 babel에도 마찬가지로 뒤에 로더를 붙여주면 된다.


이전에도 포스팅 했던


2017/02/22 - [Yame Programmer/react.js] - [react.js] module not found error cannot resolve 'babel' in 해결 방법


이것과 같은 에러인 듯 하다.



1
2
3
4
5
6
7
8
9
10
11
12
module: {
        loaders: [
            {
                test: /\.js$/,
                loaders: ['react-hot-loader''babel-loader?' + JSON.stringify({
                    cacheDirectory: true,
                    presets: ['es2015''react']
                })],
                exclude: /node_modules/,
            }
        ]
    }
cs


이렇게 수정해주면


서버 구동이 정상적으로 작동이 된다.




해당 예제는

https://github.com/cheesu/react-express-study


에서 확인 할 수 있습니다.

 Using NoErrorsPlugin is deprecated 

해결 방법






아래와 같은 설정에서 이어지는 포스팅이다.


역시나 웹팩 플러그인에서 문제가 생긴다.


저 에러가 생겨도 일단 서버 구동은 되는듯 한데


대충 이제 저 플러그인 안쓰니까 다른걸로 대체해서 사용해라 라는 메세지이다


답은 메세지에 나와있다

NoErrorsPlugin

대신에


NoEmitOnErrorsPlugin

이걸 사용하면 된다.


1
2
3
4
5
plugins: [
        new webpack.optimize.OccurrenceOrderPlugin(),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoErrorsPlugin()
    ],
cs


여기서


1
2
3
4
5
  plugins: [
        new webpack.optimize.OccurrenceOrderPlugin(),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoEmitOnErrorsPlugin()
    ],
cs



이렇게 바꿔주면 해결된다.


물론 그냥 저 NoErrorsPlugin 을 빼버려도 구동은 된다.



잘 정리되어있는 강좌라도 몇달전 강좌라면 지금 버전과 맞지 않는 부분이 생길 수 있으니


node.js나 react.js 같은 나온지 얼마 안된 라이브러리를 공부 할떈


해당 레퍼런스를 꼭 읽어봐야 하는 것 같다.


아니면 git나 stackOverFlow에서 검색을 하거나


역시 이바닥은 계속해서 공부해야 하나보다.


사실 강좌보고 예제 따라하면서 그냥 코드 복사해다가 붙여놓고 


우왕 신기하다 @_@ 


하고 넘어가고 지금까진 예제 코드들도 디코딩이 전혀 안된다


단지 이렇게 실행하다 만나는 에러들 해결방법 찾는 능력만 올라가는 것 만으로


공부가 된다고 위안을 삼는다.



일단 강좌들 한바퀴 쭉 돌고 혼자서 게시판이라도


만들어 볼 생각인데 정말 만만치가 않다


webpack.optimize.OccurenceOrderPlugin 

is not a constructor 

에러 해결 방법



react.js와 express 를 함께 사용 하는 강좌를 보며 예제를 만드는 와중에



npm run build 까진 잘 되다가 


npm run developer 명령어로 서버 실행을 하자





이런 에러가 발생한다.


대충 보니 OccurenceOrderPlugin  라는 녀석의 생성자가 없다 뭐 그런 내용인듯 하다


일단 해당 플러그인을 실행하는 부분에서 에러가 났나본데


한참동안 구글링을 하다가 


문득!


강좌는 몇달전에 만들어진거고 나는 이번에 생성하고 웹팩이나 바벨등을 설치 했으니


버전이 다르지 않을까? 라는 생각을 가지고


다시 검색을 해보니


와.. 세상에... 


이름이 바뀌었다 ㅋㅋㅋ


OccurenceOrderPlugin
OccurrenceOrderPlugin


구분이 갑니까?



webpack 1버전에서 2버전으로 올라오면서


스펠링 'r' 이 하나 더 늘었다



1
2
3
4
5
    plugins: [
        new webpack.optimize.OccurenceOrderPlugin(),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoErrorsPlugin()
    ],
cs



이렇게 되어있던 코드를


1
2
3
4
5
plugins: [
        new webpack.optimize.OccurrenceOrderPlugin(),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoErrorsPlugin()
    ],
cs


이렇게 바꿔주도록 하자...


그럼 해당 에러는 사라지게 된다.


저 밑에 NoErrorsPlugin 이것도 문제가 있는데 다음 포스팅에 올리기로 한다.



해당 예제는

https://github.com/cheesu/react-express-study


에서 확인 할 수 있습니다.

함수형 컴포넌트 만들기


react에서 컴포넌트를 정의할때 class 문법을 사용하는데 


라이프사이클API를 사용하거나 state를 사용하는 경우에는 class 문법을 사용해 컴포넌트를 만들어야 한다.


일반적으로 지금까지 만들어왔던


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//파일 및 컴포넌트의 첫 문자를 대문자로 하는건 React의 naming convention 입니다.
import React from 'react'//import JavaScript ES6 에 새로 도입된 키워드로서, require('..') 의 역할을 합니다.
/*
* 컴포넌트에서 immutable (변하지 않는)  데이터가 필요 할 땐,
* render() 메소드의 내부에 안에 { this.props.propsName } 형식으로 넣고,
* 컴포넌트를 사용 할 때, < > 괄호 안에 propsName="value" 를 넣어 값을 설정합니다.
*
* */
class Header extends React.Component {
    render(){
        return (
            <h1>this.props.title }</h1>
        );
    }
}
export default Header; //export는 JavaScript ES6 에 새로 도입된 키워드로서, module.export = Header 와 같습니다.
cs



이런식이다.


주석이 많아 좀 보기 힘들지만.. 주석을 지우면


1
2
3
4
5
6
7
8
9
10
11
12
13
import React from 'react'
 
class Header extends React.Component {
 
    render(){
        return (
            <h1>this.props.title }</h1>
        );
    }
 
}
 
export default Header; 
cs


이런식이 되겠다.



그런데 라이프사이클API도 사용하지 않고 state도 사용하지 않고


단순히 props만 전달해 뷰를 렌더링해주는 역할만 한다면 


함수형 컴포넌트 형식으로 컴포넌트를 정의 할 수 있다.




1
2
3
4
5
6
7
8
9
10
import React from 'react'
 
    function Header(){
        return (
            <h1>{props.title }</h1>
        );
    }
 
 
export default Header; 
cs



이런식으로 말이다.


뭔가 아까보다 단순해지지 않았는가?



여기서 ES6의 애로우펑션(화살표 함수)를 사용하여 만들 수도 있다.



1
2
3
4
5
6
7
8
9
10
import React from 'react'
 
    const Header = (props) => {
        return (
            <h1>{ props.title }</h1>
        );
    }
 
 
export default Header; 
cs




이 코드를 비구조화 할당 문법을 사용한다면




1
2
3
4
5
6
7
8
9
10
import React from 'react'
 
    const Header = ({title}) => {
        return (
            <h1>{ title }</h1>
        );
    }
 
 
export default Header; 
cs


이렇게 만드는게 가능 하다.



class문법을 사용하는 것 보다 훨씬 간단해 졌다.


그러나 함수형 컴포넌트에 따로 성능최적화가 이뤄진 것이 아니기 떄문에 


성능에선 클래스형 컴포넌트와 다르지 않다.


리액트 팀에서 함수형 컴포넌트의 성능을 최적화하겠다고 했지만 


일부 상황에서 제대로 동작하지 않는 오류가 있다고 하는데


레딧에서 본 정보이니 자세한 내용은 아니다.


리액트 컴포넌트 라이프 사이클 API



이 포스팅은


VELOPERT 님의 포스팅을 아주많이 참조하였습니다;;


(출처 : https://velopert.com/1130 )





1. 컴포넌트 라이프 사이클 API 순서


컴포넌트를 생성 할 때는 


constructor -> componentWillMount -> render -> componentDidMount 


순으로 진행됩니다.


컴포넌트를 제거 할 때는 componentWillUnmount 메소드만 실행됩니다.


컴포넌트의 prop이 변경될 때엔 


componentWillReceiveProps -> shouldComponentUpdate -> 

componentWillUpdate-> render -> componentDidUpdate 


순으로 진행됩니다.


 state가 변경될 떄엔 props 를 받았을 때 와 비슷하지만 shouldComponentUpdate 부터 시작됩니다.


그림으론 아래와 같이 보시면 됩니다.





2. 각 메소드들이 하는 역할


1) constructor

3
4
constructor(props){
    super(props);
    console.log("constructor");
}

1
2
3
4
5
6
7
8
9
10
11
12
13
  constructor(props) {
        console.log("컨텍트 생성자 시작");
        super(props);
        this.state = {
            contactData: [
                {name: "Abet", phone: "010-0000-00035"},
                {name: "Betty", phone: "010-0000-0002"},
                {name: "Charlie", phone: "010-0000-0003"},
                {name: "David", phone: "010-0000-0004"}
            ]
        };
        console.log("컨텍트 생성자 끝");
    }
cs


-> 생성자 메소드 입니다. 컴포넌트가 처음 만들어질때 실행되며 이곳에서 기본 state를 정할 수 있습니다.




2) componentWillMount

componentWillMount(){
    console.log("componentWillMount");
}


-> 컴포넌트가 DOM 위에 만들어지기 전에 실행 됩니다.





3) render

1
2
3
4
5
6
7
render() {
        return (
            <button onClick={this.handleClick.bind(this)}>
                Remove selected contact
            </button>
        );
    }
cs

-> 컴포넌트 렌더링을 담당합니다.



4) componentDidMount

componentDidMount(){
    console.log("componentDidMount");
}


-> 컴포넌트가 만들어지고 첫 렌더링을 다 마친 후 실행되는 메소드 입니다.

이 안에서 다른 JS 프레임워크를 연동하거나. setTomeout, setInterval및 Ajax 처리를 넣습니다.

--> https://medium.com/@taeho.leon.kim/javascript-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC%EB%93%A4%EC%97%90-%EB%8C%80%ED%95%9C-%EC%9D%B4%EC%95%BC%EA%B8%B0-8fc74fab2140#.8nmyw5gjt

이곳에서는 해당 API가 렌더링을 시잓하는 즉시 실행한다고 이야기 한다. 즉 렌더링이 끝날때까지 기다려주지 않는다고 말이다.

아직 정확히 확인을 해보지 못하였다. 





5) componentWillReceiveProps

componentWillReceiveProps(nextProps){
    console.log("componentWillReceiveProps: " + JSON.stringify(nextProps));
}


-> 컴포넌트가 prop을 새로 받았을 때 실행 됩니다. porp에 따라 state를 업데이트 해야 할 떄 사용 하면 유용 합니다.

     이 안에서 this.setState()를 해도 추가적으로 렌더링 하지 않습니다.




6) shouldComponentUpdate

2
3
4
shouldComponentUpdate(nextProps, nextState){
    console.log("shouldComponentUpdate: " + JSON.stringify(nextProps) + " " + JSON.stringify(nextState));
    return true;
}


-> 이전 포스팅에서 사용했던 메소드. prop나 state가 변경 되었을때 리렌더링을 할지 말지 정하는 메소드.

    실제로 활용 할때는 필요하는 값을 비교해서 반환하도록 사용 한다. (이전 포스팅 참조)

2017/02/27 - [Yame Programmer/react.js] - [react.js] 변경된 값만 렌더링 되도록 하기 shouldComponentUpdate()


7) componentWillUpdate

componentWillUpdate(nextProps, nextState){
    console.log("componentWillUpdate: " + JSON.stringify(nextProps) + " " + JSON.stringify(nextState));
}


-> 컴포넌트가 업데이트 되기 전에 실행된다. 이 메소드 안에서는 this.setState()를 사용하면 안된다. 무한루프에 빠져들어 버린다.



8) componentDidUpdate

2
3
componentDidUpdate(prevProps, prevState){
    console.log("componentDidUpdate: " + JSON.stringify(prevProps) + " " + JSON.stringify(prevState));
}


-> 컴포넌트가 리렌더링을 마친 후 실행된다




9) componentWillUnmount

componentWillUnmount(){
    console.log("componentWillUnmount");
}



-> 컴포넌트가 dom 에서 사라진 후 실행되는 메소드















변경된 값만 렌더링 되도록 하기 shouldComponentUpdate()


react 강좌를 보며 예제를 따라해보고 하던 도중


라이프사이클이나 실행유무 어떤 메소드가 먼저 실행되는지


여기에 있는 this와 저기에 있는 this 가 무슨 차이가 있는지


알아보기 위해 여기저기 온갖곳에 console.log를 사용하여


개발자모드 화면에서 콘솔들을 보는 도중


특정값이 바뀌는데도 맵안에 들어가 있는 녀석들을 전부 하나씩


다시 렌더링 한다는걸 알게 되었다


역시나 그에 대한 해답도 강좌에 마지막 부분에 써있었는데


기록해놔야 겠다 싶어서 포스팅을 한다



1
2
3
4
// 컴포넌트를 다시 렌더링 해야 할 지 말지 정의해준다
    shouldComponentUpdate(nextProps, nextState){
        return (JSON.stringify(nextProps) != JSON.stringify(this.props));
    }
cs




shouldComponentUpdate


요 함수가 다시 렌더링을 할지 말지 정의를 해주는데 리턴값을 보면


다음 props와 현재 props를 비교 해서 렌더링 할지 말지 정해주는 것 같다.


리턴이 true false로 가니 좀 더 다른 방법으로도 응용이 가능 할 것 같다.


ES6에는 생소한 문법들도 많고 평소 사용하던 방식과 너무나도 많이 달라 


react를 공부하는데 어려움이 엄청나게 많다. 


심지어 나는 bind나 this를 자주 사용하지 않았기 때문에 더 심한것 일수도...


현재 공부중인 리액트 예제들은


https://github.com/cheesu/react-tu


이곳에 올려놨으니 받아서 보는 것도 좋을 것이다.


왜냐하면 주석을 여기저기 엄청나게 달아놓고 console.log도 엄청나게 달아놨기 때문에 


혹여나 관심있는 사람들은 받아보면 도움이 될 것 같다.



Y축 라벨  데이터가 1 이하일땐 소수점표기 

이상일땐 자연수, 천단위 콤마찍도록 하는 방법




켄도 UI의 차트를 하다 보면 여러가지 부가기능 및 옵션설정을 해주어야 하는 부분이 많다.


뭐 가장 많이 쓰이는 것이 차트와 그리드인데


차트를 구현하다 보니 값이 0.5 같은 1 이하값이 들어오는 경우에


Y축 라벨링이


0 0 0 1 1 1 이런식으로 나타나는 경우가 있다.


그렇다고 템플릿에 


1
2
3
4
5
  valueAxis: {
            labels: {
                format: "{0:#.##}"
            }
        },
cs



이런식으로 작성하는 경우엔 값이 100이든 1000이든


Y축 라벨링은 100.00 200.00  이런식으로 소수점이 고정으로 들어가게 되버린다.


그래서 여기저기 찾아보고 삽질을 하다가


템플릿에 IF문을 사용할 수 있으니 값이 2 이하일때만 소수점으로 나오게 하고 


그 이상인 경우엔 자연수로 나오도록 하는 방법을


사용하면 되겠다 싶어 테스트 해보니 성공적으로 나오게 된다.



1
2
3
4
5
valueAxis: {
            labels: {
                template:kendo.template("#if (value == null || value < 2) {# #= kendo.format('{0:N1}', value) # #} else {# #= kendo.format('{0:N0}', value) # #}#"),
            }
        },
cs




템플릿 양식이 좀 길어지긴 하지만 성공적으로 나온다.



이렇게 값이 없거나 작으면 소수점으로







값이 커지면 자연수에 천단위 콤마까지


Y축 라벨에 천단위 콤마찍는건


포맷을 {0:N0}


이렇게 지정해 놓으면 된다

react.js 에서 Jquery 사용 하는 방법(unused import $ from jquery )



nodejs사용 babel, webpack 사용하는 사람들에게 적용 가능 한 방법입니다.


다른건 모르겠네요 어차피 여긴 야매 가이드니까 신경 ㄴㄴ



이제 튜토리얼 하고 있는데 세상에 바닐라JS는 나에겐 너무 높은 벽이었고


3년전 처음 배울때나 바닐라 JS 사용했지 실무투입하고 난 이후부턴


제이쿼리만 주구장창 썻는데 getelementById 라니 이건 나에게 너무나 가혹한것 같아


제이쿼리를 어떻게 쓸수 있을까 하고 또 구글링을 시작 했습니다.


역시 인터넷엔 없는게 없었고


1
import $ from "jquery";
cs


이렇게 js에 추가해 주면 사용 할수 있다고 스택오버플로우 형들이 알려주길래


그대로 적용 시켰더니



왜 죽은 동태눈알 색깔을 하고 있는걸까..


unused import $ from jquery 라는 메세지와


메세지창을 확장시키면


checks that javascript or typescript import binding ... 어쩌구 저쩌구


라고 나오면 실행되지 않는다.


아!


npm에서 제이쿼리를 다운받지 않아서 그런건가? 


그렇지 제이쿼리가 없으면 못쓰는거겟지 라는 생각으로


npm install jquery --save


명령어를 입력후 제이쿼리를 설치 했으나


역시 죽은동태눈깔은 돌아오지 않았다.



조금더 구글링을 해보니


1
2
import jQuery from "jquery";
window.$ = window.jQuery = jQuery;
cs


이렇게 하면 된다고 한다


오오 신기하다 된다된다


이제 리액트에서 제이쿼리를 사용할수 있겟구나 하고


테스트해보니 


제이쿼리 정상작동 하는 것을 확인 할 수 있었다.




module not found error cannot resolve 'babel' in 에러와 the node api for babel has been moved to babel-core  해결 방법




드디어 리액트에 입문!


아직 뭐가 뭔지도 잘 모르고


바벨이라는 녀석이 ES6문법으로 바꿔주고 웹팩이라는 녀석이 번들js로 


관리해준다는 대략적인 정보만 알고 난 상태에서


https://velopert.com/814


이분의 강좌를 보면서 공부를 하기로 시작 했는데 시작과 동시에 에러가 날 반겨준다.




1. the node api for babel has been moved to babel-core  해결 방법




<으아악 불길한 붉은 텍스트라니>



the node api for babel has been moved to babel-core


이 에러는 뭐 대충 설치 할때 경로 문제나 디펜던시 설정 문제 인듯 하다


pakage.json 파일의 디펜던시를 아래와 같이 바꿔주면 해결이 된다.


아마 위의 에러가 나는 것은 딘펜던시와 덴펜던시스 둘다 바벨이 들어가 있는 경우이며


글로벌로 babel과 webpack를 설치 한 후


또 종속성으로 --save 명령어로 설치하는 경우에 나타나는 에러 인듯 하다.



1
2
3
4
5
6
7
8
9
10
11
12
 "dependencies": {
    "react": "^15.4.2",
    "react-dom": "^15.4.2"
  },
  "devDependencies": {
    "babel-core": "^6.23.1",
    "babel-loader": "^6.3.2",
    "babel-preset-es2015": "^6.22.0",
    "babel-preset-react": "^6.23.0",
    "webpack": "^2.2.1",
    "webpack-dev-server": "^2.4.1"
  }
cs


디펜던시 목록을 위와같이 수정해주면 사라지며


그래도 계속 나타날 경우엔 어차피 튜토리얼 단계니까 


폴더 지우고 다시 순서대로 받아주면 해결 된다.




2.module not found error cannot resolve 'babel' in 에러 해결 방법





이 에러는 webpack.config.js 파일을 수정해 주어야 한다.


이 파일은 webpack의 설정파일인데


ECMAScript6를 컴파일 해주고 개발서버를 열어주는 webpack의 설정 파일인데


모듈 로더 부분이


1
2
3
4
5
6
7
8
9
10
11
12
13
    module: {
        loaders: [
            {
                test: /\.js$/,
                loader: 'babel',
                exclude: /node_modules/,
                query: {
                    cacheDirectory: true,
                    presets: ['es2015''react']
                }
            }
        ]
    }
cs



이런식으로 loader:'babel'

로 되어있는 경우 발생한다


바벨을 참조하지 못해서 생기는 오류인듯 한


loader:'babel' -> loader:'babel-loader' 이렇게 바꿔주면 간단히 해결이 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
   module: {
        loaders: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/,
                query: {
                    cacheDirectory: true,
                    presets: ['es2015''react']
                }
            }
        ]
    }
cs



이제 npm start 명령어를 실행하면 complied successfully 라는 반가운 문구를 볼 수가 있게 된다.



node js cannot read property 'replace' of undefined 에러 해결 



방금전 ejs를 못찾는다는 에러를 해결후 예제대로 테스트를 해봤는데


서버 실행시키는 것 까지는 성공


그러나 브라우저에서 해당 포트번호 적고 띄워보니


cannot read property 'replace' of undefined 라는 에러가 나타나면서 접속에러가 떠버린다.


이건 뭐 내가 뭘 잘못했는지도 모르겠고


30분 삽질하다가 예제의



1
2
3
4
5
6
7
8
9
10
11
12
var ejs = require('ejs');
var http = require('http');
var fs = require('fs');
 
http.createServer(function (request, response) {
    fs.readFile('ejstest.ejs''utf8'function (error, data) {
        response.writeHead(200, { 'Content-Type''text/html' });
        response.end(ejs.render(data));
    });
}).listen(5000function () {
    console.log('Server Running...');
});
cs


서버실행 부분의 readfile를 보니


ejs 파일명만 적어놓고 경로는 없다는걸 보고


혹시나 하는 생각에 위의 예제가 있는 폴더 안에 ejs 파일을 넣고 실행시켰더니 정상 동작 한다....


그렇지.. 아직 맵핑도 없고 아무것도 없는 상태였지...


하.. 멍청한짓을 하다니;;


너무도 자연스럽게 서버와 ejs는 분리되는게 맞겠지 하면서


폴더를 나눠놓고 실행시켜서 나타났던 오류였다


cannot read property 'replace' of undefined  이 오류가


이 포스팅의 이유만으로 나타나는 것은 아니고 여러가지 이유가 있겠지만


혹시나 나와 같은 실수를 하는 사람이 있거나 내가 같은 실수를 또 할 것만 같아서


이렇게 포스팅을 한다.



+ Recent posts