6달 전 · 노원재 님의 답변 업데이트
ReactNative ios build 에러 3일째 해결을 못했습니다.
시뮬레이션을 실행하려고 해도 스크립트 문제, iPhone 버전 범위 문제, 시뮬레이터 문제가 계속 발생합니다. 어떤 도움이라도 감사합니다. ReactNative를 처음 접했습니다. 저희 팀에서 저를 도울 수 있는 사람이 없습니다. #프로젝트 환경 mac M2 ruby -v ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.arm64e-darwin23] node -v v20.10.0 pod --version 1.15.2 package.json { "name": "labts", "version": "0.0.1", "private": true, "scripts": { "android": "react-native run-android", "ios": "react-native run-ios", "lint": "eslint .", "start": "react-native start", "test": "jest" }, "dependencies": { "@react-native-community/async-storage": "^1.12.1", "@react-native-community/cli": "13.6.9", "@react-navigation/bottom-tabs": "^6.6.0", "@react-navigation/native": "^6.1.17", "@react-navigation/native-stack": "^6.10.0", "@tanstack/react-query": "^5.51.5", "@types/react-native-vector-icons": "^6.4.18", "axios": "^1.7.2", "date-fns": "^3.6.0", "immer": "^10.1.1", "react": "18.2.0", "react-native": "0.74.3", "react-native-calendars": "^1.1305.0", "react-native-date-picker": "^5.0.4", "react-native-dotenv": "^3.4.11", "react-native-get-random-values": "^1.11.0", "react-native-image-crop-picker": "^0.41.2", "react-native-image-zoom-viewer": "^3.0.1", "react-native-paper": "^5.12.3", "react-native-permissions": "^4.1.5", "react-native-safe-area-context": "^4.10.8", "react-native-screens": "^3.32.0", "react-native-splash-screen": "^3.3.0", "react-native-tab-view": "^3.5.2", "react-native-vector-icons": "^10.1.0", "react-native-vision-camera": "^4.5.1", "uuid": "^10.0.0", "yarn": "^1.22.22" }, "devDependencies": { "@babel/core": "^7.20.0", "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.0", "@react-native/babel-preset": "0.74.85", "@react-native/eslint-config": "0.74.85", "@react-native/metro-config": "0.74.85", "@react-native/typescript-config": "0.74.85", "@types/react": "^18.2.6", "@types/react-native-dotenv": "^0.2.2", "@types/react-test-renderer": "^18.0.0", "babel-jest": "^29.6.3", "babel-plugin-module-resolver": "^5.0.2", "eslint": "^8.19.0", "jest": "^29.6.3", "prettier": "2.8.8", "react-test-renderer": "18.2.0", "typescript": "5.0.4" }, "engines": { "node": ">=18" } } PodFile require Pod::Executable.execute_command('node', ['-p', 'require.resolve( "react-native/scripts/react_native_pods.rb", {paths: [process.argv[1]]}, )', __dir__]).strip platform :ios, '12.0' use_frameworks! #use_modular_headers! prepare_react_native_project! linkage = ENV['USE_FRAMEWORKS'] if linkage != nil Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green use_frameworks! :linkage => linkage.to_sym end target 'nexlabts' do config = use_native_modules! use_react_native!( :path => config[:reactNativePath], # An absolute path to your application root. :app_path => "#{Pod::Config.instance.installation_root}/.." ) target 'nexlabtsTests' do inherit! :complete # Pods for testing end post_install do |installer| # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 react_native_post_install( installer, config[:reactNativePath], :mac_catalyst_enabled => false, # :ccache_enabled => true ) end end 제가 아래 에러 3가지에 대해 제가 해본 방법들입니다. 1. node 재설치 node_module 폴더 삭제, package-rock.json 삭제 후 재설치 npm install --legacy-peer-deps yarn install 2. Xcode가 node 읽을 수 있도록 설정 sudo ln -s "$(which node)" /usr/local/bin/node 3. Podfile 내 platform 설정 수정 platform :ios, '12.0' or platform :ios, '14.0' 4. Pods 재설치 rm -rf ~/Library/Developer/Xcode/DerivedData or rm -rf ~/Library/Developer/Xcode/DerivedData/* rm -rf Pods rm Podfile.lock pod install --repo-update Xcode \> Product \> Clean Build Folder. cd ./ios pod cache clean -all pod install --repo-update cd ../ npx react-native run-ios --no-packager --simulator="iPhone 15" or npx react-native run-ios --simulator="iPhone 15" or yarn start > i(run ios) Err 1. cocoaPods 설치할 때 [!] CocoaPods could not find compatible versions for pod "React-RuntimeHermes": In Podfile: React-RuntimeHermes (from ../node_modules/react-native/ReactCommon/react/runtime) Specs satisfying the React-RuntimeHermes (from ../node_modules/react-native/ReactCommon/react/runtime) dependency were found, but they required a higher minimum deployment target. Err2. iOS 실행할때 run-ios --no-packager --simulator="iPhone 15" Build description signature: fc1341421f84b87c5245d346c2c17b66 Build description path: /Users/nowonjae/Library/Developer/Xcode/DerivedData/nexlabts-argvodqcybjfcybstpulfpghnzvm/Build/Intermediates.noindex/XCBuildData/fc1341421f84b87c5245d346c2c17b66.xcbuilddata /Users/nowonjae/Desktop/project/NeXLabRN/ios/nexlabts.xcodeproj:1:1: error: Unable to open base configuration reference file '/Users/nowonjae/Desktop/project/NeXLabRN/ios/Pods/Target Support Files/Pods-nexlabts/Pods-nexlabts.release.xcconfig'. (in target 'nexlabts' from project 'nexlabts') warning: Unable to read contents of XCFileList '/Target Support Files/Pods-nexlabts/Pods-nexlabts-resources-Release-output-files.xcfilelist' (in target 'nexlabts' from project 'nexlabts') warning: Unable to read contents of XCFileList '/Target Support Files/Pods-nexlabts/Pods-nexlabts-frameworks-Release-output-files.xcfilelist' (in target 'nexlabts' from project 'nexlabts') error: Unable to load contents of file list: '/Target Support Files/Pods-nexlabts/Pods-nexlabts-frameworks-Release-input-files.xcfilelist' (in target 'nexlabts' from project 'nexlabts') error: Unable to load contents of file list: '/Target Support Files/Pods-nexlabts/Pods-nexlabts-frameworks-Release-output-files.xcfilelist' (in target 'nexlabts' from project 'nexlabts') warning: Run script build phase 'Bundle React Native code and images' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'nexlabts' from project 'nexlabts') warning: Run script build phase '[CP] Embed Pods Frameworks' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'nexlabts' from project 'nexlabts') error: Unable to load contents of file list: '/Target Support Files/Pods-nexlabts/Pods-nexlabts-resources-Release-input-files.xcfilelist' (in target 'nexlabts' from project 'nexlabts') error: Unable to load contents of file list: '/Target Support Files/Pods-nexlabts/Pods-nexlabts-resources-Release-output-files.xcfilelist' (in target 'nexlabts' from project 'nexlabts') warning: Run script build phase '[CP] Copy Pods Resources' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'nexlabts' from project 'nexlabts') --- xcodebuild: WARNING: Using the first of multiple matching destinations: { platform:iOS Simulator, id:B5AA2E84-4F83-4749-A986-A1FCE5E398A3, OS:17.5, name:iPhone 15 } { platform:iOS Simulator, id:B5AA2E84-4F83-4749-A986-A1FCE5E398A3, OS:17.5, name:iPhone 15 } ** BUILD FAILED ** ] Err3. Xcode 로 Build 할때 (Any iOS Simulator Device (arm64, x86_64)) Command PhaseScriptExecution failed with a nonzero exit code
개발자
#reactnative
#xcode
#reactnative-run-ios
답변 1
댓글 0
조회 421
일 년 전 · 익명 님의 질문 업데이트
api의 첫번째 호출 이후부터 antd Button 렌더링 안되는 이슈가 있습니다.
```jsx import { Popover, Modal, Button, Image, Result } from "antd"; const [prevImg, setPrevImg] = useState(["any"]); const [loading, setLoading] = useState(false); const [removeImgFiles, setRemoveImgFiles] = useState([]); const combinePrevImages = (prevImages, newImages) => { const combinedImages = [...prevImages, ...newImages]; return combinedImages; }; useEffect(() => { const postSeg = async () => { try { const res = await axios.post( "apiurl", { filepath: filePath, clips: sortableList.map(list => `${list.seg.start}-${list.seg.end}`), frame: frameValue }, { proxy: false } ); return res.data; } catch (error) { console.error("Error posting segments:", error); return []; } finally { setLoading(false); } }; const postSegments = async () => { if (segments[0]?.start === 0 && segments[0]?.end === 0) return; if (sortableList && filePath) { setLoading(true); const res = await postSeg(); const combinedPrevImg = combinePrevImages(prevImg, res.results); setPrevImg(combinedPrevImg); console.log("Post Request Success"); } }; postSegments(); }, [filePath, segments, frameValue]); const handleModalOpen = useCallback(() => setModalOpen(true), []); const handleModalClose = useCallback(() => { setRemoveImgFiles([]); setModalOpen(false); }, []); const handleDeleteButtonClick = async () => { if (removeImgFiles.length > 0) { setPrevImg([...removeImgFiles]); setRemoveImgFiles([]); } else { const result = await showSwal({ title: "Are you sure delete?", showCancelButton: true, confirmButtonText: "Confirm", cancelButtonText: "Cancel", confirmButtonColor: "#3085d6", cancelButtonColor: "#d33" }); if (result.isConfirmed) { setRemoveImgFiles([...prevImg]); setPrevImg([]); } const success = await Promise.all(removeImgFiles.map(deleteFiles)); return success; } } const handleRemoveFinish = async () => { if (removeImgFiles) { for (const filePath of removeImgFiles) { try { await removeFile(filePath); } catch (e) { console.log("File Remove Error", e); } } } setRemoveImgFiles([]); handleModalClose(); }; return ( <motion.div initial={{ x: width }} animate={{ x: 0 }} exit={{ x: width }} transition={mySpring} > <div style={{ fontSize: 12, padding: "0 5px", color: "var(--gray12)", display: "flex", justifyContent: "space-between", alignItems: "center" }} > <FaAngleRight title={t("Close sidebar")} size={20} className="angle-right" role="button" onClick={toggleSegmentsList} /> {header} <FaExpandArrowsAlt title={t("Image Inspection")} size={18} className="expand-arrow-alt" style={{ cursor: "pointer" }} role="button" onClick={!loading ? handleModalOpen : handleModalClose} /> <Modal title={t("Image Inspection")} centered onCancel={handleModalClose} open={modalOpen} footer={[]} width="100%" > <div className="imagecontainer"> <Button danger className="toggle-remove" onClick={handleDeleteButtonClick}> {removeImgFiles.length > 0 ? "Add" : "Remove"} </Button> {prevImg?.length > 10 && prevImg.map(img => ( <Popover key={img}> {removeImgFiles?.includes(img) ? ( <span> <Result className="result" icon={<FaSmile />} subTitle="delete" /> </span> ) : <Image key={uuidv4()} src={img} preview={{ src: img }} alt={uuidv4()} /> )} </Popover> ))} </div> <Button block onClick={handleRemoveFinish}> Finish </Button> </Modal> </div> ) ``` api 호출을 통해 frameValue 개수(여기서는 12개씩) 만큼 이미지를 렌더링 하고 있는데 두번째 호출부터는 Button이 렌더링되지 않아서 어디가 잘못됐는지 알고싶습니다.. 필요한 부분이 imagecontainer 클래스네임인 div를 렌더링 해야합니다.
개발자
#react
답변 0
댓글 0
조회 81
개발자 선생님들 도와주세요..
안녕하세요 초보개발자입니다 지금 구글로 코드 복붙하며 게시판 수정중인데 아예 똑같이 복붙 하였는데 저는 왜 이런 식으로 나올까요 도와주세요 .. ㅠㅠ 프로젝트 발표가 코앞인데.. 1번째사진은 작성자의 사진이고 2번째 사진이 제 출력 화면입니다... 코드는 댓글에 적어두겠습니다..도와주세요.. ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <!--부트스트랩은 어떤device로 접속하더라도 해상도에 맞게 알아서 설정되는 탬플릿이다. --> <meta name="viewport" content="width=device-width" , inital-scale="1"> <!--스타일시트를 참조, 주소는 css안에 부트스트랩.css--> <link rel="stylesheet" href="css/bootstrap.css"> <title>JSP 게시판 웹 사이트</title> </head> <body> <!-- 네비게이션 구현 네비게이션이라는 것은 하나의 웹사이트의 전반적인 구성을 보여주는 역할 --> <nav class="navbar navbar-default"> <!-- header부분을 먼저 구현해 주는데 홈페이지의 로고같은것을 담는 영역이라고 할 수 있다. --> <div class="navbar-header"> <!-- <1>웹사이트 외형 상의 제일 좌측 버튼을 생성해준다. data-target= 타겟명을 지정해주고--> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-exmaple="false"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <!-- 여긴 웹페이지의 로고 글자를 지정해준다. 클릭 시 main.jsp로 이동하게 해주는게 국룰 --> <a class="navbar-brand" href="main.jsp">JSP 게시판 웹 사이트</a> </div> <!-- 여기서 <1>에만든 버튼 내부의 데이터 타겟과 div id가 일치해야한다. --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <!-- div 내부에 ul은 하나의 어떠한 리스트를 보여줄때 사용 --> <ul class="nav navbar-nav"> <!-- 리스트 내부에 li로 원소를 구현 메인으로 이동하게만들고--> <li><a href="main.jsp">메인</a></li> <!-- 게시판으로 이동하게 만든다. --> <li><a href="bbs.jsp">게시판</a></li> </ul> <!-- 리스트 하나 더 생성 웹페이지 화면에서 우측 부분--> <ul class="nav navbar-nav navbar-right"> <!-- 원소를 하나 구현해 준다. 네비게이션 우측 슬라이드메뉴 구현 --> <li class="dropdown"> <!-- 안에 a태그를 하나 삽입한다. href="#"은 링크없음을 표시한다. --> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">접속하기<span class="caret"></span></a> <!--접속하기 아래에 드랍다운메뉴 생성 --> <ul class="dropdown-menu"> <!-- li class="active" 현재 선택된 홈페이지를 의미 --> <li><a href="login.jsp">로그인</a></li> <li class="active"><a href="join.jsp">회원가입</a></li> </ul> </li> </ul> </div> <!-- 네비게이션 바 구성 끝 --> </nav> <!-- 하나의 컨테이너처럼 감싸주는 역할 --> <div class="container"> <div class="col-lg-4"></div> <!-- 회원가입 폼은 위의 양식은 일치하며, 이제 내부 폼만 바꿔준다. --> <div class="col-lg-4"> <div class="jumbotron" style="padding-top: 20px;"> <!-- 양식 삽입 post는 회원가입이나 로그인같이 어떠한 정보값을 숨기면서 보내는 메소드/ 로그인 Action페이지로 정보를보내겠다--> <form method="post" action="joinAction.jsp"> <!-- 회원 가입에 맞게 위에 액션은 joinAction페이지로 밑에 제목은 회원가입 화면으로 변경 --> <h3 style="text-align: center;">회원가입 화면</h3> <div class="form-group"> <!-- 회원 가입에서도 userID or userPassword는 동일하게 가져가고, 회원가입에 필요한 나머지 속성추가 --> <input type="text" class="form-control" placeholder="아이디" name="userID" maxlength="20"> </div> <div class="form-group"> <input type="password" class="form-control" placeholder="비밀번호" name="userPassword" maxlength="20"> </div> <!-- userName 추가 --> <div class="form-group"> <input type="text" class="form-control" placeholder="이름" name="userName" maxlength="20"> </div> <!-- 성별 선택 추가 --> <div class="form-group" style="text-align: center;"> <!-- 버튼 공간을 따로 마련해준다.(남,녀) --> <div class="btn-group" data-toggle="buttons"> <!-- 선택이 된곳에 표시를 하는 active를 설정해준다. --> <label class="btn btn-primary active"> <input type="radio" name="userGender" autocomplete="off" value="남자" checked>남자 </label> <label class="btn btn-primary"> <input type="radio" name="userGender" autocomplete="off" value="여자" checked>여자 </label> </div> <!-- 성별 선택부분 완료 --> </div> <!-- email 작성부분 구현 --> <div class="form-group"> <!-- placeholder는 아무런 입력이 없을때 띄워주는 값 --> <input type="email" class="form-control" placeholder="이메일" name="userEmail" maxlength="20"> </div> <!-- 버튼 또한 회원가입으로 value변경 --> <input type="submit" class="btn btn-primary form-control" value="회원가입"> </form> </div> </div> <div class="col-lg-4"></div> </div> <!-- 애니메이션을 담당하게 될 자바스크립트 참조 --> <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> <!-- 특정홈페이지에서 제이쿼리 호출 --> <script src="js/bootstrap.js"></script> </body> </html>
개발자
#jsp
#java
답변 2
댓글 4
보충이 필요해요 3
조회 360
일 년 전 · 닉네임을 등록해주세요 님의 질문
VM에 VPN(Wireguard)을 통한 접속 방법
안녕하세요. 제발 도움 부탁드리겠습니다. *** 제가 궁극적으로 하고 싶은 것 : 외부에서 노트북으로, 저희 집 데스크톱에 VM으로 띄워 놓은 서버에 VPN을 통해서 접속 (네트워크 지식이 부족하여, 어느 부분이 빠졌는지, 뭘 고려해야하는지, 뭘 알아야하는지... 등 조언과 훈수 부탁드립니다. 구체적인 방법을 알려주시면 가장 좋고요ㅠ) 현재 저의 상태입니다. 1. LG 유플러스 인터넷 사용, 집에 있는 데스크톱에 랜선을 꽂아서 인터넷 사용중 (IP : 192.168.219.102) 2. VMware - Bridged 방식으로 VM 서버(Ubuntu 22.04) 하나를 띄워 놓음 (IP : 192.168.219.201) 3. 위의 VM 서버에 Wireguard VPN을 설치 (VPN 서버 + 개인용 웹서버로 사용하기 위해) 4. https://jjeongil.tistory.com/2062 블로그를 보며 VPN 서버 구축을 함 5. Wireguard 설정 ㅇ 서버측 wireguard 설정(VM) [Interface] Address = 192.168.219.1/24 SaveConfig = true PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens33 -j MASQUERADE ListenPort = 51820 PrivateKey = xxxxxxxxxx= [Peer] PublicKey = xxxxxxxxxx= AllowedIPs = 192.168.219.202/32 ------------------------------------------------------------- ㅇ 클라이언트쪽 wireguard 설정(노트북) [Interface] PrivateKey = xxxxxxxxxx= Address = 192.168.219.202/24 [Peer] PublicKey = xxxxxxxxxx= AllowedIPs = 0.0.0.0/0 Endpoint = 192.168.219.201:51820 ============================================================= [ 로그 ] 2023-09-22 16:18:28.666678: [TUN] [srm-pjt-vm-server] Starting WireGuard/0.5.3 (Windows 10.0.22621; amd64) 2023-09-22 16:18:28.667384: [TUN] [srm-pjt-vm-server] Watching network interfaces 2023-09-22 16:18:28.669947: [TUN] [srm-pjt-vm-server] Resolving DNS names 2023-09-22 16:18:28.669947: [TUN] [srm-pjt-vm-server] Creating network adapter 2023-09-22 16:18:28.750000: [TUN] [srm-pjt-vm-server] Using existing driver 0.10 2023-09-22 16:18:28.762403: [TUN] [srm-pjt-vm-server] Creating adapter 2023-09-22 16:18:28.967072: [TUN] [srm-pjt-vm-server] Using WireGuardNT/0.10 2023-09-22 16:18:28.967588: [TUN] [srm-pjt-vm-server] Enabling firewall rules 2023-09-22 16:18:28.938662: [TUN] [srm-pjt-vm-server] Interface created 2023-09-22 16:18:28.972410: [TUN] [srm-pjt-vm-server] Dropping privileges 2023-09-22 16:18:28.972410: [TUN] [srm-pjt-vm-server] Setting interface configuration 2023-09-22 16:18:28.972932: [TUN] [srm-pjt-vm-server] Peer 1 created 2023-09-22 16:18:28.974501: [TUN] [srm-pjt-vm-server] Monitoring MTU of default v4 routes 2023-09-22 16:18:28.974501: [TUN] [srm-pjt-vm-server] Interface up 2023-09-22 16:18:28.977259: [TUN] [srm-pjt-vm-server] Setting device v4 addresses 2023-09-22 16:18:28.995686: [TUN] [srm-pjt-vm-server] Monitoring MTU of default v6 routes 2023-09-22 16:18:29.023405: [TUN] [srm-pjt-vm-server] Setting device v6 addresses 2023-09-22 16:18:29.072431: [TUN] [srm-pjt-vm-server] Startup complete 2023-09-22 16:18:29.070847: [TUN] [srm-pjt-vm-server] Sending handshake initiation to peer 1 (192.168.219.201:51820) 2023-09-22 16:18:34.106156: [TUN] [srm-pjt-vm-server] Handshake for peer 1 (192.168.219.201:51820) did not complete after 5 seconds, retrying (try 2) 2023-09-22 16:18:34.106156: [TUN] [srm-pjt-vm-server] Sending handshake initiation to peer 1 (192.168.219.201:51820) 2023-09-22 16:18:39.107654: [TUN] [srm-pjt-vm-server] Sending handshake initiation to peer 1 (192.168.219.201:51820) 2023-09-22 16:18:44.115294: [TUN] [srm-pjt-vm-server] Sending handshake initiation to peer 1 (192.168.219.201:51820) 2023-09-22 16:18:49.267198: [TUN] [srm-pjt-vm-server] Handshake for peer 1 (192.168.219.201:51820) did not complete after 5 seconds, retrying (try 2) 2023-09-22 16:18:49.267198: [TUN] [srm-pjt-vm-server] Sending handshake initiation to peer 1 (192.168.219.201:51820) 2023-09-22 16:18:54.340284: [TUN] [srm-pjt-vm-server] Handshake for peer 1 (192.168.219.201:51820) did not complete after 5 seconds, retrying (try 2) 2023-09-22 16:18:54.340284: [TUN] [srm-pjt-vm-server] Sending handshake initiation to peer 1 (192.168.219.201:51820) 2023-09-22 16:18:59.355253: [TUN] [srm-pjt-vm-server] Sending handshake initiation to peer 1 (192.168.219.201:51820) 2023-09-22 16:19:04.414034: [TUN] [srm-pjt-vm-server] Handshake for peer 1 (192.168.219.201:51820) did not complete after 5 seconds, retrying (try 2) 2023-09-22 16:19:04.414034: [TUN] [srm-pjt-vm-server] Sending handshake initiation to peer 1 (192.168.219.201:51820) 2023-09-22 16:19:07.916126: [TUN] [srm-pjt-vm-server] Shutting down 2023-09-22 16:19:07.922350: [MGR] [srm-pjt-vm-server] Tunnel service tracker finished
개발자
#network
#ubuntu
#vpn
#wireguard
#vm
답변 0
댓글 0
조회 346
9달 전 · 최용빈 님의 답변 업데이트
파이썬 오류 좀 고쳐주세요 ㅠㅠ
import time import requests import streamlit as st API_BASE_URL = "http://localhost:8000/qna" # Fastapi로 api 생성 def request_chat_api(user_message: str) -> str: url = API_BASE_URL resp = requests.post( url, json={ "user_message": user_message, }, ) resp = resp.json() print(resp) return resp["answer"] def init_streamlit(): st.set_page_config(page_title='Dr. KHU', page_icon='🩺') if "messages" not in st.session_state: st.session_state.messages = [{"role": "assistant", "content": "안녕하세요! Dr.seo입니다🩺"}] # Initialize chat history if "messages" not in st.session_state: st.session_state.messages = [] # Display chat messages from history on app rerun for message in st.session_state.messages: with st.chat_message(message["role"]): st.markdown(message["content"]) def chat_main(): if message := st.chat_input(""): # Add user message to chat history st.session_state.messages.append({"role": "user", "content": message}) # Display user message in chat message container with st.chat_message("user"): st.markdown(message) # Display assistant response in chat message container assistant_response = request_chat_api(message) with st.chat_message("assistant"): message_placeholder = st.empty() full_response = "" for lines in assistant_response.split("\n"): for chunk in lines.split(): full_response += chunk + " " time.sleep(0.05) # Add a blinking cursor to simulate typing message_placeholder.markdown(full_response) full_response += "\n" message_placeholder.markdown(full_response) # Add assistant response to chat history st.session_state.messages.append( {"role": "assistant", "content": full_response} ) if __name__ == "__main__": init_streamlit() chat_main() 이 코드를 실행시키면 자꾸 AttributeError: st.session_state has no attribute "messages". Did you forget to initialize it? More info: https://docs.streamlit.io/library/advanced-features/session-state#initialization 라고 뜨네요..
개발자
#파이썬
#python
답변 2
댓글 1
보충이 필요해요 2
조회 333
10달 전 · 익명 님의 새로운 댓글
타입스크립트 타입지정
리액트 쿼리로 OptimisticUpdate 를 구현했는데 onError 에서 context 타입 지정을 어떻게 해야할지 모르겠습니다 ㅠㅠ context : 타입 하면 오류나고, data : 타입 = context 해도 오류나고 as 를 쓰면 해결되긴 하는데 더 좋은 방법 없을까요? ㅠㅠㅠ 'use client'; import { useState } from 'react'; import { toast } from 'react-toastify'; import { usePostLikeCount } from '@/hooks'; interface LikeContextType { previousLikeCount: number; previousIsLike: boolean; } export const useOptimisticLike = ( boardId: number, initialLikeCount: number, initialIsLike: boolean, refetch: () => void ) => { const [optimisticLikeCount, setOptimisticLikeCount] = useState(initialLikeCount); const [optimisticIsLike, setOptimisticIsLike] = useState(initialIsLike); const { mutate: postMutate } = usePostLikeCount(boardId, { onMutate: async (): Promise<LikeContextType> => { setOptimisticLikeCount((prev) => optimisticIsLike ? prev - 1 : prev + 1 ); setOptimisticIsLike((prev) => !prev); return { previousLikeCount: optimisticLikeCount, previousIsLike: optimisticIsLike, }; }, onError: (err, variables, context) => { const data: LikeContextType = context; if (data) { setOptimisticLikeCount(data.previousLikeCount); setOptimisticIsLike(data.previousIsLike); } toast.error('좋아요 업데이트에 실패했습니다.'); }, onSuccess: () => { refetch(); }, }); const uploadLike = () => { postMutate(); }; return { optimisticLikeCount, optimisticIsLike, uploadLike, }; };
개발자
#react-query
#typescript
답변 1
댓글 1
조회 54
10달 전 · 익명 님의 질문
React Spring 배포과정 중 의문의 404
react + spring boot로 진행하는 프로젝트가 현재 cloudtype이라는 플랫폼으로 배포중에 있습니다. 문제는 정확한 서버주소를 호출하는 것 같음에 불구하고 404 에러가 발생하여 해결하지 못하고 있습니다. 현재, 아래 사진과 같은 로그가 클라이언트, 서버에 각각 발생합니다. 서버에서는 다음과 같이 구성되어있고 @RestController @RequestMapping("/v1/login") @RequiredArgsConstructor @CrossOrigin(origins = "https://web-secondchance-front-bug-1cupyg2klvnmgdft.sel5.cloudtype.app") public class KakaoController { private final KakaoService kakaoService; private final Logger LOGGER = LoggerFactory.getLogger(KakaoController.class); @PostMapping("/kakao-login") public ResponseEntity<UserDto> kakaoLogin(@RequestBody KakaoLoginDto kakaoLoginDto) { String code = kakaoLoginDto.getCode(); LOGGER.info("Get Code from FrontEnd : {}", code); LOGGER.info("Request getAccessToken()"); kakaoLoginDto = kakaoService.getAccessToken(code); String accessToken = kakaoLoginDto.getAccess_token(); LOGGER.info("access_token : {}", accessToken); if(accessToken != null){ UserDto userDto = kakaoService.getUserInfo(accessToken); return ResponseEntity.ok(userDto); } else { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); } // accessToken이 null임에도 getUserInfo를 부름. // 안부르게 끔 위의 방법을 포함하여 // 1. map에서 true, false를 사용하여 해봄 // 2. getAccessToken을 map객체로 반환하게끔 하여 accessToken이 있으면 true, 없으면 false로 하여 isEmpty 함수로 체크하여 부름 // 위의 두 방법 전부 소용없음. 그냥 getUserInfo를 부름. } @PostMapping("/kakao-logout") public String kakaoLogout(){ return "ok"; } } 현재 리액트에서는 다음과 같이 axios.post로 접근하여 code를 전달합니다. 무엇이 문제일까요?
개발자
#react
#spring-boot
#배포
#404
답변 0
댓글 0
추천해요 1
조회 147
일 년 전 · 고건 님의 새로운 댓글
nginx 관련 질문 있습니다 ㅠㅠ
안녕하세요, 현재 프로그래밍을 공부하고 있는 학생입니다. 공부를 하던 중 django를 사용해 프로젝트를 진행했고 aws, nginx, uwsgi 로 배포를 진행하게 되었는데, 배포는 성공적으로 됐지만 처리해야할 데이터가 많은 기능을 사용하면 자꾸 아래 오류가 뜨더군요. (퍼블릭 ip 주소는 X로 가렸습니다) 2023/11/07 15:14:13 [error] 7487#7487: *1 upstream timed out (110: Unknown error) while reading response header from upstream, client: xx.xxx.xxx.xxx, server: _, request: "POST /file_upload/upload/ HTTP/1.1", upstream: "uwsgi://unix:/home/ubuntu/docusift/uwsgi.sock", host: "xx.xxx.xxx.xx", referrer: "http://xx.xxx.xxx.xx/success_with_token/WeDkQYs84hDYcDsl/" 구글링을 해봐도, 스택오버플로우를 찾아봐도 110 오류가 unknown error로 뜨는 것에 대한 해결책은 나오지 않아서 이렇게 여쭤보게 되었습니다. 다만 구글링을 해본 결과 설정을 따로 만져줘야 한다는 것을 봐서 설정은 아래처럼 해놓은 상태인데, 아직 해결은 되지 않은 상황입니다. [uwsgi] chdir=/home/ubuntu/docusift/blog module=blog.wsgi:application master=True pidfile=/tmp/project-master.pid vacuum=True max-requests=5000 daemonize=/home/ubuntu/docusift/debug_uwsgi.log home=/home/ubuntu/docusift/venv virtualenv=/home/ubuntu/docusift/venv socket=/home/ubuntu/docusift/uwsgi.sock chmod-socket=666 socket-timeout=600 harakiri = 300 http-timeout = 300 server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name _; location / { include /etc/nginx/uwsgi_params; uwsgi_pass django; proxy_buffer_size 512k; proxy_buffers 16 512k; proxy_busy_buffers_size 1024k; proxy_connect_timeout 500s; proxy_send_timeout 500s; proxy_read_timeout 500s; send_timeout 500s; } location /static/ { alias /home/ubuntu/docusift/blog/staticfiles/; } http { upstream django { server unix:/home/ubuntu/docusift/uwsgi.sock; } client_max_body_size 100M; proxy_connect_timeout 800s; proxy_send_timeout 800s; proxy_read_timeout 3600; 혹시라도 해결 방법을 아시는 분들 답변 주시면 정말 감사하겠습니다!!!
개발자
#배포
#aws
#ubuntu
#nginx
#uwsgi
답변 1
댓글 1
조회 173
react axios 로 api호출시 recoil value 전달 실패
회원가입 마지막 단계 페이지인 관심태그 페이지입니다. 이미 nickName, email, phoneNum, pwd, subGroup, workYear는 recoil의 userState에 저장된 상태입니다. 다음 코드를 실행하면 api 호출에는 성공하는데, isSuccess가 false가 되면서 '이메일을 입력해주세요'라는 message가 뜨고 회원가입 실패 alert 창이 뜹니다. 아무래도 recoil value의 전달에 실패한 것 같은데 왜 그럴까요? 참고로 api 주소는 가짜로 적었습니다. function InterestTag() { const [user, setUser] = useRecoilState(userState); const [interestIdx, setInterestIdx] = useRecoilState(userState); const [buttonColor, setButtonColor] = useState("f1f4f7"); const nickName = useRecoilValue(userState).nickName; const email = useRecoilValue(userState).email; const phoneNum = useRecoilValue(userState).phoneNum; const pwd = useRecoilValue(userState).pwd; const subGroup = useRecoilValue(userState).subGroup; const workYear = useRecoilValue(userState).workYear; const handleTagClick = (interestIdx) => { setInterestIdx(interestIdx); setUser({ ...user, interestIdx: interestIdx, isLogin: true, }); setButtonColor("#36f"); }; console.log(interestIdx); const navigate = useNavigate(); const handleSubmit = () => { axios .post("https://abcd.shop/users", { data: { nickName: nickName, email: email, phoneNum: phoneNum, pwd: pwd, subGroup: subGroup, workYear: workYear, interestIdx: interestIdx, }, }) .then((response) => { console.log(response.data); if (response.data.isSuccess === true) { alert("회원가입 성공"); navigate("/"); } else { alert("회원가입 실패"); } }); };
개발자
#react
#axios
#recoil
답변 1
댓글 0
조회 346
Gmail이 안 보내져요 ㅠㅠ 퇴근하고 싶어요
서버 비용 잇슈로 이관 진행 중에 있습니다. 그런데 이전 서버인 AWS에서는 Gmail이 정상적으로 전송이 됬는데 카페24로 이관을 하고선 Gmail 전송이 안되고 있습니다. 차이는 Nginx를 안사용하다가 사용하게된 차이가 있습니다. 방화벽 인바운드, 아웃바운드 설정을 해줬고요 로그를 확인해 보니 이런 에러만 나오는데 스택오버에서는 같은 질문에 답변이 안 달려 있더라고요 0|npm | [0] info: chet createShowhostChat updateMember {"timestamp":"2023-04-17 18:28:50"} 0|npm | [0] [2023-04-17 09:28:50] DEBUG Sending mail using SMTP/6.8.0[client:6.8.0] 0|npm | [0] 0|npm | [2023-04-17 09:28:50] DEBUG [SDdf79wZJFg] Resolved smtp.gmail.com as 74.125.23.109 [cache hit] 0|npm | [0] [2023-04-17 09:28:50] ERROR [TSzLl35tpQ] Connection timeout 0|npm | [0] 0|npm | [2023-04-17 09:28:50] DEBUG [TSzLl35tpQ] Closing connection to the server using "destroy" 0|npm | [0] 0|npm | [2023-04-17 09:28:50] ERROR Send Error: Connection timeout 소스는 이렇게 구성되어 있습니다. 예상은 SMTP 587 Port가 활성화가 아니구나라고 생각을 했는데 잘 안되더라고요 선배님들 도와주세요 ㅠㅠ 추가 로그 입니다. 0|npm | [0] [2023-04-17 11:51:32] DEBUG Sending mail using SMTP/6.8.0[client:6.8.0] 0|npm | [0] [2023-04-17 11:51:32] DEBUG [4tmiO0CAyPQ] Resolved smtp.gmail.com as 64.233.188.109 [cache hit] 0|npm | [0] POST /showhost/approval/approve - - - - ms 0|npm | [0] 0|npm | info: request url : /root/path/to/custom/error/path/500.html {"timestamp":"2023-04-17 20:52:32"} 0|npm | [0] error: app.js/404 {"timestamp":"2023-04-17 20:52:32"} 0|npm | [0] GET /root/path/to/custom/error/path/500.html 404 9 - 3.101 ms 0|npm | [0] [2023-04-17 11:53:02] ERROR [m98HJ7ZDhGM] Connection timeout 0|npm | [0] [2023-04-17 11:53:02] DEBUG [m98HJ7ZDhGM] Closing connection to the server using "destroy" 0|npm | [0] [2023-04-17 11:53:02] ERROR Send Error: Connection timeout 0|npm | [0] error: app.js/500 {"timestamp":"2023-04-17 20:53:02"} 왜 저에게 이런 시련이 ㅠㅠ 원인조차 모르겠습니다. ㅠㅠ 빨리 해결해 퇴근하고 싶습니다.
개발자
#node
#gmail
#방화벽
#smtp
답변 2
댓글 1
추천해요 1
조회 517
2년 전 · 엄홍재 님의 새로운 답변
nextjs 초보 fetch & DELETE 동작이 안되요.
app/api/list/[id]/route.js export async function DELETE(request, {params}) { const id = params.id; const {searchParams} = request.nextUrl; const sort = searchParams.get('sort'); return NextResponse.json({message: 'test', id, sort}); } 위처럼 되어있고, app/list/ListItem.js <button className="blue"> <span onClick={() => { fetch('/api/list/' + post._id, { method: 'DELETE' }).then(() => { console.log('call delete'); }); }}>삭제</span> </button> 위 처럼 코드를 작성했는데, DELETE route가 실행이 되지 않습니다. 어떻게 해야 하나요?... POST의 경우에는 아래와 같은데 동작이 잘 되서요.. app/write/route.js export async function POST(request) { const data = await request.formData(); let body = Object.fromEntries(data); const db = (await connectDB).db('exam'); await db.collection('post').insertOne(body); return new Response('POST'); } app/write/page.js <form action="/api/write" method="POST"> <input type="text" name="title" placeholder="제목"/> <br/> <input type="text" name="content" placeholder="내용"/> <button type="submit">NEW</button> </form>
개발자
#nextjs
답변 1
댓글 0
조회 168
<input type="file"> 관련하여..
<template> <label for="camera1"> 촬영 </label> <input type="file" id="camera1" accept="image/*" capture="camera" style="display: none" @change="onStartFileSelected" /> </template> <script> const startFile = ref({}) //@change const onStartFileSelected = event => { const startFileInfo = event.target.files[0] startFile.value = startFileInfo if (startFileInfo) { startImageYn.value = 'Y' console.log('startFileInfo', typeof startFileInfo) } else { startImageYn.value = ' ' console.log('no image') } } // 파일 포함 다음 상태 업데이트하는 api const fileUpdateStatusApiHandler = async () => { const formData = new FormData() console.log('startFile===',startFile.value)//File형식 데이터 정상 찍힘 -> 타입 : 객체(Object) console.log('startFile',JSON.stringify(startFile.value)) //안찍힘???왜?????? 객체->스트링으로 바꿈 formData.append('file_upload', JSON.stringify(startFile.value),startFile.value) //빈값이 들어감.. try { const res: any = await ApiCert.post( API_URL.url, formData, { headers: { 'Content-Type': 'multipart/form-data' } } ) console.log('response =====', res) if (res.resCode === 'OK') { console.log('OK') } else { alert(res.resMsg) } } catch (err: any) { console.log('error =====', err) } } </script> file형식 데이터를 api보낼때 formData에 넣어 보내고싶은데 file이 안들어가네요.. file_upload: {} 빈값으로 들어갑니다. 도와주세용
개발자
#input
#type="file"
#vue3
#javascript
#form-data
답변 2
댓글 0
조회 180
일 년 전 · 익명 님의 새로운 댓글
COPY(PG) GC 오버헤드 에러
안녕하세요. 대용량의 텍스트 파일을 postgreSql에 적재하는 모듈을 개발하고 있습니다. copy 함수를 활용하여 텍스트 파일('|'으로 구분되어 있는)을 테이블에 insert 하는데 헤더 스킵을 위해 csv로 parsing하려고 합니다. 근데 파일이 커서 그런가(8GB정도) 'OutOfMemoryError : gc overhead limit exceeded' 에러가 계속 발생합니다.. (어떨 땐 에러 없이 잘 들어가기도 합니다) 코드 중에 불필요한 구문이 있는 건지 판단이 잘 안됩니다... 또 csv로 파싱하지 않고 텍스트 파일의 첫째 줄을 지우고 copy로 밀어 넣는 방법이 있을까요? --------구현 코드-------- try ( BaseConnection c = dataSource.getConnection().unwrap(BaseConnection.class)) { try ( PGCopyOutputStream os = new PGCopyOutputStream(c, "COPY " + tableName + " FROM STDIN WITH (FORMAT CSV)"); CSVPrinter writer = new CSVPrinter(new OutputStreamWriter(os, StandardCharsets.UTF_8), CSVFormat.POSTGRESQL_CSV); CSVParser reader = new CSVParser(new InputStreamReader(inputStream, charset), CSVFormat.INFORMIX_UNLOAD.withFirstRecordAsHeader())) { for (CSVRecord row : reader) { for (String col : row) { if (col != null && StringUtils.hasText(col.trim())) { writer.print(col.trim()); } else { writer.print(null); } } writer.println(); } } } *inputStream은 해당 파일 BufferedInputStream 객체입니다.
개발자
#postgresql
#error
답변 1
댓글 1
조회 75
일 년 전 · 손우진 님의 새로운 답변
nextauth 를 이용해 springboot 의 jwt를 받아와서 로그인을 구현중입니다.
안녕하세요. nextauth 를 이용해 로그인 구현중입니다. 흔히 생각하는 소셜 로그인이 아닌 username 과 password를 통해 springboot security 에서 jwt를 반환 받아오려고 합니다. // app/api/auth/[...nextauth]/route.ts CredentialsProvider({ name: 'Credentials', credentials: { username: { label: 'Username', type: 'text', placeholder: '아이디' }, password: { label: 'Password', type: 'password' }, }, async authorize(credentials, req) { const res = await fetch(`${process.env.NEXTAUTH_URL}/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ username: credentials?.username, password: credentials?.password, }), }); const user = await res.json(); console.log(user); if (user) { return user; } else { return null; } }, }), 그런데 위의 코드처럼 코드를 구성했을때 .env.local 파일의 NEXTAUTH_URL 이 등록이 되면 authorize 가 작동하지 않습니다 . 에러 log라도 있으면 어떻게라도 해보겠는데.. 그것도 없습니다. 그래서 NEXTAUTH_URL 를 등록하지 않고 const res = await fetch(`http://localhost:8080/auth`, 바꾸면 이것역시 에러 log 없이 브라우저상에서 Error 라는 문구만 보여줍니다. 이렇게 생각했을때 authorize는 값을 내부에서만 가져올수 있는거 같은데요. 실제로 가상의 const user = {....} 를 만들어서 반환하면 로그인이 아주 잘 됩니다. 하지만 제가 원하는 방법은 아니죠..ㅍ 검색해보면 prisma 가 많이 나오는데.. 그것 또한 시스템상 제가 원하는 방식이 아닙니다. springboot security 에서 jwt를 받아와서 nextauth에 로그인을 할수 있는 방법은 없을까요? custom login 페이지를 만들어서 해야 할거 같은데 방법을 잘 모르겠습니다. 현재 springboot 서버에 cors 설정이 정상적으로 허용된 상태입니다.
개발자
#nextauth
#springboot
#jwt
#nextjs
#typescript
답변 1
댓글 0
조회 1,203
Type error: Property 'session' does not exist on type '{}' (nextjs auth google 연동)
next-auth 라이브러리를 사용해서 구글 로그인을 구현하고있는데 에러가 발생합니다. https://dantechblog.gatsbyjs.io/posts/next-auth/ 이 글을 따라서 연동중이고 import type { AppProps } from "next/app"; import {SessionProvider} from 'next-auth/react'; const App = ({Component, pageProps}:AppProps) => { return ( <SessionProvider session={pageProps.session}> <Component {...pageProps} /> </SessionProvider> ); } export default App; 위와 같이 작성한 코드에서 pageProps가 session 타입을 가지고 있지 않다고 에러가 나옵니다.. (Type error: Property 'session' does not exist on type '{}' ) 혹시 next-auth로 구글 연동하신 분들 같은 이슈 해결해본적 있으신가요??
개발자
답변 1
댓글 0
추천해요 3
조회 319
7달 전 · 익명 님의 질문
next.js의 캐시와 react query 캐시 질문
next.js와 react query를 사용해 프로젝트를 진행하다가 이해가 안되는 현상이 있어서 질문드립니다. 어떤 A 라는 페이지에 들어오면 포스트와 포스트의 댓글들이 보이는 상황입니다. 첨부한 코드는 A 페이지를 담당하는 page.tsx 코드와 page 에서 사용중인 컴포넌트중 댓글 컴포넌트인 Comments 컴포넌트, 그리고 Comments 에서 useQuery의 queryFn으로 지정한 getComments 함수의 코드입니다. Comments 컴포넌트의 useQuery의 staleTime은 10초로 해두었고, queryFn인 getComments 함수의 fetch는 revalidate를 60초로 해둔 상황입니다. useQuery의 staleTime보다 fetch의 revalidate 시간을 길게 한건 react query로 인한 클라이언트측의 캐시와, next.js의 fetch에 의한 서버 측의 캐시의 차이점을 확인해보려고 그런것입니다. A 페이지에 처음 들어와 page 컴포넌트가 실행되면 ['posts', id, 'comments'] 쿼리로 인해 받아온 댓글(comments) 데이터가 화면에 보입니다. 이 댓글에는 랜덤으로 생성된 이미지가 있습니다. 우선 10초가 지나기 전에는 새로고침에도 기존의 데이터 그대로 보이고, fetch 요청을 받는 백엔드 api에도 요청이 들어오지 않습니다. react query로 인해 쿼리가 실행되지 않아서 그런 것이겠죠? 그러고 10초가 지나 ['posts', id, 'comments'] 쿼리가 stale 상태가 된 후에 A 페이지를 새로고침하면 ['posts', id, 'comments'] 쿼리는 다시 fresh 해지는데 백엔드 api에는 요청이 들어오지 않았더라구요. 화면상의 댓글의 이미지들도 이전과 동일하게 나옵니다. 저는 이게 "A 페이지에 들어와 page 컴포넌트가 실행되면 ['posts', id, 'comments'] 쿼리가 실행되어 fetch 요청이 실행되는데 이 ['posts', id, 'comments'] 쿼리는 서버 컴포넌트에서 프리패치 되는 거니까, 즉 fetch가 서버쪽에서 실행되는 거니까 react query의 캐시가 아닌 fetch의 캐시 설정을 따른다. 그렇기 때문에 ['posts', id, 'comments'] 쿼리가 실행되어 fetch가 실행되지만 fetch의 캐시는 남아있으니까 캐싱된 값을 사용해서 백엔드 api에는 요청이 안들어온것이다." 라고 생각했고 이걸 확인하기위해 새로고침을 해본것이었기 때문에 이 결과에 대해 납득하긴 했는데요.. 이 생각이 맞는건지가 일단 궁금합니다. 그리고 진짜 이해가 안되는건 이겁니다. A 페이지에 들어오고 10초가 지나 ['posts', id, 'comments'] 쿼리가 stale해지면 이번에는 다른 페이지로 이동했다가 A 페이지로 다시 돌아옵니다. A 페이지에서 새로고침을 하지 않고 사이트 내에서 페이지 이동으로 A 페이지에 다시 들어오는거죠. 이러면 백엔드 api에 요청이 들어오더라구요. 이게 왜 그런건지 모르겠습니다. 10초가 지나 ['posts', id, 'comments'] 쿼리는 stale 해졌지만 60초는 안지나서 fetch의 캐시는 유효한... 위의 새로고침 경우와 동일한 상황인데 새로고침 시에는 api로 요청이 안들어오고, 다른 페이지로 이동했다가 다시 돌아온 경우는 api로 요청이 들어오네요. A 페이지에서 새로고침을 하나, 다른 페이지에서 A 페이지로 페이지 이동을 하나, 둘 다 page 컴포넌트가 실행되고 ['posts', id, 'comments'] 쿼리가 서버에서 프리패치되니까 fetch가 서버에서 실행되는거 아닌가요? 근데 왜 새로고침하면 fetch의 캐싱이 적용되는것처럼 백엔드 api로 요청이 안들어오고 페이지 이동 시에는 들어올까요... 이걸 아무리 생각해도 모르겠습니다. 60초가 지난 후에는 새로고침 시에도 백엔드 api로 요청이 들어오더라구요. 이것으로보아 60초 전에는 새로고침 시 요청이 안들어오는게 fetch의 캐시 때문인것도 맞는 거 같은데, 왜 페이지 이동 시에는 60초 전에도 캐싱값을 안쓰고 api로 요청을 보내는지 모르겠습니다. 어떤 메커니즘으로 이렇게 되는것일까요? 아직 Next.js의 캐싱과 react query에 대해 잘 알지 못해서 이해가 안됩니다.. ㅠ 도와주십쇼..!
개발자
#next.js
#react-query
#프론트엔드
답변 0
댓글 0
조회 78
일 년 전 · 김태영 님의 새로운 댓글
리액트쿼리 고수분들 도와주세요
사이드프로젝트 리팩토링을 진행하는 중에 이해가 안되는 부분이 있어 글 써봅니다. const { data, isLoading, fetchNextPage } = useInfiniteQuery( ["getProducts", sortOption, sortOrder, filterValue, categoryName], async ({ pageParam = page - 1 }) => { const response = await api.post(`/cal/v1/product/${categoryName}`, { filter: filterValue, page: pageParam, query: "", size: size, => size: size - 8 /* 변경한 부분 */ sort: [{ field: sortOption, option: sortOrder }], }); setTotalProduct(response.data.body.product.totalCount); return response.data.body.product.items; }, { refetchOnWindowFocus: false, getNextPageParam: () => page, } ); 위 코드는 인피니티 스크롤을 구현한건데요, size는 한번에 받아 올 상품의 개수 입니다. 상품을 한번에 4개 받아올때는 500ms~, 8개 = 2500ms~, 12개 = 10000ms~ 정도로 요청시간이 비정상적으로 커집니다. 사용자경험과 api요청횟수를 고려했을 때, 12개를 받아오는것이 가장 적당하다고 생각되는데 렌더링 속도가 많이 느리다고 생각되서 개선하고자 합니다. **초기렌더링 에서만 문제가 발생되고, 캐싱되어 fresh한 상태일 때는 바로 불러옵니다** 코드의 다른요소들은, 필터링. 정렬들을 위한 요소들이라 렌더링 시간에 영향을 줄 것 같지는 않은데 왜 이런 문제가 발생하는지 궁금합니다. 이 외에도 잘못작성된 부분이 있거나, 개선해야할 사항이 보이신다면 알려주시면 감사하겠습니다!!
개발자
#react
#reactquery
#infinitescroll
답변 1
댓글 3
조회 98
6달 전 · 정성린 님의 질문
[사이드 프로젝트] 패션 이커머스 플랫폼 '푸츠(PUTS)' 앱 개발팀 모집
프로젝트 소개: ‘푸츠(PUTS)_Pick Up The Style!’서비스는 패션 디자이너 브랜드를 중심으로 BM특허까지 보유한 혁신적인 패션 커머스 플랫폼서비스 입니다. 데모버전까지 외주개발을 통해 개발이 완료되었지만 현시점에서 리뉴얼하여 새롭게 런칭버전을 개발하고자 역량있는 팀원을 모집합니다. <참고> 본 서비스의 시장성은 2024년 약 19조 5천억원(캐주얼) 정도의 시장성을 예상하고 있으며 연간 약 3.5%씩 지속적으로 성장 중에 있습니다. 3-5년이내 시장의 10%이상 점유를 목표하고 있으며 시장을 장악 가능한 비즈니스 모델과 마케팅 능력을 보유하고 있습니다. (참조: https://global.fashionseoul.com/2023-11-10/Korean-Fashion-Market-Size-Anticipated-Highest-Growth-Ever) 우리는 패션과 기술을 접목해 사용자와 소비자에게 최상의 쇼핑 경험과 정보 공유, 소득을 제공하는 서비스로 패션산업의 큰 파도를 함께 일으킬 분들을 모집합니다. 사이드 프로젝트 형태로 진행되며, 유연한 근무 환경에서 협업을 지향합니다. 3-5년이내 엑싯을 목표로 진행됨으로 임금지급 방식이 아닌 지분분배 방식으로 진행됩니다. 프로젝트 완료시 파트별 기여도에 따라 지분설정이 되며 관련 내용은 프로젝트 진행 전 협의를 통해 산정하여 계약진행 예정.(급여를 제공 받고자 하시는 분은 정중히 사양합니다.) 모집 직군: 1. 프론트엔드 개발자 (1~2명) o 주요 업무: 모바일 앱 UI/UX 구현, 웹 랜딩페이지, 사용자 인터페이스, 어드민 프론트엔드 개발 o 기술 스택: React Native 또는 Flutter, JavaScript/TypeScript, HTML/CSS o 우대 사항: 모바일 퍼포먼스 최적화 경험, 패션 커머스 개발 경험 2. 백엔드 개발자 (1~2명) o 주요 업무: 서버 및 데이터베이스 설계, API 개발, 어드민 백엔드 개발 o 기술 스택: Node.js, Django, AWS, PostgreSQL, RESTful API o 우대 사항: 대용량 트래픽 처리 경험, 보안 및 결제 시스템 개발, 이커머스 어드민개발 경험, 포인트관리 및 쿠폰설정 관리 등 3. UI/UX 디자이너 (1명) / 대표자와 함께 진행 또는 대표자가 진행 o 주요 업무: 모바일 앱 디자인, 사용자 경험 설계 o 필수 스킬: Figma 또는 Photoshop, Illustrator o 우대 사항: 패션 브랜드 디자인 경험, 사용성 테스트 및 피드백 반영 경험 근무 형태: • 프로젝트 기반 협업 (파트타임 가능) • 원격 근무 가능 (주 1회 온라인 미팅) • 유연한 일정과 주도적인 업무 환경 우대 사항: • 사이드 프로젝트 경험 • 패션, 커머스에 대한 관심과 열정 • 스타트업 문화에 익숙한 분 • 책임감 강하신 분 지원 방법: • 이력서와 포트폴리오를 [dcode00@naver.com]로 제출 • 지원 시 사이드 프로젝트 경험 및 참여 가능 시간을 명시해 주세요. 문의: • 이메일: [dcode00@naver.com] • 카카오톡/오픈채팅방: [https://open.kakao.com/o/gi5ixgVe] • 회사주소: 경기도 안산시 상록구 한양대학로55 제2과학기술관 지하2층 B210호 (한양대학교 에리카캠퍼스 소재) 지원 마감일: [채용 완료시까지] 로켓펀치 참여링크 https://www.rocketpunch.com/jobs/139647 문의: • 이메일: [dcode00@naver.com] • 카카오톡/오픈채팅방: [https://open.kakao.com/o/gi5ixgVe]
개발자
#사이드플젝
#사이드프로젝트
#팀빌딩
답변 0
댓글 0
추천해요 1
보충이 필요해요 1
조회 151
9달 전 · 김유진 님의 새로운 댓글
리액트에서 superagent를 활용해서 minio에 업로드하는 방법을 알려주세요 😂
제발 도와주세요 ㅜㅜㅜㅜㅜ 몇일동안 오류를 해결하지 못하고 있어요.. .. 리액트 웹에서 모바일 핸드폰으로 웹을 접속했을 경우, input을 통해서 사진을 업로드하거나 촬영한 이미지를 minio에 업로드 하고 싶은데, 아래 부분에서 계속 오류가 발생해서 도움을 요청해요 ㅠㅠ https://min.io/docs/minio/linux/developers/javascript/API.html#presignedPostPolicy 위 문서를 참고해서 코드를 작성했어요! [핸드폰으로 웹 접속 -> 사진 업로드/촬영 -> minio 업로드] 이 순서인데, minio에 이미지가 업로드가 되지 않고 계속 오류를 발생시켜요. superagent를 활용해서 minio에 업로드가 가능하다고, 위 문서를 참고해서 작성을 했는데, 계속 아래 에러 메시지를 전달받고 있어요ㅜㅜ 아래 에러를 게속 반환해요. <Error> <Code>MalformedPOSTRequest</Code> <Message>The body of your POST request is not well-formed multipart/form-data. (The name of the uploaded key is missing)</Message> <BucketName>bucket</BucketName> <Resource>/bucket</Resource> <RequestId>RequestId...</RequestId> <HostId>HostId...</HostId> </Error> f12 개발자 모드 페이로드 전달 데이터 bucket: 데이터 Content-Type: multipart/form-data x-amz-date: 날짜정보 x-amz-algorithm:데이터 x-amz-credential: 데이터 policy: 데이터 x-amz-signature: 데이터 file: (바이너리)
개발자
#react
#superagent
#typescript
답변 1
댓글 2
조회 60
데이터 수집 시스템 조언 부탁드립니다..
안녕하세요. 현재 데이터분석가 인턴으로 회사에 들어간지가 한달이 조금 넘었습니다. 현재 회사에서 분석이 아닌, 직접 데이터를 수집하는 작업을 하고 있습니다. 제가 분석만 하다보니, 데이터를 수집하고 저장하는 작업을 처음해보고 사수도 따로 없다보니 조언을 구할 곳이 없어서 이렇게 게시물로 조언을 요청드립니다.. 지식이 부족해 다소 어렵게 설명을 드려도 이해 부탁드리며, 제 글을 보고 “저 친구는 왜 저렇게 비효율적으로 하지? 이렇게 하면 좋을텐데”라는 생각이 드신다면 바로 댓글이나 쪽지 부탁드립니다. 제가 처음 올려봐서 쪽지 기능이 있나 모르겠네요.. 먼저, 간단하게 제가 진행하고 있는 데이터 수집 절차를 설명드리겠습니다. 1. 컬럼이 한개인 4GB가 조금 넘는 데이터를 수집 코드에 불러와야 한다. 해당 데이터에는 도메인 주소가 담겨 있다. 2. 내 수집 코드는 불러온 데이터를 한행씩 조회하면서 수집을 진행한다. 3. 한 행에 있는 도메인 주소에 순서대로 http 접속을 해서 해당 도메인 주소가 사전에 설정한 특정 조건을 만족하면, 해당 도메인 주소와 사이트에 접속해서 추출한 정수형 값을 DB에 저장한다. 4. 즉, 4기가의 데이터를 불러와 한 행씩 조회해가면서 실시간으로 데이터를 db에 수집하는 코드다. 5. 24시간 동안 코드를 돌리는 수집 예상 기간은 3개월 정도이다. 다음으로는 조금 구체적인 진행 사항을 말하겠습니다. 밑에서부터 길어지니, 바쁘신 분들은 위에 주요 절차만 보시고 조언 주시면 감사하겠습니다. 1. 파이썬만 사용할 줄 알기 때문에, 파이썬을 사용하여 class로 만들어 수집 코드를 짰다. 2. 데이터의 양이 많아서 메모리 부족 오류가 빈번하게 나타나, 하둡과 아파치 스파크를 이용해봤다. 내가 조회할 데이터 파일을 하둡 HDFS에 업로드 한다음에, 아파치 스파크 클러스터를 구축했다. 그리고, pyspark 모듈을 이용해 파티션을 나눠 데이터를 불러왔다. 파티션으로 받아온 값을 리스트로 변환하여 순서대로 해당 도메인 주소로 접속하는 반복문을 진행하면서 데이터를 수집했다. 즉 파티션으로 데이터를 쪼개서 1번 파티션부터 n번 파티션까지 각각 파티션 내부에 도메인 주소 리스트가 반복문을 진행된다고 보면 된다. 각 파티션이 다른 파티션으로 전환되는 과정도 반복문으로 처리했다. 하나의 파티션 마다 내가 만든 class(도메인 리스트를 인자로 받는다)가 한번씩 실행된다고 보면 된다. 3. 수집 속도가 너무 느려서 class에 있는 수집 메소드를 멀티 스레드 방식을 이용해서 수정해주었다. 수집 속도가 매우 빨라졌다. 4. 기존에는 aws의 클라우드 db(dynamo db)를 사용했지만, 과금 문제로 인해 로컬에 db를 설치하기로 했다. 쓰기 속도가 매우 빠른 redis db를 선택했다 5. 위에서 설명한 반복문을 돌면서 조건에 일치한 도메인 주소와 정수 값은 한 행씩 redis db에 key(도메인주소) value(정수값) 형식으로 저장하도록 코드를 만들었다. 이 과정도 class 내부에 포함되어 있다. 6. redis는 on memory db이기 때문에 대용량 데이터를 영구적으로 저장하고 분석하기에 적합하지 않다고 판단해서 1시간마다 redis에 있는 데이터를 postgresql db로 옮겨주는 코드를 따로 만들었다. postgresql db에 미리 redis에서 옮겨갈 테이블을 생성해두었다. redis의 key였던 도메인 이름을 첫 번째 필드에 프리이머리 키로 저장했고 value인 정수 값을 2번 째 필드에 값으로 넣어줬다. 그리고, 마지막 필드에는 자동으로 데이터가 저장될 때, 현재 시간이 넣어지게 테이블을 만들었다. 총 3개의 열로 구성된 테이블에 1시간에 한번씩 redis에 저장해두었던 데이터가 옮겨간다고 생각하면 된다. 7. 처음 redis에 데이터를 저장할 때 ttl을 설정해서 1시간 10분이 지나면 redis db에서 데이터가 자동으로 소멸되도록 설정했으며, 만약 postgresql에 중복된 데이터가 들어간다면 자동으로 무시하고 다음 작업을 진행하도록 테이블 설정을 해줬다. 즉, 실시간으로 데이터가 수집되고 자동으로 시간이 지나면 데이터가 소멸되는 redis db에서 1시간마다 한번 postgresql로 옮겨주는 코드를 따로 만들었다. 8. 수집 코드를 spark-submit 명령문으로 실행해주었다. spark-submit 명령어 앞에 nohup을 해줘서 백그라운드에서 코드가 실행되게 해줬고, 로그 결과를 따로 파일을 만들어 저장되도록 했다. 그리고 파이썬 실행 파일 내에서도 로그를 입력하는 코드를 만들어서, 도메인의 http 접속이 성공했는지의 여부를 로그 파일에 실시간으로 입력되도록 했다. 예를 들어, http 접속이 잘 된 도메인 주소는 로그에 “INFO 도메인 주소: success” 이렇게 기록하고, 타임아웃 에러, 접속 에러, redirect 오류, db 저장 오류는 모두 종류별로 예외 처리해서 로그에서 기록되도록 코드를 구성했다. 파이썬에서 자체적으로 로그를 기록한 파일은 수집코드를 실행하면서 파티션이 전환될 때마다 하나씩 생성된다. 이제 이렇게 제가 실행할 코드는 24시간 내내 수집을 진행하는 코드 하나와 1시간에 한번 데이터를 옮겨주는 스케줄러 코드로 총 2개가 됩니다. 저는 이 코드와 수집 환경을 만들기 위해 모두 도커를 활용하였으며, 사용한 컨테이너와 부가 설명은 다음과 같습니다. spark-master: 하둡과 스파크 클러스터를 구축하는 컨테이너로 standalone모드로 spark-summit 명령어로 파이썬 파일을 실행해주었다. --conf 옵션으로 메모리, 하트비트 간격, 파티션 수 를 지정해주었다. 스파크와 하둡을 처음 사용해봐서 약간의 개념만 있는 상태에서 돌려보니 아직도 세부 설정을 제대로 이해하지 못했다. 결국 worker를 1개 생성해서 파이썬 파일을 처리하도록 하였다. 현재 대다수의 오류가 이 컨테이너에서 발생한다. redis: spark-master에서 실시간으로 실행되고 있는 수집 코드에서 선별된 데이터들이 redis 컨테이너에 있는 redis db에 저장된다. postgresql: 1시간에 한번 redis에 있는 데이터를 옮기기 위해 postgresql 컨테이너를 생성했다. schduler: 1시간에 한번 postgresql 컨테이너에서 작동하고 있는 postgresql db에 redis 데이터를 옮겨주기 위한 스캐줄러 코드를 실행할 컨테이너다. redis-monitor: 실시간으로 redis db를 모니터링 하기 위해 redis-monitor 컨테이너를 생성하여 웹에서 모니터링 툴인 Redis-Stat에 접속한다. postgre-monitor: 마찬가지로, 실시간으로 postgresql db를 모니터링 하기 위해 생성한 컨테이너로 웹에서 Pgadmin4를 사용할 수 있다. 이렇게 총 6개의 컨테이너를 생성하여 내 수집 코드를 실행했는데, 여기서 많은 문제가 발생했습니다. 제가 가진 의문과 문제를 나열하자면 다음과 같습니다. 1. 먼저, 수집 코드를 실행한 다음에 스케줄러 코드를 실행해주었는데, (서로 독립된 컨테이너에서 실행) 두 코드가 DB에 동시에 접속할 때, 충돌이 일어날 가능성이 있지 않을까? 2. 수집 코드를 실행하고 몇분이 지나면 터미널이 먹통이 되고, 코드가 더 이상 실행이 안되는 일이 빈번하게 발생한다. 너무 많은 자원을 사용하고 있어서 그런건가.. 컴퓨터 사양이 안좋아서 그런건가 원인을 잘 모르겠다.. 3. spark-submit 로그를 보면 내 노트북에서는 안그러는데, 대용량 파일을 불러오는 과정에서 파티션 별로 데이터를 정리할 때 오류가 빈번하게 발생한다 . executor가 통신이 안된다는 경고 메세지도 자주 나오고, 특히, Remote RPC client disassociated 라는 오류가 가장 많이 나온다. 내 컴퓨터보다 높은 사양의 클러스터를 구축하려고 해서 그런가. 검색해보니 네트워크 문제이거나, 컨테이너에 할당한 자원을 초과해서 그런거라고 한다. 대용량 데이터를 불러오는 다른 방법을 강구해봐야되나 고민하고 있다. “그래서 요점이 뭐야” 라고 물어보신다면, 저는 현직에서 활동하고 계신 데이터 엔지니어, 백앤드 개발자 분들이 제 글을 본다면 “아니 굳이 왜 그렇게 하지? 이렇게 쉬운 방법이 있는데” 또는 “저기서 이렇게도 해봤나?, 이러면 안정적으로 코드를 돌릴 수 있을텐데”라는 반응으로 갈릴 것 같다고 생각합니다.
개발자
#데이터베이스
#데이터수집
#아파치스파크
#redis
#python
답변 2
댓글 0
추천해요 7
조회 883
8달 전 · 익명 님의 질문 업데이트
PostLike 테이블에서의 JPA 관계 설정 (Web, Spring, JPA)
Post 테이블 (Long pno, String cotent) UserInfo 테이블 (String uid, String nickname) PostLike 테이블 (Long pno, String uid) Post에 대한 좋아요 정보를 PostLike테이블에서 관리하고 있습니다. 여기서 PostLike 엔티티를 정의할 때 1) UserInfo userInfo, Post post를 @ManyToOne으로 관리할지, 2) 아니면 그낭 Long pno, String uid로 관리할지 고민입니다. 1번 방법) 장점 : Post, UserInfo를 delete 할때 알아서 관련된 좋아요 정보를 찾아서 삭제해준다는 면에서 무결성 관리가 편함. 단점 : JPA는 where pno=(삭제하는 게시글 id)처럼 쿼리 한 번으로 삭제하지 못 한다. 먼저 PostLike 테이블에 pno가 삭제 게시글 id와 같은 것들이 무엇이 있는지 확인하고, 해당 id에 해당하는 row를 deleteById로 하나하나 삭제하기 때문에 쿼리가 N+1 필요해서 성능 이슈가 생긴다. 2번 방법 ) 장점 : 성능 문제가 해결된다. 쿼리 한 번으로 게시글 혹은 유저를 삭제했을 때 관련 좋아요 정보를 삭제할 수 있다. 단점 : 무결성 관리를 직접 해줘야 해서 프로그래머가 신경써서 관리해야 한다. ◼️ 질문 1 1번 방법과 2번 방법 중에서 2번 방법을 선택하려고 합니다. Trade off를 제대로 한 게 맞을까요? Post와 Comment에서는 @ManyToOne을 사용하고, Follow나 PostLike에서는 @ManyToOne을 사용하지 않는 것이 제멋대로인 것 같아서 고민입니다. ◼️ 질문 2 유저를 삭제할 때 해당 유저가 좋아요를 누른 기록을 유지하는 것이 좋을까요, 삭제하는 것이 좋을까요? 요구사항에 따라 달라진다는 것은 알지만 그래도 일반적으로 사용되는 방법이 궁금합니다.
개발자
#spring-boot
#jpa
#backend
#web
답변 0
댓글 0
조회 28
일 년 전 · 조진형 님의 질문 업데이트
카페24 웹호스팅 중 cors에러 관련 질문입니다.
정부 지원사업으로 3개월짜리 인턴십 진행중인 신입개발자 입니다. 현재 회사에는 시니어 개발자나 선임 개발자가 없어서 정말 초짜 백엔드 1명, 프론트 1명이서 프로젝트르 진행중입니다. node.js - react로 구현한 웹페이지를 카페24 웹호스팅을 통해 배포중입니다. (호스팅 : node.js 호스팅 일반형 / 도메인: htcoummunity.cafe24app.com) 배포된 웹페이지를 테스트 도중 cors에러를 만났습니다. 상황= 로그인 버튼을 누르면 로그인 정보를 체크하는 API가 cors에러로 인해 응답을 받아오지 못하고 있습니다.(모든 api가 안됩니다.) 에러메세지= Access to fetch at 'http://localhost:8001/api/signup/checkuser' from origin 'http://htcoummunity.cafe24app.com' has been blocked by CORS policy: The request client is not a secure context and the resource is in more-private address space `local`. POST http://localhost:8001/api/signup/loginEmail net::ERR_FAILED 자체적인 분석으로는 'http://htcoummunity.cafe24app.com' 가 public IP이기 때문에 로컬호스트로 요청하는 api는 리소스의 Private 수준이 더 높기때문에 cors정책에 의해 막힌 것이라고 해석했습니다. 하지만 적절한 해결책은 찾지 못하고 있습니다. Proxy설정까지는 시도해봤지만 문제가 해결되지는 않았습니다. 인턴십이 이제 3일정도 남아서 배포만이라도 깔끔하게 마무리하고 싶은데 해결이 되지 않고 있습니다. 부디 해결책을 제시해주시면 감사하겠습니다!
개발자
#react
#node.js
#cors
#카페24
답변 1
댓글 0
조회 665
일 년 전 · 익명 님의 질문
POST Body 가 간헐적으로 잘려서 들어옵니다.
App (react-native) 에서 RNFS 로 여러장의 이미지를 base64로 변환하여 post body 에 넣어 요청을 보냅니다. 하지만 간헐적으로 서버 (spring boot) 에서 post body 가 잘려서 들어오고 EXCEPTION : org.springframework.http.converter.HttpMessageNotReadableException ERROR MESSAGE : JSON parse error: java.io.EOFException 아래와 같은 에러가 발생합니다. 동일 이미지들을 다시 base64로 변환하여 요청하면 대부분 성공합니다. 어떤 문제일까요? spring boot yml 에는 아래와 같이 설정해두었습니다. server: port: tomcat: connection-timeout: 1800000 max-http-post-size: 100MB max-swallow-size: 100MB threads: max:
개발자
#react-native
#spring-boot
답변 0
댓글 0
추천해요 1
보충이 필요해요 1
조회 127
일 년 전 · 정연준 님의 새로운 댓글
프론트엔드 개발자를 지망하는 취준생인데 이력서에 뭐가 부족한 것일까요?
5월 19일에 국비 부트캠프를 수료한 후 현재까지 5개월 동안 구직 활동을 하고 있는 취준생입니다. 현재까지 100군데 넘게 스타트업, 중소, 중견, 대기업 가리지 않고 다 지원했는데 면접은 커녕 서류 통과가 되는 곳이 한 군데도 없습니다. 취업에 먼저 성공했던 동료 취준생과 디스코드의 개발자 커뮤니티를 통해 이력서를 수정하고 있는데 현재 맞게 진행되고 있는지 긴가민가 합니다. 그래서 여기 계시는 현직자 분들한테 피드백 요청드리고자 합니다. 가감없는 솔직한 평가 부탁 드리겠습니다. 1. 이력서 제목: '이력서 | 안녕하세요, 정연준입니다!' -부족해도 멈추지 않는 개발자 -아는 것과 모르는 것을 구분할 줄 아는 개발자 2. 자기 소개: `안녕하세요, 신입 React 프론트엔드 개발자 정연준입니다. -시행 착오를 통해 성장해나갑니다. -잘하는 것과 부족한 것을 구분하여 잘하는 것을 부각시키고, 부족한 것을 채울려고 노력하는 개발자가 될려고 합니다. -좋은 서비스와 더불어 사용자가 편하게 이용할 수 있는 서비스를 만드는 것을 목표로 하고 있습니다. ` 3. 개발 직무: 프론트엔드 개발자 4. 프로젝트: -기간: 2023.04.17 ~ 2023.05.19 -서비스 제목: One-Line -한 줄 요약: AI모델이 사용자가 작성한 게시글을 한 줄 요약 및 제목 생성 -프로젝트 종류: 팀 프로젝트 -역할: 프론트엔드 파트(메인 페이지 게시글 목록 전체 조회, 인증 페이지 구현) *메인페이지 게시글 목록 전체 조회 1) Trending 섹션 2) Recent Posts 섹션 *메인 헤더(Global Navigation 메뉴) *인증 페이지에 Firebase Authentication 기능 적용 5. 교육 이력: -기간: 2022.11.28 ~ 2023.05.19 -주관 기관: 엘리스 -교육 프로그램 이름: 엘리스 AI트랙 6기 -학습한 기술 스택: React, Express.js, MongoDB, HTML5, CSS3, JavaScript, GitLab, Python, MySQL, TensorFlow, Pandas, Node.js -세부 사항 *JavaScript 1) JavaScript 기초 2) 싱글 스레드, Event, Promise 개념 숙지 *React 1) React 기초 *Express.js 1) Express.js 기초 *MongoDB + Mongoose 1) DBMS 기초 2) MongoDB, Mongoose 기초 *데이터 분석 1) Python, SQL 기초 2) Pandas 기초 *인공지능 1) 데이터 과학 기초 2) 이미지 처리 기초 6. 링크 -프로젝트 링크: https://10team.vercel.app/ -프로젝트 시연 영상: https://drive.google.com/file/d/16Qni0swyC8HbAY2iqnEy5QWze9ianjln/view?usp=sharing -개인 블로그: https://chadolbaegi128.tistory.com/
개발자
#프론트엔드-취준
#react
#javascript
답변 3
댓글 5
추천해요 7
보충이 필요해요 1
조회 2,245
자바스크립트 협업시 궁금한 점이 있습니다!
자바스크립트로 프론트 1명과 백엔드 1명이 협업으로 토이프로젝트를 한다고 가정했을때요, (포폴용 협업 플젝 느낌..) nodejs랑 express로 port 설정해서 app.use() 같은 작업은 백엔드가 하는건가요..? 혼자 프로젝트를 하면서 프론트부터 nodejs 까지 다 만지다보니.. 뭔가 좀 구분하는게 어렵습니다.. 예를들어, router.js 파일에는 app.route("/board").get(function).post(function2); 이런 코드가 있고 controller.js 파일에는 const renderBoard = () => { return res.render("board"); }; 이렇게 board를 render 해주는 코드가 있다고 치면요.. renderBoard 함수는 말 그대로 board라는 템플릿을 화면에 뿌려주는거니까 프론트 개발자가 작업하고 app.route ~ 코드는 서버와 통신하는거니까 백엔드가 작성하는건가요?? 그래서 협업할 땐, 프론트 왈: "야 /board get 할때 함수 이름 function이고, post 할땐 function2다" 아니면 반대로, 백엔드 왈: "야 /board get함수 이름 function 이고 post는 function2 니까 헷갈리지 말고 짜라!" 라고 말하는건가요... 죄송합니다.. 말로 설명하면 깔끔할 것 같은데 글로 쓰니까 좀 이상하네요... restful api가 결국엔 서버와 통신을 하기 위한건데.. 만약, route하는 코드부터 get, post할 때 작동할 function 까지 전부 백엔드가 작업하는거라면, 프론트는 html, css + 동적웹을 위한 js를 해주면 되는건가요? 제가 배운거로는.. pug같은거 사용해서 템플릿 뿌려준다거나, scss를 적용한다거나.. 물론 이때 필요한 npm 사용법이나, package.json 설정법 등은 프론트가 해야겠죠!! 아직 협업 경험이 없다보니.. 실제로 협업을 하게되면 어떻게 업무를 나누는지 궁금합니다. 글이 좀 두서없네요. 아으.. 근데 이 뭔가 가려운 부분을 긁어주고싶습니다ㅜㅜ 선배님들 조언 부탁드립니다.. 답변 미리 감사드립니다!!!
개발자
#javascript
#frontend
#node.js
#express.js
#backend
답변 1
댓글 1
조회 368
일 년 전 · 윪 님의 새로운 댓글
html form태그에서 action속성 오류
html 중에서 <form aciton="/signup" method ="POST">이 부분엔서 /signup부분에 하이퍼링크처럼 줄이 생기고 페이지를 로드했을 때 404오류가 뜨는데 혹시 어떤 부분이 잘못되서 그런지 알 수 있을까요..? 그리고 언더바가 생기는 이유도 알고 싶습니다! 구글링을 해도 제가 원하는 답이 없어서 조언 부탁드립니다 ㅜㅜ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <form action="/signup" method="POST"> <div> <label for="id">아이디</label> <input type="text" id="id" name="id" /> </div> <div> <label for="password">패스워드</label> <input type="text" id="password" name="password" /> </div> <div> <button type="submit">회원가입하기</button> </div> </form> </body> </html>
개발자
#html
#form
#frontend
#action
답변 1
댓글 1
조회 96
일 년 전 · 최건 님의 질문
firebase authentication
html에서 아래 같이 data를 전송했을 때 백엔드에서 const {createUserWithEmailAndPassword,signInWithEmailAndPassword,signOut,browserSessionPersistence, setPersistence}= require("firebase/auth"); const db = require("../config/firestore"); const {email,password} = req.body; console.log(email,password) await signInWithEmailAndPassword(auth,email,password) res.redirect("/api/home") 로 받으면 첫 번째 로그인시 Cannot POST /auth/login가 뜨면서 로그인이 안되고 뒤로 갔다가 다시 로그인을 하면 로그인이 완료되는 오류가 발생합니다... firestore은 form 데이터를 받아 저장하는 것에 오류가 발생하지 않는데 왜 authentication에서는 이러 오류가 발생하는지 궁금합니다 ㅠㅠ 해결 방안도 궁금합니다 ! ㅠㅠ
개발자
#firebase
#firebase-authentication
답변 0
댓글 0
조회 59
일 년 전 · 정득광 님의 새로운 댓글
웹 백엔드) Bcrypt를 이용하여 암호화 시 비밀번호 검증
사용중인 라이브러리: Express.js bcrypt mongoose 현재 진행중인 사내 웹 프로젝트내에 게시판을 만들려고 하는데 DC인사이드 처럼 게시글마다 비밀번호를 설정하도록 기능구현을 한 상태입니다. 비밀번호는 bcrypt를 이용해서 암호화를 진행했고 수정이나 삭제를 할 땐 비밀번호 검증 후 수정/삭제가 이뤄지도록 구현하고 있습니다. 패스워드가 bcrypt로 암호화되어 있기 때문에 수정의 경우 1. request body에 비밀번호를 보내서 백엔드에서 bcrypt.compare() 2. 비밀번호가 일치할 시 해당 게시글의 데이터를 response 3. response에서 받은 데이터를 기반으로 프론트 수정페이지에 보여준다음 4. 수정페이지 내용을 다시 PUT요청으로 수정하도록 구현되어 있습니다. 이 과정에서 API가 1. 비밀번호 검증용(GET) 2. 게시글 수정용(PUT) 이렇게 두가지가 필요한 상황이 되었는데, 비밀번호 검증 GET에서 질문이 생겼습니다. 기본적으로 GET과 DELETE요청은 request body를 가지지 않는게 규칙이라고 배웠습니다. 하지만 request body를 가지는 POST와 PUT은 그 의미가 생성/수정이라고 이해하고 있습니다. 그렇다고 비밀번호를 URL에 Query Params로 보내자니 보안상 문제가 되지않을까 걱정이 되구요... 1. GET 또는 DELETE요청에 request body를 포함하여 보낸다. - 현재 사용중인 방식이고 앞서 말한 규칙 때문에 수정을 고민중이며 구현, 사용상에 문제는 없었습니다. 2. POST 또는 PUT요청에 request body를 포함하여 보낸다. - 현재 고려중인 방식이고 의미적인 문제가 없다면 이렇게 사용하려고 합니다. 개발 자체를 공부해본지 얼마안된 개발어린이라 제 상식외의 문제가 발생하면 대처하기가 어렵네요..ㅜㅜ 위에 제시한 1, 2번 방법중 어떤게 더 Best Practice에 가까울까요? 더 좋은 방법이 있다면 의견도 제시해주시면 너무 감사하겠습니다. <(__)>
개발자
#express.js
#bcrypt
#node.js
답변 3
댓글 3
조회 87
일 년 전 · 백승훈 님의 새로운 답변
Docker compose 컨테이너 구성을 어떻게 될까요?
저는 prisma nextjs postgresql을 사용하고 있습니다 Docker compose에서 컨테이너를 local용postgresql, deploy용postgresql, nextapp 이렇게 3개로 구성하려고 합니다 이렇게 해서 npm run dev로 app을 local로 실행한다고 하면 local용 postgresql과 연결되게 하고 Build를 하고 deploy된것은 deploy용postgresql과 연결되게 하려고합니다 해당 프로젝트가 포폴용이라 상관은 없지만, 정말 서비스를 진행하려고하면 서버를 늘리는 일이 일어날텐데 이런경우 위에서 생성했던 docker이미지를 이용해서 docker compose up을 할텐데요 그러면 새로운 서버가 생길때마다 local용 db를 생성할 수 밖에 없을 것 같은데 제가 아직 배포도 안해보고 프론트라서 제가 지금 생각하는 방식이 맞는지 잘 모르겠습니다 혹시 제가 말한게 맞나요?
개발자
#front
#deploy
#docker
#배포
답변 1
댓글 0
조회 70
6달 전 · 포크코딩 님의 새로운 댓글
Next.js Dynamic Routing 관련 질문
현재 ./pages 폴더에서 page router로 라우팅 관리 중에 있습니다! id별 post 상세창 조회를 위해 ./pages/post-detail/[id].tsx 와 같이 작성했으나 Whitelabel Error Page This application has no configured error view, so you are seeing this as a fallback. Fri Aug 30 21:08:21 KST 2024 [67199a4f-4509] There was an unexpected error (type=Not Found, status=404) 만 발생합니다 참고로 ./pages/post-write.tsx 와 같은 파일은 정상 작동합니다 혹시 무엇이 문제일까요? 추가+) 혹시 Next.js 14에서 page router 방식을 사용하는것이 문제일지 궁금합니다
개발자
#react
#next.js
답변 1
댓글 2
조회 50