화면 스크롤시 효과주기

|

화면 스크롤시 효과주기

토이프로젝트때 사용했으냐, 이 프로젝트에는 어울리지않는 효과인거같아 폐기처분하기전에 혹시 나중에 다른거에 적용할 수 있으니 여기에 기록해둡니다.

코드

import React, { useEffect } from 'react';
import styled, { keyframes } from 'styled-components';

import aboutClip from './aboutClip.mp4';

const typing = keyframes`
0%{
    width:0%;
}
50%{
    width:100%;
}
100%{
    width:0%;
}
`;

const AboutContainer = styled.div`
  background: #111;
  cursor: initial;
`;

const Section = styled.section`
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  clip-path: circle(1000px at center center);

  video {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
`;

const Wrapper = styled.div`
  position: relative;
  margin-top: 250vh; // 포인트
  padding: 100px;
  background: #111;
  height: 40vh;

  h2 {
    font-size: 2.5em;
    margin: 0;
    margin-bottom: 20px;

    color: transparent;
    position: absolute;
    top: 0%;
    left: 0%;
    text-transform: capitalize;
    white-space: nowrap;

    ::before {
      content: 'SKETCHBOOK 프로젝트는..';
      width: 100%;
      height: 100%;
      color: #da4747;
      overflow: hidden;
      border-right: 3px solid white;
      position: absolute;
      top: 0;
      left: 0;
      /* 커서 역할 */
      /* steps는 content길이 */
      animation: ${typing} 5s steps(18) infinite;
    }
  }

  p {
    font-size: 1em;
    color: #fff;
    font-family: 'elvetica Neue",Helvetica,Arial,sans-serif';
  }
`;

const About = () => {
  //   스크롤 내릴때마다 원이 줄어들고 올리면 원이 다시 넓어짐
  useEffect(() => {
    const banner = document.querySelector('.banner');
    window.addEventListener('scroll', function () {
      const value = 1000 - window.scrollY;
      banner.style.clipPath = 'circle(' + value + 'px at center center)';
    });
  }, []);

  // 새로고침시 스크롤 맨 위로
  useEffect(() => {
    window.onload = function () {
      setTimeout(function () {
        window.scrollTo(0, 0);
      }, 100);
    };
  }, []);

  return (
    <AboutContainer>
      <Section className='banner'>
        <video src={aboutClip} autoPlay muted loop></video>
      </Section>
      <Wrapper>
        <h2>SKETCHBOOK 프로젝트는..</h2>
        <p>
          지루하고 반복되는 일상을 잠시 벗어날  있게끔 당신에게 여유를
          제공합니다.
        </p>
      </Wrapper>
    </AboutContainer>
  );
};

export default About;

heroku로 배포할때 package.json

|

heroku로 배포할때 package.json

이 페이지는 개인적인 메모를 위한 용도입니다. 불친절한 내용일 수 있습니다.감사합니다.

package.json

 "engine":{
    "node":"10.16.0",
    "npm":"6.14.8"
  },
  "scripts": {
    "start": "node server/server.js",
    "backend": "nodemon server/server.js",
    "frontend": "npm run start --prefix client",
    "dev": "concurrently \"npm run backend\" \"npm run start --prefix client\"",
    "heroku-postbuild":"NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
  },
  • 먼저 engine 부분을 작성해줘야하고,
  • scripts 부분에서 heroku-postbuild를 작성해 주어야한다.

heroku-postbuild 부분 파헤쳐보기

"heroku-postbuild":"NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"

NPM_CONFIG_PRODUCTION=false ?

20년 10월 11일 현재: 질문을 올린 상태 잘 처리가안됨

  • package.json에 devDependencies 부분이있는데,false를 설정해서 이거를 무시하지 않게끔 해주는 코드이다.
  • default 값은 true이다.

npm install –prefix client && npm run build –prefix client ?

  • 수동으로 하면 client 폴더에서, npm install-> build 순서로 진행해야 heroku가 이를 인식하는데 이 과정을 코드 한줄로 해결한 것

최종적으로..

npm run heroku-postbuild 이 명령어가 잘 안듣는다.(질문 올린 상태)
그래서 client 폴더에서 npm run build 해준후 다시 루트 디렉토리로 가서, git add . git commit -m “” , git push heroku master로 heroku에 빌드해준다.

AWS s3로 파일 업로드

|

AWS s3로 파일 업로드

aws s3란?

  • S3란 Simple Storage Service의 약자로 쉽게말해 파일을 저장하는 저장소

aws s3 버킷 생성 및 id와 key얻기

npm i aws-sdk multer-s3
  • 버킷 생성

  • 버킷을 생성하면 엑세스가 퍼블릭으로 되있지않을텐데 왼쪽 메뉴에서 퍼블릭계정권한 탭에서 해제하여 퍼블릭으로 바꿔주면된다.

  • 이후 aws 서비스 탭에서 IAM을 눌러 사용자추가를 해준다

    • 사용자 추가를 할때 맨 아래 AWS 액세스 유형 방식에서 프로그래밍 방식 액세스를 체크해준후 다음 탭 클릭
    • (액세스 방식을 사용할것이기 때문)
  • 권한 설정 페이지에서 기존 정책 직접 연결을 눌러 S3를 검색,AmazonS3FullAccess 체크후 다음 탭 클릭후 한번 더 다음 탭 클릭후 사용자 만들기 탭 클릭

  • 이후 access key ID 와 Secret access key가 보여지는 페이지가 나오는데, 이 화면을 떠나면 더이상 여기에 접근할 수 가없기때문에 따로 적어줘야한다.

aws s3에 Multer로 파일 업로드하기

기존 multer를 활용한 코드에서 multer-s3로 바꿔준다. 몇몇의 수정사항이있으니 기존코드와 수정 코드 둘다 올려놓겠다.

기존 multer를 활용한 코드

const multer = require('multer');

//=================================
//             (게시글이미지업로드)
//=================================
var multerImage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/images');
  },
  filename: function (req, file, cb) {
    cb(null, `${Date.now()}_${file.originalname}`);
  },
});
//=================================
//             (프로필이미지업로드)
//=================================
var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/avatar');
  },
  filename: function (req, file, cb) {
    cb(null, `${Date.now()}_${file.originalname}`);
  },
});

var imageUpload = multer({ storage: multerImage }).single('file');

var avatarUpload = multer({ storage: storage }).single('file');

// module.exports = upload;
exports.avatarUpload = avatarUpload;
exports.imageUpload = imageUpload;

수정된 multer-s3 코드

  • server/middleware/upload
const multer = require('multer');
const multerS3 = require('multer-s3');
const aws = require('aws-sdk');

//=================================
//             (게시글이미지업로드)
//=================================

const s3 = new aws.S3({
  accessKeyId: process.env.AWS_KEY,
  secretAccessKey: process.env.AWS_PRIVATE_KEY,
});

var imageUpload = multer({
  storage: multerS3({
    s3: s3,
    acl: 'public-read',
    bucket: 'gongcha/uploadImage',
    contentType: multerS3.AUTO_CONTENT_TYPE,
    metadata: function (req, file, cb) {
      cb(null, { fileName: file.fieldname });
    },
    key: function (req, file, cb) {
      var filename = file.originalname;

      var ext = file.mimetype.split('/')[1];
      if (!['png', 'jpg', 'jpeg', 'gif', 'bmp'].includes(ext)) {
        return cb(new Error('Only images are allowed'));
      }

      cb(null, Date.now().toString() + filename);
    },
  }),
}).single('file');

var avatarUpload = multer({
  storage: multerS3({
    s3: s3,
    acl: 'public-read-write',
    bucket: 'gongcha/avatarImage',
    contentType: multerS3.AUTO_CONTENT_TYPE,
    metadata: function (req, file, cb) {
      cb(null, { fileName: file.fieldname });
    },
    key: function (req, file, cb) {
      var filename = file.originalname;
      var ext = file.mimetype.split('/')[1];
      if (!['png', 'jpg', 'jpeg', 'gif', 'bmp'].includes(ext)) {
        return cb(new Error('Only images are allowed'));
      }

      cb(null, Date.now().toString() + filename);
    },
  }),
}).single('file');

// module.exports = upload;
exports.avatarUpload = avatarUpload;
exports.imageUpload = imageUpload;
exports.s3 = s3;
  • server/routes/api/users.js
    • 기존에 file.path였지만,file.location로 변경해줘야 받을 수 있다.
// @route   POST api/users/edit/avatar (프로필 이미지 편집)
// @desc    AvatarChange user
// @access  Private
router.post('/edit/avatar', async (req, res) => {
  // 프론트 에서 가져온 이미지를 저장을 해준다.
  upload.avatarUpload(req, res, (err) => {
    if (err) {
      return res.json({ success: false, err });
    }
    if (!req.file) return res.send('Please upload a file');

    return res.json({
      success: true,
      filePath: res.req.file.location,
      fileName: res.req.file.originalname,
    });
  });
});
  • 이후 프론트에서 이미지를 불러올때 기존의 코드는가

    <img src={`http://localhost:5000/${user.avatar}`} alt='userAvatar' />
    

    이랬다면, 이렇게 바꿔줘야한다.

<img src={user.avatar} alt='userAvatar' />

s3에 파일 업로드된거 삭제 해주기

☆★☆★ 파일명 꼭 영어로 해주기☆★☆★
s3는 한글명으로하면 에러난다고함 그리고 작동안함
실제로 이 문제 때문에 꼬박 하루 고생했음

// @route   DELETE api/posts/:id
// @desc    게시글 지우기
// @access  Private
router.delete('/:id', auth, async (req, res) => {
  try {
    const post = await Post.findById(req.params.id);
    const user = await User.findById(req.user.id).select('-password');

    if (!post) {
      return res.status(404).json({ msg: '게시글이 없습니다.' });
    }

    // aws s3 버킷에서 파일 삭제
    const url = post.image.split('/'); // post에 저장된 image를 가져옴
    const delFileName = url[url.length - 1];

    const params = {
      Bucket: 'gongcha',
      Key: `uploadImage/${delFileName}`,
    };

    upload.s3.deleteObject(params, function (err, data) {
      console.log(params);

      if (err) {
        console.log('aws image delete error');
        console.log(err, err.stack);
        return;
      } else {
        console.log('aws image delete success' + data);
      }
    });

    // check user
    if (post.user.toString() !== req.user.id) {
      return res.status(401).json({ msg: '게시글을 작성한 유저가 아닙니다.' });
    }
    const userPost = user.posts.filter(
      (post) => post._id.toString() !== req.params.id
    );
    // Get remove index
    const removeIndex = user.posts
      .map((post) => post._id.toString())
      .indexOf(req.user.id);

    user.posts.splice(removeIndex, 1);

    await user.save();
    await post.remove();

    res.json({ msg: '게시글 삭제 완료' });
  } catch (err) {
    if (err.kind === 'ObjectId') {
      return res.status(404).json({ msg: '게시글을 찾을 수 없습니다.' });
    }
    res.status(500).send('Server Error');
  }
});

PUT과 POST가 헷갈려요

|

PUT과 POST가 헷갈려요

본 게시글은 mern강의의 질문응답 게시판의 내용을 카피해온겁니다. 영어 질문을 번역기 돌린거라 문맥이 맞지 않을 수 있습니다.

질문

  • 좋아요 추가 / 제거가 PUT 요청이고 댓글 추가 / 삭제가 POST 요청 인 이유를 이해할 수 없습니다. Brad는 “기술적으로 게시물을 업데이트하고 있기 때문에”PUT 요청이라는 좋아요 경로를 만드는 댓글을 작성합니다. 그러나 댓글이 게시 모델의 두 필드이기 때문에 동일한 논리가 댓글에 적용되지 않습니까?

또한 PUT 요청으로 ‘/ api / post / : id’경로를 사용하여 좋아요 및 댓글 추가 / 제거를 캡처하는 것이 REST 아키텍처 측면에서 더 합리적일까요?

답변

  • 새 리소스 생성을위한 POST

  • 전체 자원 교체를위한 PUT

  • 기존 자원의 일부를 업데이트하기위한 PATCH

HTTP 에러 코드 정리

|

HTTP 에러 코드 정리

이번 프로젝트를 작업하면서 에러코드를 찾아보다가 하나하나 찾아보는게 너무 귀찮아서 자주 접하게되는 에러코드를 어느 한 블로그에서 퍼왔습니다.

HTTP 에러 코드들 정리