【你應該瞭解的】詳盡&全面的前端部署(從零起步,前端上線不用愁)

skFeTeam  本文做者:陸程php

遇到前端部署問題怎麼辦?nginx、端口、https域名怎麼配置,跨域問題咋整,react/vue項目怎麼部署,什麼是反向代理,請您耐心往下看。本文通俗易懂,可操做,旨在拋磚引玉。要是幫到了您,還請順便點個贊。css

前言

前端部署,是讓前端代碼在服務器環境正常運行。而前端平常工做,主要仍是業務代碼開發,資源引用,前端路由配置等。至於部署,更多的是運維人員操做接觸很少。但現實項目中,每每一部署到這些環境就出現各類各樣的問題,若是咱們有部署相關的理論、實踐經驗,面對問題就能更容易定位到問題,提升上線效率。html

背景

當你興致勃勃買了臺服務器,而後規劃着美好的將來,規劃搭建平臺。問題來了,前端項目如何部署(demo來自於Internet項目版權歸各自全部)...前端

images/1.上線預期.png

預期的幾個目標:vue

  • 1.web站點(SEO) 基於nextjs前端web服務,port 18001(可修改)。經過nextjs官方example建立 github.com/zeit/next.j…node

  • 2.api服務 基於koa的前端nodejs服務,port 18000(可修改)。經過koa腳手架 github.com/17koa/koa2-… 建立react

  • 3.靜態web項目1-基於vue的前端單頁面靜態資源項目 /vue-app。經過vue-cli建立 cli.vuejs.org/zh/linux

  • 4.靜態web項目2-基於react/typescript等前端靜態資源項目 /react-app。經過create-react-app-antd建立 github.com/ant-design/…nginx

  • 5.公共靜態資源圖片、css、js等。 /staticgit

目錄

按照從零起步的原則,按照如下目錄來按部就班

  • 1.服務器分類
  • 2.輕量強大的nginx
  • 3.前端服務管理工具-pm2
  • 4.解決跨域「問題」
  • 5.☆部署react/vue單頁面靜態項目
  • 6.實現https
  • 7.持續集成CI-自動化部署

1.服務器分類

1.1 應用服務器

專一於動態資源、解析高級開發語言編寫的代碼。前端服務通常基於解析JavaScript語言的nodejs搭建

  • JAVA:Tomcat、resin、jboss、weblogic 等
  • PHP:Apache等
  • .NET:IIS等
  • Nodejs:express、 koa、eggjs等

1.2 網關服務器

專一於靜態資源、代理轉發、負載均衡等

  • Nginx、Tengine等

2.輕量強大的Nginx

Nginx特性不少,前端經常使用一些特性,其餘特性各大互聯網公司通過大量實踐已證實。關於nginx配置,主要就是配置nginx.conf以及修改後reload使配置生效。具體nginx下載與教程能夠參照官網等。Nginx主要是修改配置文件以及生效。

2.1 簡介

2.1.1 前端經常使用特性

  • 域名綁定
  • 靜態資源
  • 反向代理
  • 支持https
  • 跨平臺

2.1.2 其餘特性

  • 負載均衡、高併發

2.1.5 nginx下載和目錄說明

nginx官方網站:nginx.org/

nginx主要經過修改conf/nginx.conf配置文件,重啓nginx程序生效實現服務器功能。

images/2.輕量強大的nginx-靜態資源-nginx文件目錄

// 重啓使配置文件生效
// windows
.\nginx.exe -s reload

// linux/mac
nginx -s reload

// ps windows下強制結束nginx.exe進程命令
taskkill /f /t /im nginx.exe
複製代碼

2.2 實戰配置

2.2.1 環境準備

  • nginx.org下載最新的nginx壓縮包直接解壓,windows/linux/mac下載對應的版本
  • 建立文件夾,windows下爲如C盤根目錄建立 c:/server;linux/mac能夠在某個目錄建立如根目錄建立 /server

2.2.2 靜態資源

首先,咱們來實現js、png圖片、css資源的靜態資源配置。server文件夾下建立static文件夾,裏面分別建立js、img、css文件夾並在對應文件夾放置對應格式的測試文件內容隨意。最終訪問路徑和效果以下:

/static/js/js.js
/static/img/img.png
/static/css/css.css
複製代碼

images/2.輕量強大的nginx-靜態資源-資源訪問效果.png

2.2.3 nginx配置靜態資源

找到nginx文件夾中的 conf/nginx.conf配置文件對應以下配置,配置完成後須要重啓nginx,上面有如何重啓,結束進程再次打開進程或者reload。

# nginx.conf文件找到server區域

server {
    # nginx監聽端口號,不能被其餘應用佔用
    listen 80;

    # nginx綁定的域名,本文用localhost
    server_name  localhost;

    # 公共靜態資源
    location /static/ {
      #root C:/server/;
      alias C:/server/static/;
      autoindex on;
      # 是否啓用目錄索引
      #autoindex on;
    }
}

複製代碼

2.2.4 目錄索引

以上配置有個 autoindex on,若是配置了若是訪問的是目錄,則展現目錄索引,若是關閉則展現403 Forbidden。通常爲了服務器安全不被探測,都是關閉索引目錄。

開啓索引效果

開啓索引效果

關閉索引效果

關閉索引效果

2.2.5 附:nginx靜態站點

配置三個靜態web站點備用。配置方法很簡單,C:/server建立兩個文件夾,立馬分別有個index.html文件。nginx.conf增長如下配置後重啓nginx生效。

server {
    listen       10001;
    server_name  localhost;
    root C:/server/siteA;
    index  index.html index.htm;
}
server {
    listen       10002;
    server_name  localhost;
    root C:/server/siteB;
    index  index.html index.htm;
}
server {
    listen       10003;
    server_name  localhost;
    root C:/server/siteB;
    index  index.html index.htm;
    location / {
      add_header X-Frame-Options SAMEORIGIN;
    }
}
複製代碼

至此,任務5靜態資源任務達成。恭喜您已經具有使用nginx搭建靜態web站點和靜態文件服務的能力了,具體相關其餘配置能夠自行深刻研究。

3 部署前端服務-pm2

前端服務-即前端使用如基於nodejs平臺下可以有獨立運行訪問的web服務等。如nextjs、express、koa、eggjs等前端應用服務器。

pm2是什麼

衆所周知,咱們通常啓動前端服務,開啓一個bash,而後執行如npm start服務器愉快的跑起來,但若是有多個服務,就必需要打開多個,通常在服務器環境你只有一個bash端口必須得後臺運行,如何後臺運行nodejs服務,以及方便的管理各個nodejs服務的暫停、重啓、銷燬,咱們得須要一個可以管理他們的軟件。pm2應運而生。

pm2工具:把nodejs服務變爲後臺服務,統一管理(經常使用於服務器環境、控制檯命令環境)

詳見pm2官方文檔 www.npmjs.com/package/pm2, pm2.keymetrics.io/docs/usage/…

安裝

npm install pm2 –g
複製代碼

經常使用命令

  • pm2 start pm2.json #根據pm2.json配置方式啓動進程
  • pm2 list, pm2 status #列出當前全部pm2管理列表
  • pm2 stop 0 #停用指定id的服務
  • pm2 delete 0 #刪除指定id的服務
  • pm2 restart 0 #重啓指定id的服務

實戰

咱們根據上述最開始官方項目啓動nextjs、koa2的nodejs服務,(之前咱們是執行npm run start,本地模擬能夠直接先啓動),如今若是須要pm2改造

先看運行效果:

1.基於nextjs的nodejs服務:127.0.0.1:12111

部署前端服務-nextjs

2.基於koa2的nodejs服務:127.0.0.1:18000

部署前端服務-koa

3.pm2 list列出全部pm2託管的node服務

.部署前端服務-pm2

配置

最終咱們是直接經過目錄下的start.bat/start.sh執行pm2命令。最終爲了間接執行到npm start的命令,給予pm2進行託管

windows下的pm2存在一些問題,須要經過間接方式執行npm命令

// 1.koa/nextjs項目根目錄增長start.bat / start.sh,內容爲pm2的命令
pm2 start ecosystem.config.js

// 2.建立ecosystem.config.js配置文件,如下已溝通。詳細其餘參數可參照pm2官網查看具體配置. https://pm2.keymetrics.io/docs/usage/application-declaration/ 
module.exports = {
    apps: [{
        name: 'MyKoa',
        script: 'start.js',
        args: 'one two',
        instances: 1,
        autorestart: true,
        watch: false,
        max_memory_restart: '1G',
        env: {
            NODE_ENV: 'development'
        },
        env_production: {
            NODE_ENV: 'production'
        }
    }]
};

// 3.建立start.js
const cmd = require('node-cmd');
cmd.run('npm run start');

// 4.package.json配置,須要項目安裝node-cmd的包,具體npm run start就是項目中如何啓動nodejs服務根據具體項目來
{
  "start": "node bin/development.js",
}
複製代碼

至此,您已經本地運行了兩個前端node服務。任務一、2完成50%.

4.解決跨域"問題"

4.1跨域——「正常」的安全策略

咱們兩個node都啓了,你必定會立馬就想讓nextjs的fetch請求來請求koa的api服務,結果跨域了。。

場景1、XMLHttpRequest、fetch等同源限制

瀏覽器出於安全當訪問不一樣端口、域名默認狀況下是不容許的,也是出於安全。若是誰都能互相隨便調用豈不是沒有了安全可言。

4.解決跨域問題-fetch同源限制

場景2、iframe跨域引用問題

通常出於安全,頁面的HTTP請求的Response頭部設置了X-Frame-Options:sameorigin,防止頁面被其餘站點內嵌。

解決跨域問題-iframe跨域問題

4.2nginx解決方案-反向代理

4.2.1 什麼是反向代理

一句話解釋:客戶端請求服務器,服務器接收轉發給其餘服務器得到內容,再傳給客戶端。

反向代理(Reverse Proxy)方式是指以代理服務器來接受internet上的鏈接請求,而後將請求轉發給內部網絡上的服務器,並將從服務器上獲得的結果返回給internet上請求鏈接的客戶端,此時代理服務器對外就表現爲一個反向代理服務器。

正向代理:意思是一個位於客戶端和原始服務器(origin server)之間的服務器,爲了從原始服務器取得內容,客戶端向代理髮送一個請求並指定目標(原始服務器),而後代理向原始服務器轉交請求並將得到的內容返回給客戶端。

4.2.2 先看nginx的預期效果

當localhost訪問 /api/test/list成功轉發到koa服務(127.0.0.1:12111)返回數據

解決跨域問題-nginx反向代理

4.2.3 nginx配置反向代理

# 1.首頁爲nextjs的web server,便於SEO優化。訪問全部優先轉發給nextjs服務
location / {
    proxy_pass http://127.0.0.1:12111/;
    proxy_redirect  off;
    proxy_set_header Host $proxy_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Via "nginx";
}

# 2.轉發/api請求給前端koa服務器
location /api {
    proxy_pass http://127.0.0.1:18000/api;
    proxy_redirect  off;
    proxy_set_header Host $proxy_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Via "nginx";
}
複製代碼

4.3 iframe跨域解決

iframe跨域通常仍是經過服務器設置response header頭。分爲舊版本瀏覽器和新版本瀏覽器。舊版本:X-Frame-Options,新版本:Content-Security-Policy。可參考:developer.mozilla.org/en-US/docs/…

nginx下具體設置以下,能夠指定對應可跨域iframe訪問的域名

# 被內嵌iframe web設置
server {    
    listen       10004;
    server_name  localhost;
    root C:/server/siteB;
    index  index.html index.htm;
    location / {
      # 舊版本
      add_header X-Frame-Options "ALLOW-FROM http://localhost";
      # 新版本使用csp
      # add_header Content-Security-Policy "frame-ancestors 'self’ http://localhost";
    } 
}
複製代碼

4.解決跨域問題-iframe跨域問題-設置頭

4.4 http報頭跨域

通常爲開發階段的mock server,或者設置容許跨域的域名.這樣,咱們能夠直接訪問mock數據

解決跨域問題-iframe跨域問題-http報頭跨域設置

解決跨域問題-iframe跨域問題-http報頭跨域效果

☆5.部署react/vue單頁面靜態項目

本章節做爲react/vue開發者必備部署知識,由於你的代碼始終是要發佈的,出了啥問題你就能很快定位(甩鍋)問題所在。

5.1 單頁面應用核心問題

部署單頁面應用項目咱們核心思考的問題:服務器端路由與靜態單頁面應用路由的轉換過程

部署react、vue單頁面靜態應用-服務器端路由與靜態單頁面應用路由的轉換過程思考

5.2 nginx配置單頁面應用

咱們進行分析:當訪問url時,先訪問nginx服務器,nginx路由斷定後給前端路由託管。咱們得出如下的配置:訪問靜態資源子路徑下的全部路由均轉發給靜態資源的index.html文件。實現後端路由轉換爲前端路由。

# 1.create-react-app靜態項目
location /react-app {
  # 路徑
  alias C:/server/create-react-app-antd/build;
  # 默認首頁
  index index.html;
  # 訪問不到資源後的處理
  try_files $uri $uri/ /react-app/index.html;
}

# 2.vue靜態項目
location /vue-app {
  alias C:/server/vueapp/build;
  index index.html;
  try_files $uri $uri/ /vue-app/index.html;
}

複製代碼

問題一:原始項目直接配置完成沒法訪問,資源報錯

vue-cli項目配置

首先,若是直接從vue官網的命令安裝依賴,執行npm run build,配置完是會報錯的。

部署react、vue單頁面靜態應用-vue或react原始項目直接build會報錯

問題緣由:css/js資源引用路徑沒有引用到,解決方法1改爲相對路徑訪問

部署react、vue單頁面靜態應用-單頁面靜態的前端資源須要變爲相對路徑

修改後從新編譯,成功訪問

部署react、vue單頁面靜態應用-vue靜態頁面完成部署

react項目配置

默認create-react-app-antd項目npm run build後配置完會出現資源沒法訪問的問題。緣由,項目都是絕對路徑訪問資源。

部署react、vue單頁面靜態應用-react默認項目路徑報錯

react項目裏面因爲腳手架配置讀取package.json的homepage項爲根路徑

部署react、vue單頁面靜態應用-react項目修改資源路徑

從新打包編譯後正常訪問。這裏稍做修改,項目內容增長了路由跳轉,這樣好測試靜態資源路由功能。

部署react、vue單頁面靜態應用-react項目正確配置完成後預覽效果

問題二:我上線出現了點擊上面react項目首頁 http://localhost/react-app/ 點擊連接跳轉 http://localhost/react-app/test 能打開,但我刷新頁面報nginx404了。(不少小夥伴都出現了發佈後出現這個狀況明明默認都能點,刷新頁面後就打不開了報404)

部署react、vue單頁面靜態應用-react項目正常路由跳轉到test子路由

子路由刷新頁面後404

部署react、vue單頁面靜態應用-react項目子路由刷新後報404

why刷新報錯?

冷靜思考,根源仍是來自於先後端路由的轉換問題,還記得上面配置行(3行)中重要的一句話:try_files 嘗試文件,也就是說服務器找不到文件你得告訴怎麼處理跳轉到哪兒。也就定位到問題:try_files uriuri/ /react-app/index.html;這句異常處理若是不加就會致使刷新訪問不到文件的問題。 回味一下配置:訪問不到的時候轉發給下面的index.html頁面,index.html無縫對接前端的路由。問題解決。

location /react-app {
  alias C:/server/create-react-app-antd/build;
  index index.html;
  # 下面這句話就起做用了很關鍵
  try_files $uri $uri/ /react-app/index.html;
}
複製代碼

至此,您已具有單頁面應用項目的能力,斷定資源訪問路徑,並且還可以排查出部署刷新頁面報404這樣的經典問題。任務3,4react/vue的靜態子項目成功部署。

6 https訪問

至此,上述的幾個應用系統已經徹底貫通運做。但http不是不安全嗎,我須要用https讓網站可以安全訪問。

6.1 https基於ssl證書訪問關鍵要素

  • 申請證書、祕鑰(openssl工具)
  • 配置nginx

其實本地環境是能夠經過命令行工具生成祕鑰和證書,用來測試https

nginx 本地https祕鑰可參考文檔:www.cnblogs.com/isylar/p/10…

先看效果:https訪問後端口號變爲了443

https訪問-成功配置效果

nginx配置以下:最關鍵的就是pem證書和key的生成。按照上面文檔本地就能夠生成,網上也有不少關於https證書祕鑰生成教程。

server {
        listen 443 ssl;
        server_name localhost;
        index index.html index.htm index.php;
        root  C:/lc/server;
        # pem證書路徑
        ssl_certificate  C:/lc/work/proj/https/server/server.pem;
        # pem證書路徑
        ssl_certificate_key C:/lc/work/proj/https/server/server.key;
        ssl_session_timeout 5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        location / {
          …
        }
}

複製代碼

問題:本地剛配置https訪問後瀏覽器提示不安全的鏈接

https訪問-本地剛配置好提示不安全

解答:因爲瀏覽器https是須要通過合法CA辦法的證書,咱們本身配置的並不是通過證書頒發機構。點擊繼續前往仍是可以本地訪問到。

如何強制http請求轉爲https請求

nginx配置爲:80端口訪問後rewrite全部請求爲https

server {
      listen 80;
      server_name  localhost;
      # 強制使用https
      rewrite ^(.*)$ https://$host$1 permanent;
}

複製代碼

7.持續集成CI-自動化部署

7.1核心思想

  • 具備執行服務器端腳本能力
  • 經過web等UI界面方便操做
  • 支持經過如git web hook等觸發式構建

7.2經常使用軟件

7.3本地寫個自動更新代碼自動打包的腳本

咱們在剛剛 C:/server/create-react-app-antd下新建build.sh和build.bat,用來執行後自動拉取代碼以及自動執行編譯打包

build.bat

echo start build...
echo running step 1.git pull
git pull
echo running step 2.npm run build
npm run build
複製代碼

build.sh

#!/usr/bin/env bash
echo start build...
echo running step 1.git pull
git pull
echo running step 2.npm run build
npm run build
複製代碼

收尾

能看到這裏,真心感謝您的耐心,是否是有種醍醐灌頂,原來前端部署一篇就夠了。有了這些,咱們在之後的前端上線部署再也不是盲區,又可以快速定位問題。 結尾仍是那句話:要是幫到了您,還請順便點個贊,謝謝(90度鞠躬)。

想了解skFeTeam更多的分享文章,能夠點這裏,謝謝~

相關文章
相關標籤/搜索