You are running `create-react-app` 4.0.3, which is behind the latest release (5.0.1). We no longer support global installation of Create React App. Please remove any global installs with one of the following commands: - npm uninstall -g create-react-app - yarn global remove create-react-app The latest instructions for creating a new app can be found here: https://create-react-app.dev/docs/getting-started/
해석하자면, 버전이 낮아서 안된다는 말. 지우고 다시 설치해야함.
Create React App의 글로벌(전역) 설치를 더 이상 지원하지 않습니다. 다음 명령어를 입력하여 글로벌 설치를 제거하세요 - npm uninstall -g create-react-app - yarn global remove create-react-app
PS C:\study\react> npm uninstall -g create-react-app
removed 67 packages in 0.818s
PS C:\study\react> npm i create-react-app
npm WARN saveError ENOENT: no such file or directory, open 'C:\study\react\package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN notsup Unsupported engine for create-react-app@5.0.1: wanted: {"node":">=14"} (current: {"node":"10.24.0","npm":"6.14.11"})
npm WARN notsup Not compatible with your version of node/npm: create-react-app@5.0.1
npm WARN notsup Unsupported engine for fs-extra@10.1.0: wanted: {"node":">=12"} (current: {"node":"10.24.0","npm":"6.14.11"})
npm WARN notsup Not compatible with your version of node/npm: fs-extra@10.1.0
npm WARN enoent ENOENT: no such file or directory, open 'C:\study\react\package.json'
npm WARN react No description
npm WARN react No repository field.
npm WARN react No README data
npm WARN react No license field.
+ create-react-app@5.0.1
added 67 packages from 27 contributors and audited 67 packages in 4.303s
5 packages are looking for funding
run `npm fund` for details
found 5 high severity vulnerabilities
run `npm audit fix` to fix them, or `npm audit` for details
[해석]
npm WARN notsup fs-extra@10.1.0에 대해 지원되지 않는 엔진: 원함: {"node":">=12"} (현재: {"node":"10.24.0","npm":"6.14.11" }) npm WARN notsup 노드/npm 버전과 호환되지 않음: fs-extra@10.1.0 npm WARN enoent ENOENT: 해당 파일이나 디렉터리가 없습니다. 'C:\study\react\package.json'을 엽니다. npm WARN 반응 설명 없음 npm WARN react 저장소 필드가 없습니다. npm WARN 반응 README 데이터 없음 npm WARN react 라이센스 필드가 없습니다.
이 파일들은 유지보수를 하면서 계속 수정되는데 문제는 브라우저에서 한번 불러온 css, js 파일을 캐시 해두는 탓에 사용자들에게 바로 적용이 되지 않는다.
특히 제품의 동일한 파일명의 js를 수정하였더라도 캐시된 수정전 버전이 적용되는 경우 브라우저 캐시를 날려도 적용이 안되는 경우가 있다.
따라서 캐싱되지 않도록 방법을 찾아야한다.
1. 캐시 사용금지
웹페이지의 헤더에 내용을 추가해서 캐시를 사용하지 않도록 설정할 수 있다.
html 문서의<head>와</head>사이에 다음 내용을 추가한다.
<meta http-equiv="Pragma" content="no-cache"> <!-- ← HTTP 1.0에서 사용하던 방법 -->
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="0"/>
위의 방법은 모든 캐시를 사용하지 않기 때문에 페이지를 로드할 때마다 새로 파일을 불러오기 때문에 사용자에게 바로 적용이 된다는 장점은 있지만, 반대로 파일의 변경이 없을 때에도 무조건 계속 새로 불러오기 때문에 속도에서도 손해를 볼 뿐만 아니라 트래픽을 쓸데없이 낭비하게 된다는 단점이 있다.
2. 파일 로드 방법의 변경
이 방법은 파일이 변경될 때마다 파일 이름을 바꾸어서 브라우저가 새로 파일을 불러오게 하는 방식이다.
이렇게 하면 파일이 변경되었을 때에만 다시 불러오게 되므로 훨씬 효율적이다.
다만 실제로 파일의 이름을 바꾸는 것은 아니고, 파일의 url 뒤에 사용하지 않는 파라미터를 덧붙여 브라우저가 다른 파일명으로 인식하게 하는 것이다.
가장 깔끔하고 효율적인 방법이다.
<!--이전 적용 파일-->
<script src="license.js"></script>
<!--캐싱되지 않도록 버전관리하는 파일-->
<script src="license.js?ver=20221213"></script>
뒤에 쿼리스트링으로 버전 정보 등을 붙여 스크립트 주소를 바꾸게 되면 매번 바뀐 URL 주소로 파일을 찾으므로 캐싱이 되지 않는다.
서버 캐시는 웹서버나 WAS 등을 껐다 켜야 하는 번거로움이 있지만 SHUTDOWN 후에는 캐시가 잘 날라간다.
브라우저 캐시는 F12로 개발자도구를 띄워놓은 뒤 새로고침 버튼 위에서 우클릭 > 강력 새로고침 방법으로 캐시를 비우기 해주는 편이 가장 좋다.
블로그 만들기 프로젝트 중 회원가입 부분에서 비밀번호 유효성 체크를 하는데 if문이 안먹더라.
String userPwd = req.getParameter("userPwd"); //ajax로 전달한 data 값 userPwd
PrintWriter out = resp.getWriter();
String result = "";//결과값
if (userPwd == "12345678!")) { //안됨
System.out.println("사용불가");
result = "1";
}else if (userPwd.equals("1004!!!!")) { //됨
System.out.println("위험");
//1004 등의 특정 의미있는 비밀번호
result = "2";
}
out.write(result); //ajax 결과값인 result
한참을 고전하다가 이유를 찾았는데, ==와 equals()의 차이 때문.
1. 사용법의 차이
생긴거부터가 다르다.
==는 비교를 위한 연산자(operator)이다. 메모리 주소를 비교한다.
equals()는 메소드(method)이다. 두 인스턴스의 주소값을 비교하여 같은 인스턴스인지를 확인하고 같으면 true, 다르면 false의 boolean값을 리턴한다.
2. 리터럴과 객체의 차이
리터럴은 변하지 않는 데이터 그 자체(=상수)이다. 원시타입과 String이 있으며, Heap메모리 영역 안에 있는Constant Pool이라는 메모리 영역에 값을 할당한다.
int a = 10;
int b = 10;
똑같은 값을 또 호출하면 전에 할당한 메모리 주소값을 똑같이 보내준다.
new 연산자는 객체를 Heap이라는 메모리 영역에 메모리 공간을 할당해주고 메모리주소를 반환한 후 생성자를 실행시켜준다. 리터럴과는 달리 new 연산자로 생성된 객체는 똑같은 값을 가진 객체가 있어도 서로 다른 메모리를 할당하기 때문에(=주소값이 다르기 때문에) 서로 다른 객체로 분류된다.
str과 str2는 동일한 내용이여도 주소값이 다르다.
객체가 아닌 일반적인 String 리터럴은 원시타입과 마찬가지로 같은 값을 호출할 시에 새로운 메모리를 할당하지 않고 String Constant Pool영역에 이미 할당되어 있는 값을 가르키게 된다.
3. 비교해보기
리터럴 str1,str2와 객체 str3,str4
str1과 str3는 그 내용은 같지만 인스턴스의 주소가 다르다. 하지만 equals메서드를 이용해 비교하면 동일하다는 결과가 나온다.
public class test {
public static void main(String[] args) {
String str1 = "apple"; //리터럴을 이용한 방식
String str3 = new String("apple"); //new 연산자를 이용한 방식
System.out.println(System.identityHashCode(str1)); //결과값 : 366712642
System.out.println(System.identityHashCode(str3)); //결과값 : 1829164700
}
String형에서의 equals()는 두 대상의 내용이 같으면 같다고 판단한다.
==는 메모리 주소를 비교하기 때문에 두 대상의 내용이 같아도 메모리 주소가 다르면 false를 리턴한다.
4. Call by value vs Call by reference
함수를 호출할 때 메모리 공간 안에서는 함수를 위한 임시공간이 생성된다. (ex.stack frame)
이 때 함수 호출 시 인자로 전달되는 변수가 어떻게 오는지에 따라 호출방식이 달라지게 된다.
call-by-value (값에 의한 호출) - 복사본 전달
call-by-value 값에 의한 호출방식은 함수 호출시 전달되는 변수의 값을 복사하여 함수의 인자로 전달한다.
복사된 인자는 함수 안에서 지역적으로 사용되는 local value의 특성을 가진다.
따라서 함수 안에서 인자의 값이 변경되어도, 외부의 변수의 값은 변경되지 않는다. (왜? 복사본을 변경했을 뿐 메모리에 있는 원래 변수값은 변경되지 않음)
call-by-reference (참조에 의한 호출) - 본래값 주소 전달
call-by-reference 참조에 의한 호출방식은 함수 호출시 인자로 전달되는 변수의 레퍼런스를 전달한다. (해당 변수를 가르킨다.)