Nodejs, Express, EJS 및 NewsApi로 뉴스 앱 빌드

41446 단어 nodecssbeginnerswebdev


오늘 우리는 NodeJS, Express, EJS 및 bootstrap의 도움으로 간단한 뉴스 앱을 개발할 것입니다.

이 웹 사이트 검색 및 뉴스 기사 표시에는 2가지 주요 기능이 있을 예정이며 뉴스 기사를 얻기 위해 Newapi를 사용할 예정입니다.

시작하자



새 프로젝트 초기화



새 프로젝트를 초기화하려면 새 폴더 "News App"을 만들고 Visual Studio 코드 또는 다른 IDE에서 폴더를 열고 명령줄에서 아래 코드를 실행하기만 하면 됩니다.

 npm init  

이것은 몇 초 밖에 걸리지 않으며 초기화가 끝나고 파일 이름 "Package.json"이 생성된 후 프로젝트 이름, 설명 등과 같은 프로젝트에 대한 질문을 거의 하지 않습니다.

프로젝트 구조





위 이미지의 참조와 같이 폴더를 만들고 파일은 자동으로 생성되므로 node_modules package-lock 및 package-json을 둡니다.

종속성 설치



프로젝트에 설치해야 하는 의존성입니다.

express
ejs
body-parser
axios
math
moment

이러한 종속성을 설치하려면 터미널에 아래 코드를 작성하기만 하면 됩니다.

npm install express ejs body-parser axios math moment

실행을 위한 설정 앱



서버를 자동으로 시작하려면 변경 사항이 감지되면 자동으로 서버를 다시 시작하는 Nodemon을 설치하기만 하면 됩니다.

npm install -D nodemon

개발자 실행 및 일반 실행을 위한 설정 응용 프로그램입니다. package.json 에서 아래 코드로 스크립트 섹션을 변경하기만 하면 됩니다.

"scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js"
  },

개발자 로컬 서버 시작



테스트/개발을 위해 앱을 시작하려면 명령줄에 다음 명령을 입력하기만 하면 됩니다.

npm run dev

신청



우리의 app.js 파일을 코딩합시다. 이것이 메인 파일이고 우리 웹사이트의 루트에 위치할 것입니다.
이 파일에서 서버를 설정해야 합니다.

파일:-> app.js
const express = require('express')
const app=express()
const port = process.env.PORT||3000;
const bodyParser = require('body-parser');
const moment = require('moment')
app.locals.moment = moment;

// template engine  
app.use(express.static('public'))
app.set('view engine','ejs')

app.use(bodyParser.urlencoded({ extended: true }));
app.use('/',require('./routes/news'))

app.set('views','./views')

app.listen(port,()=> console.log("started"))

노선



극한 경로를 구축하자
외부 라우팅은 코드를 구조화하여 주 서버 파일 외부에서 경로 구현을 가져와 별도의 라우터 파일로 이동하여 훌륭하고 체계적으로 유지되도록 하는 방법입니다.

먼저 데이터를 가져오려면 NewsApi API 키가 필요합니다. NewsApi 사이트로 이동하여 Api 키를 얻은 다음 URL의 YOUR_API를 아래 코드에서 Api 키로 바꾸십시오.
파일:-> routes/news.js
const express = require('express')
const axios = require('axios')
const newsr=express.Router()
const moment = require('moment')
const math = require('math')


newsr.get('/',async(req,res)=>{
    try {
        var url = 'http://newsapi.org/v2/top-headlines?' +
          'country=in&' +
          'apiKey={YOUR_API}';

        const news_get =await axios.get(url)
        res.render('news',{articles:news_get.data.articles})




    } catch (error) {
        if(error.response){
            console.log(error)
        }

    }
})

newsr.post('/search',async(req,res)=>{
    const search=req.body.search
    // console.log(req.body.search)

    try {
        var url = `http://newsapi.org/v2/everything?q=${search}&apiKey={YOUR_API}`

        const news_get =await axios.get(url)
        res.render('news',{articles:news_get.data.articles})





    } catch (error) {
        if(error.response){
            console.log(error)
        }

    }
})


module.exports=newsr

견해



파일:-> views/news.ejs
<!DOCTYPE html>
<html lang="en">


<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>News</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
        integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
        <link rel="preconnect" href="https://fonts.gstatic.com">
        <link href="https://fonts.googleapis.com/css2?family=PT+Sans:ital@1&display=swap" rel="stylesheet">
        <link rel="stylesheet" href="/css/style.css">
        <style>
            .form-control{
                border-color: red;
            }
        </style>
</head>

<body>

    <nav class="navbar navbar-expand-lg navbar-light bg-light navbar-fixed-top fixed-top">
        <a class="navbar-brand" href="/" style="font-weight: 700;
        font-size: 24px;"> <span style="color: red;" >X</span>-news</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>

        <div class="collapse navbar-collapse searc-bar" id="navbarSupportedContent">

            <form class="form-inline my-2 my-lg-0" action="/search" method="POST">
                <input class="form-control mr-sm-2"  name="search" type="search" placeholder="Search" style="width: 522px;"
                    aria-label="Search">
                <button class="btn btn-outline-danger my-2 my-sm-0" type="submit">Search</button>
            </form>
        </div>
    </nav>





    <div class="news-container ">
        <div class="news ">

            <% articles.forEach(function(article,index){ %>

                <% if ((typeof article.url=='object') || (typeof article.title=='object') || (typeof article.urlToImage=='object') || (typeof article.content=='object')){ %>
                    <% } else{ %>
                        <a href="<%- article.url %>" target="_blank" class="news-box Hover-effect">

                            <img src="<%- article.urlToImage %>" alt="Image">
                            <h3>
                                <%- article.title %>
                            </h3>


                            <p>
                                <%- article.content.replace(/<[^>]+>/g, '') %>
                            </p>
                            <br>
                            <p style="margin-bottom: 0px; position: absolute; right: 0; bottom: 0; font-family: ui-monospace;">Updated: <span style="color:red;" ><%- new Date(article.publishedAt.slice(0,10)).toDateString() %>    <%- moment.utc(article.publishedAt).local().format('hh : mm A') %> </span></p>


                        </a>
                        <% } %>
                        <% }) %>
        </div>
    </div>
    <script src="moment.js"></script>
<script src="moment-timezone-with-data.js"></script>
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</body>

</html>

스타일



body{
    margin: 0;
    font-family: sans-serif;
    background-color: rgba(245, 238, 238, 0.89);
}
nav{
    margin-bottom: 40px;
}
img{
    max-width: 100%;
    transition: all 0.7s ;
}

.Hover-effect:hover{
    transform:  translateY(-3px) scale(1.01);

}
.Hover-effect:hover img{
    transform:  translateY(-5px) scale(1.02);
    box-shadow: 10px 9px 17px -10px rgba(0,0,0,0.28);
}
h3{
    font-size: 1.55rem;
}
h2{
    font-size: 1.55rem;
}
.news-container{
    margin-bottom: 69px;
    padding: 0 1rem;
    padding-top: 92px;
}
.news{
    display: grid;
    grid-template-columns: repeat(auto-fill,minmax(300px,1fr));
    grid-gap: 2rem;

}
.news-box{
    transition: all 0.3s ;
    text-decoration: none;
    color: rgb(29, 25, 25);

    background-color: white;
    padding: 20px;
}

.news-box:hover{
    text-decoration: none;
    color: rgb(29, 25, 25);;
    box-shadow: 0 3px 3px rgba(0,0,0,0.16), 0 3px 3px rgba(0,0,0,0.23);
}


.searc-bar{
    justify-content: center;
}

/* #effect ********************** */

.Hover-effect {
    position: relative;
}
:root{
    --underline_color: red;
    --underline-hight:0.175rem;
}
.Hover-effect::after {
    content: "";
    position: absolute;
    width: 100%;
    height: var(--underline-hight);
    background-color: var(--underline_color);
    left: 0;
    bottom: 0;
    transform: scale(0, 1);
    transition: transform 0.3s ease;
}



.Hover-effect:hover::after {
    transform: scale(1, 1);
}

앱이 완성되었습니다 🎉🎉


시사


Github




atultyagi612 / 뉴스 앱


nodejs, express, ejs를 이용한 뉴스 앱

좋은 웹페이지 즐겨찾기