'웹팩 기본편 - 자주 사용하는 로더' 를 학습하고 있습니다. 로더들 중에, file-loader에 대해 학습하다가 질문이 생겼습니다. 웹팩이 .png 파일을 발견하면 file-loader 를 실행할 것이고, 로더가 동작하고 나면 아웃풋에 설정한 경로로 이미지 파일을 복사합니다. 그리고 파일명이 해쉬코드로 변경 됩니다. 수업시간에 강사님께서 쿼리스트링이 매번 바뀌는 해시값으로 설정된다고 하셨는데, 그러면 빌드를 할때마다 해시값이 매번 바뀌는 건가요? 그리고 이게 캐시 관점에서 어떤 도움을 주는지 궁금합니다. 파일명이 해쉬코드로 변경되는게 캐쉬 갱신을 위한 처리로 보인다고 하셨는데, 정확히 어떤점에서 캐쉬 갱신에 도움을 주는지 이해가 잘 안가서요ㅠㅠ 알려주시면 감사하겠습니다!
안녕하세요 강사님. 제가 npm run build 로 빌드를 하려고 할때마다 다음과 같은 에러가 생기더라구요.. [에러 내용] $ npm run build > sample@1.0.0 build > webpack node:internal/crypto/hash:69 this[kHandle] = new _Hash(algorithm, xofLen); ^ Error: error:0308010C:digital envelope routines::unsupported at new Hash (node:internal/crypto/hash:69:19) at Object.createHash (node:crypto:138:10) at module.exports (C:\Users\power\OneDrive\inflearn\devEnv\sample\node_modules\webpack\lib\util\createHash.js:135:53) at NormalModule._initBuildHash (C:\Users\power\OneDrive\inflearn\devEnv\sample\node_modules\webpack\lib\NormalModule.js:417:16) at handleParseError (C:\Users\power\OneDrive\inflearn\devEnv\sample\node_modules\webpack\lib\NormalModule.js:471:10) at C:\Users\power\OneDrive\inflearn\devEnv\sample\node_modules\webpack\lib\NormalModule.js:503:5 at C:\Users\power\OneDrive\inflearn\devEnv\sample\node_modules\webpack\lib\NormalModule.js:358:12 at C:\Users\power\OneDrive\inflearn\devEnv\sample\node_modules\loader-runner\lib\LoaderRunner.js:373:3 at iterateNormalLoaders (C:\Users\power\OneDrive\inflearn\devEnv\sample\node_modules\loader-runner\lib\LoaderRunner.js:214:10) at Array.<anonymous> (C:\Users\power\OneDrive\inflearn\devEnv\sample\node_modules\loader-runner\lib\LoaderRunner.js:205:4) at Storage.finished (C:\Users\power\OneDrive\inflearn\devEnv\sample\node_modules\enhanced-resolve\lib\CachedInputFileSystem.js:55:16) at C:\Users\power\OneDrive\inflearn\devEnv\sample\node_modules\enhanced-resolve\lib\CachedInputFileSystem.js:91:9 at C:\Users\power\OneDrive\inflearn\devEnv\sample\node_modules\graceful-fs\graceful-fs.js:123:16 at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read_file_context:68:3) { opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ], library: 'digital envelope routines', reason: 'unsupported', code: 'ERR_OSSL_EVP_UNSUPPORTED' } Node.js v20.3.0 위의 에러가 왜 발생했는지 찾아봤고 원인과 해결방법을 다음 링크에 정리했습니다. [정리 링크] https://github.com/SeoMiYoung/Learning/issues/6 결론적으로, npm run build 를 하기전에 export NODE_OPTIONS=--openssl-legacy-provider 위의 명령어를 한번 쳐주고, npm run build 를 하면, 제대로 빌드가 작동되더라구요..! 그런데 VSCode를 다시 껐다 켜면, 또 다시 위의 명령어를 입력해준 다음에 빌드를 해야되더라구요.. 아마, 위의 명령어는 Node.js실행시, OpenSSL의 레거시 프로바이더를 사용하도록 환경변수를 설정해주는 명령어인데, 해당 명령어는 임시적으로 현재 세션에서만 레거시 프로바이더를 사용하도록 해주는 명령어이다보니, VSCode를 껐다 켜는것처럼, 재부팅하거나 새로운 세션을 시작하는 경우에는 환경변수가 초기화되어 다시 설정해줘야되는 것 같아서 그런 것 같더라구요..! 재부팅할때마다 빌드하기전에 해당 명령어를 치고 시작하는게 번거롭습니다.. 혹시 해결 방법이 없을까요?? [참고: 버전 정보] { "name": "sample", "version": "1.0.0", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack" }, "author": "", "license": "ISC", "description": "", "dependencies": { "css-loader": "^4.3.0", "file-loader": "^6.2.0", "react": "^18.2.0", "style-loader": "^1.3.0" }, "devDependencies": { "webpack": "^4.46.0", "webpack-cli": "^3.3.12" } }
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 안녕하세요. 카운트 쿼리 분리 부분을 듣는 도중에 카운트 쿼리에 LEFT JOIN이 사용되는 결과를 확인하기 위해 다음처럼 코드를 작성하였습니다. public interface MemberRepository extends JpaRepository<Member, Long> { @Query(value = "select m from Member m left join m.team t") Page<Member> findByAge(int age, Pageable pageable); ... } @Test public void paging() throws Exception { //given memberRepository.save(new Member("member1", 10)); memberRepository.save(new Member("member2", 10)); memberRepository.save(new Member("member3", 10)); memberRepository.save(new Member("member4", 10)); memberRepository.save(new Member("member5", 10)); //when PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Sort.Direction.ASC, "username")); Page<Member> page = memberRepository.findByAge(10, pageRequest); //then List<Member> content = page.getContent(); assertThat(content.size()).isEqualTo(3); assertThat(page.getTotalElements()).isEqualTo(5); assertThat(page.getNumber()).isEqualTo(0); assertThat(page.getTotalPages()).isEqualTo(2); assertThat(page.isFirst()).isTrue(); assertThat(page.hasNext()).isTrue(); } 그런데 결과는 강의와는 달리 카운트 쿼리에 LEFT JOIN 이 사용되지 않았고, 심지어 JPQL select m from Member m left join m.team t 을 @Query에 작성했음에도 조회 쿼리도 LEFT JOIN을 사용하지 않은 것을 확인했습니다. 이후 스프링 부트 3 이하 버전에서 동일한 코드로 실행해보니 강의와 동일한 결과를 얻을 수 있었습니다. 스프링 부트 3 부터 적용된 스프링 데이터 JPA 에서는 이러한 부분의 최적화를 자동으로 제공하는 것일까요?
안녕하세요. 백엔드 개발자 희망하고 있습니다. 자바 독학 공부 시작했는데 기본문법 예제들은 혼자 짤 수 있는데 객체지향/3 로또 부분부터 어렵네요. 구구단, 별찍기 하다가 로또 구현할 수 있을때까지 공부 방법이 궁금합니다. ㅠ.ㅠ 자바 공부 방법 알려주세요 ㅠㅠㅠ 지금은 강사님 강의 보고 이해가 부족하다는 부분 이론서 보면서 나가고있습니다. 이론서에 나와있는 문제들도 타이핑 하면서 진행하구 있습니다. 길게 코드 작성할 수 있을때까지 자바 공부 방법 알려주세요.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] plugins { id 'org.springframework.boot' version '2.6.5' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' ext["hibernate.version"] = " 5.6.5.Final " configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'javax.validation:validation-api' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-hibernate5' //JdbcTemplate 추가 //implementation 'org.springframework.boot:spring-boot-starter-jdbc' //MyBatis 추가 implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0' //JPA, 스프링 데이터 JPA 추가 implementation 'org.springframework.boot:spring-boot-starter-data-jpa' //Querydsl 추가 implementation 'com.querydsl:querydsl-jpa' annotationProcessor "com.querydsl:querydsl-apt:$ { dependencyManagement.importedProperties['querydsl.version'] } :jpa" annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api" //H2 데이터베이스 추가 runtimeOnly 'com.h2database:h2' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' //테스트에서 lombok 사용 testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' } tasks.named('test') { useJUnitPlatform() } //querydsl 추가 //def querydslDir = '$buildDir/generated' def querydslDir = "src/main/generated" //clean { // delete file(generated) //} querydsl { library = "com.querydsl:querydsl-apt" jpa = true querydslSourcesDir = querydslDir } sourceSets { main { java { srcDirs = ['src/main/java', querydslDir] } } } compileQuerydsl { options.annotationProcessorPath = configurations.querydsl } configurations { querydsl.extendsFrom compileClasspath } 강사님이 올려주신 내용 + 구글링 + 직접 수정했습니다. 간혹, 빌드는 되는데 generated 파일에 QClass 안보이시는 분들은 queryDsl 저장되는 경로에 $buildDir 대신 'src/main/'으로 해보세요
주문 서비스 개발 부분 강의를 듣다가 궁금한 점이 있어 질문드립니다. 주문 취소(OrderService.cancelOrder) 부분에서order.cancel() 만 작성하면 JPA 특징으로 인해, 데이터 업데이트 관련 쿼리 로직 없이 자동으로 업데이트 된다고 하셨는데요. 주문 생성(OrderService.order)의 EntityManager 가 사용된 orderRepository.save (order); 와 혼동이 와서 질문 남깁니다. 주문 취소 order.cancel() 메서드를 타면서 엔티티의 값(status, count 등) 변경 내역이 자동으로 업데이트 되는 것이라고 하면, 주문 생성도 Order.createOrder(member, delivery, orderItem); 를 타면서 엔티티의 값들을 설정하기 때문에 orderRepository.save (order); 를 사용하지 않아도 되는게 아닌가 라는 생각이 듭니다. 제가 JPA 를 잘 몰라서 혼란이 오는 것 같은데.. 쿼리는 직접 작성하지 않아도 업데이트/저장/삭제 등 DB 조작이 일어나려면 EntityManager 를 통해야 된다고 생각하고 있었습니다. 주문 취소는 EntityManager 없이 업데이트 되고, 주문 생성은 EntityManager의 persist() 를 사용해서 저장하는 것 이 2가지 차이점에 대해서 설명 부탁드립니다! 감사합니다 :)
안녕하세요! 수업시간에 보면 webpack.config.js 웹팩 설정파일을 CommonJS방식으로 작성하였는데요, 웹팩은 Node.js에서 동작하는 프로그램이고, Node.js가 사용하는 모듈시스템이 CommonJS이므로 웹팩 설정파일을 CommonJS로 작성한 건 이해했습니다. 그런데 문득 드는 궁금증이, CommonJS 모듈 시스템을 채택했던 NodeJS 환경에서 ES Module 을 사용하려면 Babel과 같은 트랜스파일러(transpiler)를 사용했어야 했는데요. NodeJS 버전 13.2부터 ES모듈 시스템에 대한 정식 지원 이 시작됨에 따라 다른 도구 없이 NodeJS 에서 손쉽게 ES Module 을 사용할 수 있게 되었잖아요..? 그렇다면 노드버전 13.2부터는 webpack.config.js 를 CommonJS가 아닌, ES Module방식으로 작성해도 상관없는건가요?
안녕하세요? 웹팩 cli를 처음 깔아보는 수강생입니다.. npm install -D webpack@4 webpack-cli 위의 코드처럼 그냥 webpack-cli를 깔면, 에러가 발생하는데요... 그래서 수업시간에 webpack-cli를 버전3을 사용한다는 글을 보고, 다음과 같이 명령어를 바꿔서 쳐보았더니 npm install -D webpack@4 webpack-cli@3 정상적으로 설치가 되었습니다. 왜 버전을 명시해주지 않으면 에러가 발생하나요?
강사님께서, 수업중에 import해오는 방법을 두가지를 언급하셨는데요, import * as math from './math.js'; // [방법1] 모든 export를 math라는 객체로 가져오기 import { sum } from './math.js'; // [방법2] sum함수만 가져오기 방법1로 import할 경우, sum함수를 사용하기 위해서 math.sum(,) 이렇게 써야하지만, 방법2로 import할 경우, 그냥 바로 sum(,)으로 사용하면 되나요? 저는 일단 그렇게 이해하고 있는데 그러면 import * as math1 from './math1.js'; import * as math2 from './math2.js'; 이렇게 math1.js와 math2.js에서 각각 sum함수를 만들고, 그걸 app.js에서 위와 같이 import해서 사용했을 때, math1.sum(,) 그리고 math2.sum(,) 이렇게 쓰면 되니깐, 이름이 sum으로 같아도 충돌이 안나겠네요? 그러나 방법2방식으로 import { sum } from './math1.js'; import { sum } from './math2.js'; 이렇게 가져온다면, 둘다 sum(,)으로 호출하게 되니깐, 이름 충돌이 발생하겠네요? 제가 이해한것이 맞는지 확인부탁드려요ㅠㅠ
안녕하세요. where 조건을 동적으로 생성해주는 부분에 대해서는 충분히 이해가 되었습니다. 그런데 혹시 특정 condition 값에 따라 join을 해줘야하는 테이블이 다른 경우라면 어떻게 처리되어야 할지 모르겠어서 글을 남기게 되었습니다. condition조건에 teamName이 있을 때만 team을 조인해주고 싶은데 join 구문을 동적으로 처리할 수 있는 좋은 방법이 어떤 것인지 질문드립니다. 😭 감사합니다.