배고프니 Vue 프로젝트 (3)

13335 단어 프런트 엔드

배고프니 Vue 프로젝트 (3)


오늘은 노드 서버에 대한 지식을 말씀드리겠습니다.

1. node 서버 관련 명령


평소에 우리는 npmrundev 명령으로 프로젝트를 실행하는 것을 자주 사용하는데, 오늘은 npm 명령에 대해 이야기합시다.
npmrun 명령은 프로젝트의 패키지에 있습니다.json 파일에서 scripts 영역을 찾습니다. 예를 들면:
  "scripts": {
    "dev": "cross-env NODE_ENV=development supervisor --harmony index.js",
    "local": "cross-env NODE_ENV=local supervisor --harmony index.js",
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "cross-env NODE_ENV=production pm2 start index.js --node-args='--harmony' --name 'node-elm'",
    "stop": "cross-env NODE_ENV=production pm2 stop index.js --name 'node-elm'",
    "restart": "cross-env NODE_ENV=production pm2 restart index.js --node-args='--harmony' --name 'node-elm'"
  },

이 때, 당신은 npmrundev나 어떤scripts의 항목을 입력할 수도 있고, 간단하게 npmdev라고 쓸 수도 있습니다. 즉run을 절약할 수도 있습니다.
JS 파일, 즉 node index를 실행할 수도 있습니다.js.
위의 구성을 자세히 살펴보겠습니다.
  1. cross-env
  Node.js에 환경 변수가 하나 있습니다 NODE_ENV는 서로 다른 용도의 node 응용 프로그램, 예를 들어 개발(개발), 프로덕션(생산)을 설정하는 데 사용된다. 왜냐하면 개발과 생산 환경은 프로젝트를 실행할 때 약간의 차이가 있기 때문이다.
NODE_와 같은 환경 변수 값을 명령에 지정하는 경우DEV=production, 이 때 일부 Windows 시스템은 오류를 보고합니다. "'NODE_ENV'는 내부나 외부 명령도 아니고 실행 가능한 프로그램도 아닙니다."크로스-env라는 작은 플러그인은 이 문제를 해결하고 플랫폼을 뛰어넘어 환경 변수를 사용할 수 있습니다.
  2. supervisor와pm2
위의 스크립트에서 개발 환경 dev는'supervisor index.js'를 사용했고 생산 환경 start는'pm2 index.js'를 사용했다. 그러면 이 두 가지는 어떻게 다른가?
  (1) supervisor
node에서 서버의 JS 코드는 node에서 처음 인용해야만 다시 불러옵니다.만약 node가 어떤 파일을 불러왔다면, 우리가 그것을 수정하더라도 node는 이 파일을 다시 불러오지 않을 것입니다.그렇다면 개발 과정에서 어떻게 해야만 어떤 파일을 수정한 후에 웹 페이지를 직접 새로 고치면 효과를 볼 수 있을까?
이 때 Supervisor라는 플러그인을 사용하여 JS 파일을 실행할 수 있습니다.
  (2) pm2
pm2는 프로세스 관리 도구로 당신의 node 프로세스를 관리할 수 있으며 성능 모니터링, 프로세스 수호, 부하 균형 등 기능을 지원합니다.pm2는 일반적으로 생산 환경에 응용된다.
  3. --harmoney 옵션
NodeJS는 V8 엔진을 사용하고 V8 엔진은 ES6에 있는 것을 일부 지원하기 때문에 NodeJS에서는 ES6에 있는 것을 사용할 수 있다.그러나 많은 것들이 초안일 뿐 정식 버전은 삭제될 수 있기 때문에 아직 직접 도입하지 않았다.조화 (harmony) 모드에 놓고 node의 운행 매개 변수에 --harmony 로고를 넣어야 사용할 수 있습니다.

2. express 서버


Express는 Node 기반입니다.js플랫폼의 매우 간단하고 유연한 웹 응용 개발 프레임워크는 일련의 강력한 특성을 제공하여 각종 웹과 모바일 응용 프로그램을 만드는 데 도움을 준다.Express가 Node가 아닙니다.js의 기존 특성은 2차 추상화되었지만 그 위에서 웹 응용에 필요한 기본 기능을 확장했다.
  Node.js의 원리는 말하지 않겠습니다. 한 마디로 하면, 그것의 높은 병렬 접근 성능은 절대적으로 우수합니다.Express는 Node에만 있습니다.js에 패키지를 추가했습니다. 서버로 적합합니다. 웹 서버(Apache)일 수도 있고 응용 서버(Tomcat 상당)일 수도 있습니다.
Express에는 두 가지 중요한 개념이 있습니다. 우리는 잘 알아야 합니다.
  1. 경로
Express는 서버로서 사용자 요청을 라우팅합니다.예를 들어 "/user"에 접근하면 어떤 JS 함수를 호출하고, "/product"에 접근하면 다른 JS 함수를 호출하여 하나의 URL과 하나의 함수를 연결합니다.
Express의 등록 라우팅 예:
var server = express();

server.get('/user', function(req, res, next) {
  res.send('You are visiting user');
});

위의 예에서 "/user"라는 URL을 함수와 연결시켜 이 URL에 접근하면 이 함수를 실행합니다.
get 방법 외에post,put,delete 등 자주 사용하는 HTTP 방법도 있어 서로 다른 요청 유형에 대응한다.get 방법의 첫 번째 매개 변수는 URL이고 두 번째 매개 변수는 리셋 함수입니다.리셋 함수에는 req(HTTP 요청),res(HTTP 응답),next(다음 루트) 세 가지 인자가 수신될 수 있습니다.
모든 HTTP 요청(get,post,put,delete,...)에 응답할 수 있는 all 방법이 있습니다.URL이 일치하면
라우팅은 하나의 체인을 구성할 수 있습니다. 즉, URL이 여러 개의 콜백 함수를 연속적으로 실행할 수 있습니다. 예를 들어 다음과 같습니다.
var cb0 = function (req, res, next) {
  console.log('CB0');
  next(); //  
}

var cb1 = function (req, res, next) {
  console.log('CB1');
  next(); //  
}

var cb2 = function (req, res) {
  res.send('Hello from C!'); //  
}

server.get('/user', [cb0, cb1, cb2]);

  2. 중간부품
Express는 자체 기능이 매우 간단하고 루트와 중간부품으로 구성된 웹 개발 프레임워크입니다.본질적으로 말하자면, Express 응용 프로그램은 각종 중간부품을 호출하는 것이다.중간부품 (Middleware) 은 요청 대상 (req), 응답 대상 (res), 다음 중간부품 (next) 에 접근할 수 있는 함수입니다.
현재 중간부품에 종료 요청 - 응답 순환이 없으면next () 방법으로 다음 중간부품에 제어권을 넘겨야 합니다. 그렇지 않으면 요청이 끊깁니다.
중간부품과 루트의 사용 방식이 거의 똑같다는 것을 알 수 있다.
Express에 등록된 중간부품의 예:
var server = express();

//  GET 
server.get('/user/:id', function (req, res, next) {
  res.send('USER');
});

//  。use HTTP 
server.use('/user/:id', function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});

//  URL 。 
server.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();
});

3. 백엔드 프로젝트의 루트 분석


백엔드 프로젝트의 입구부터 봅시다, index.js:
import express from 'express';
import db from './mongodb/db.js';
import config from 'config-lite';
import router from './routes/index.js';
import cookieParser from 'cookie-parser';
import session from 'express-session';
import connectMongo from 'connect-mongo';
import winston from 'winston';
import expressWinston from 'express-winston';
import path from 'path';
import history from 'connect-history-api-fallback';
import chalk from 'chalk';

//  Express 
const server = express();

//  
// “Acces-Control-Allow-” HTTP , 
//  response HTTP 
server.all('*', (req, res, next) => {
	res.header("Access-Control-Allow-Origin", req.headers.Origin || req.headers.origin || 'https://cangdu.org');
	res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
	res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
	res.header("Access-Control-Allow-Credentials", true);
	res.header("X-Powered-By", '3.2.1');
	next();
});

//  , cookie 、session 
server.use(cookieParser());
server.use(session(...));

//  , /routes/index.js 
router(app);

//  , 
server.use(history());
//  ,express.static 
server.use(express.static('./public'));

//  
server.listen(config.port, () => {
	console.log(chalk.green(` :${config.port}`));
});

  routes/index.js:
'use strict';

import v1 from './v1'
import v2 from './v2'
import v3 from './v3'
import v4 from './v4'
import ugc from './ugc'
import bos from './bos'
import eus from './eus'
import admin from './admin'
import statis from './statis'
import member from './member'
import shopping from './shopping'
import promotion from './promotion'

export default server => {
	server.use('/v1', v1);
	server.use('/v2', v2);
	server.use('/v3', v3);
	server.use('/v4', v4);
	server.use('/ugc', ugc);
	server.use('/bos', bos);
	server.use('/eus', eus);
	server.use('/admin', admin);
	server.use('/member', member);
	server.use('/statis', statis);
	server.use('/shopping', shopping);
	server.use('/promotion', promotion);
}

여기는 엄격하지 않을 수도 있습니다. 모든 인터페이스를 통일된 경로에 두어야 합니다. 예를 들어/api/v1,/api/v2 등입니다.
루트/v1을 한층 더 관찰하다.js:
const router = express.Router();

router.get('/cities', CityHandle.getCity);
router.get('/cities/:id', CityHandle.getCityById);
......

백엔드 프로젝트의 인터페이스는 여러 모듈로 나뉘어져 있음을 알 수 있습니다(예:/v1,/v2,...).각 모듈에는 여러 라우팅이 각각 지정됩니다.
여기에 사용되는 express.Router는 모듈화된 루트로 하나의 루트를 하나의 모듈로 구성하여 루트의 모듈화 관리에 편리하다.

4. 프런트엔드 프로젝트의 루트 분석


전단 항목도 입구부터 보고 패키지부터 본다.json 파일:
  "scripts": {
    "dev": "cross-env NODE_ENV=online node build/dev-server.js",
    "local": "cross-env NODE_ENV=local node build/dev-server.js",
    "build": "node build/build.js"
  },

전단 항목은node 명령으로build 디렉터리에 있는 dev-server를 직접 실행하는 것을 볼 수 있습니다.js 파일.
왜 프런트엔드 프로젝트가 백엔드 프로젝트처럼 supervisor나pm2로 Express를 시작하지 않습니까?
전단 항목이 비교적 복잡하고 각종 기술이 혼잡하기 때문에 전기에는 많은 처리가 필요하다.예를 들어 ES6, TypeScript는 ES5로 번역해야 하고, 스타일시트 언어less,sass는 CSS로 번역해야 하며, JS 파일은 조합과 압축이 필요하다.이 작업들은 모두 서버가 시작되기 전에 완성해야 한다.
웹팩은 프로젝트 구조를 분석하고 자바스크립트 모듈과 다른 브라우저가 직접 실행할 수 없는 확장 언어를 찾아 브라우저에 적합한 형식으로 포장하는 모듈 패키지라고 볼 수 있다.
웹팩에는 많은 플러그인이 있어 더 많은 기능을 실현할 수 있다.
우리는 전단 프로그램의 집행 절차를 좀 봅시다.
먼저 dev-server를 실행합니다.js:
//  /config/index.js
var config = require('../config')
if (!process.env.NODE_ENV) process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
var path = require('path')
var express = require('express')
var webpack = require('webpack')
var opn = require('opn')
var proxyMiddleware = require('http-proxy-middleware')
//  webpack 
var webpackConfig = require('./webpack.dev.conf')

var port = process.env.PORT || config.dev.port

//  Express 
var server = express()
//  webpack
var compiler = webpack(webpackConfig)

//  webpack :webpack-dev-middleware
var devMiddleware = require('webpack-dev-middleware')(compiler, {
    publicPath: webpackConfig.output.publicPath,
    stats: {
        colors: true,
        chunks: false
    }
})

//  webpack :webpack-hot-middleware
var hotMiddleware = require('webpack-hot-middleware')(compiler)
compiler.plugin('compilation', function(compilation) {
    compilation.plugin('html-webpack-plugin-after-emit', function(data, cb) {
        hotMiddleware.publish({
            action: 'reload'
        })
        cb()
    })
})

//  HTTP :http-proxy-middleware
var context = config.dev.context
switch(process.env.NODE_ENV){
    case 'local': var proxypath = 'http://localhost:8001'; break;
    case 'online': var proxypath = 'http://elm.cangdu.org'; break;
    default:  var proxypath = config.dev.proxypath; 
}
var options = {
    target: proxypath,
    changeOrigin: true,
}
if (context.length) {
    server.use(proxyMiddleware(context, options))
}

server.use(require('connect-history-api-fallback')())

server.use(devMiddleware)

server.use(hotMiddleware)

//  
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
server.use(staticPath, express.static('./static'))

//  
module.exports = server.listen(port, function(err) {
    if (err) {
        console.log(err)
        return
    }
    var uri = 'http://localhost:' + port
    console.log('Listening at ' + uri + '
') if (process.env.NODE_ENV !== 'testing') { opn(uri) } })

  1. 웹pack-dev-middleware, 중간부품 개발
웹pack-dev-middleware의 역할은 자원의 변경을 감청하고 자동으로 포장하는 것이다.
  2. 웹pack-hot-middleware, 열 업데이트 중간부품
웹 팩-hot-middleware는 일반적으로 웹 팩-dev-middleware와 함께 사용하여 페이지의 열 업데이트를 실현합니다.
  3. http-proxy-middleware, HTTP 프록시 중간부품
HTTP 프록시 중간부품이 필요한 이유는 무엇입니까?다음과 같은 경우를 가정합니다. 웹 서버는 8000 포트, 응용 서버는 8001 포트에서 실행됩니다. 이때 프런트엔드 프로젝트가 백엔드 프로젝트의 API를 호출하려면 JSON 데이터를 가져와서 이렇게 접근해야 합니다.http://127.0.0.1:8081/api/user두 항목이 같은 포트에서 실행되지 않았기 때문에 크로스 필드 문제가 존재합니다.
크로스 도메인은 한 도메인 이름의 웹 페이지에서 다른 도메인 이름의 자원을 요청하는 것을 가리킨다.예를 들면 www.baidu.com 페이지에서 www.google을 요청합니다.com의 리소스입니다.크로스 도메인의 엄격한 정의는 프로토콜, 도메인 이름, 포트가 다르면 크로스 도메인으로 간주된다는 것이다.
왜 브라우저는 크로스 도메인 접근을 제한합니까?원인은 바로 안전 문제이다. 만약에 한 페이지가 다른 사이트의 자원을 마음대로 방문할 수 있다면 고객이 전혀 모르는 상황에서 안전 문제가 발생할 수 있다.
기왕 안전 문제가 있는 바에야 왜 또 영역을 뛰어넘어야 합니까?때로는 회사 내부에 여러 개의 다른 하위 영역이 있기 때문에, 예를 들면, 하나는location이다.company.com, 응용 프로그램은 앱에 놓는다.company.com, 이때 앱에서company.com 방문 위치.company.com의 자원은 크로스 필드에 속합니다.
http-proxy-middleware라는 중간부품의 역할은 크로스 액세스 문제를 해결하는 것이다.
http-proxy-middleware 관련 코드 사용:
var context = config.dev.context
switch(process.env.NODE_ENV) {
    case 'local': var proxypath = 'http://localhost:8001'; break;
    case 'online': var proxypath = 'http://elm.cangdu.org'; break;
    default: var proxypath = config.dev.proxypath;
}
var options = {
    target: proxypath, //  URL
    changeOrigin: true, //  URL
}
//  HTTP , :
// context: URL
// options: 
if (context.length) {
    server.use(proxyMiddleware(context, options))
}

전례의context 매개 변수는config에 사용되었습니다.dev.context, 이 설정 대상은/config/index에 정의됩니다.js:
        context: [
            '/shopping',
            '/ugc',
            '/v1',
            '/v2',
            '/v3',
            '/v4',
            '/bos',
            '/member',
            '/promotion',
            '/eus',
            '/payapi',
            '/img',
        ],

HTTP 프록시 중간부품을 사용하면 전방 프로젝트에서 "/shopping"에 직접 접근할 수 있습니다. 중간부품은 이 요청을 목표 URL에 전달하고 크로스 필드 문제를 처리합니다.

5. 프런트엔드 라우팅 및 백엔드 라우팅


배고프냐 이런 단일 페이지에서 백엔드는 백엔드에 데이터를 먹이거나 백엔드에서 온 데이터를 데이터베이스에 저장하고 데이터 왕래는 JSON 형식을 사용하는 것을 볼 수 있다.백엔드에서 올바른 URL을 입력하면 백엔드의 응답을 받을 수 있는 액세스 API가 출시되었습니다.
우리는 백엔드 프로젝트의 루트를 백엔드 루트라고 하는데 실질적으로 하나의 액세스 API이다.백엔드의 실현은 사실 자바 언어도 잘 한다. 스프링 MVC가 바로 이 일을 하는 것이다.다만 node는 자바스크립트 언어를 사용하기 때문에 전방 개발자들이 비교적 익숙하다.현재 자바스크립트 언어는 자바스크립트 언어의 케이크를 뺏은 것과 같다.
전단 부분은 전단 항목이 항상 한 페이지에 적용되기 때문에 모두 하나의 index이다.html 페이지, 그래서 페이지 점프는 존재하지 않습니다.그러나 다른 기능 페이지에서 전환할 필요가 있다. 일반적으로 하나의 URL로 하나의 구성 요소를 대표하기 때문에 루트 문제도 존재한다.프론트 루트는 일반적으로 개발 프레임워크에 의해 관리된다. 예를 들어 Vue 프레임워크에는 vue-router 모듈이 있다.

좋은 웹페이지 즐겨찾기