亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Node中間層實踐(二)——搭建項目框架

DrizzleX / 3416人閱讀

摘要:項目地址腳手架使用過,的同學(xué)都清楚,官方推薦的安裝方式是通過專用的來快速搭建一個由編譯打包的項目框架。用在層的模塊化,在中間層實現(xiàn)了模塊化。這樣,從中間層到前端都實現(xiàn)了熱加載。

版權(quán)聲明:更多文章請訪問我的個人站Keyon Y,轉(zhuǎn)載請注明出處。

項目地址:https://github.com/KeyonY/NodeMiddle

腳手架?

使用過angular2,vue2的同學(xué)都清楚,官方推薦的安裝方式是通過專用的angular-cli、vue-cli來快速搭建一個由webpack編譯、打包的項目框架。

受這兩個工具的啟發(fā),我在項目之初開發(fā)一個基于webpack的項目框架:

使用express搭載webpack-dev-middleware和webpack-hot-middleware進(jìn)行熱加載

內(nèi)置dev(開發(fā)環(huán)境)和 production(生產(chǎn)環(huán)境)兩種啟動方式

技術(shù)選型 node開發(fā)框架

express和koa二選一。

express的更貼近Web Framework這一概念;

express功能極簡,完全是由路由和中間件構(gòu)成一個的 web 開發(fā)框架:從本質(zhì)上來說,一個 Express 應(yīng)用就是在調(diào)用各種中間件;

koa使用co作為底層運行框架,使用它完全忘記了什么時候回調(diào)函數(shù)或者callbackshell;

express歷史更久,裝機量大,文檔完整,第三方的中間件也很多;

我選擇了express作為node開發(fā)框架。

模板引擎

由于之前用node寫過restFul的網(wǎng)站(詳見我的博客-NodeJS開發(fā)個人博客網(wǎng)站),比較熟悉jade,所以這次直接選擇了pug作為服務(wù)器端模板引擎。
pug是一個比較靈活的服務(wù)器端模板,express配置起來也很簡單,在根目錄的app.js文件中配置

// 設(shè)置模板引擎的類型
app.set("view engine", "pug");
// 設(shè)置模板文件路徑
app.set("views", path.resolve(__dirname, "src/Views"));

這樣,在express渲染時候使用 res.render("Home/index", {}),指定對應(yīng)的頁面模板路徑就行了,第二個參數(shù) 是要在pug頁面使用的數(shù)據(jù)內(nèi)容,json格式。

中間層與后端的異步通信

其實就是個ajax庫,所以我選擇了axios,vue2官方推薦的ajax庫,內(nèi)置的axios.all(),可以在中間層代理多個后端請求一并返回,輕松實現(xiàn)Bigpipe。

模塊化

因為是網(wǎng)站前臺頁面,需要考慮SEO,無法使用前端框架,所以換個思路,使用webpack+es6/AMD來實現(xiàn)模塊化。
于是,使用webpack作為打包機+View層的模塊化,從前端層面實現(xiàn)了模塊化和組件化。
es6用在Contorl層的模塊化,在node中間層實現(xiàn)了模塊化。

環(huán)境配置(啟動文件)

app.js作為項目的啟動文件,是express的配置文件,同時也是運行開發(fā)環(huán)境 / 生產(chǎn)環(huán)境的配置文件。

通過node啟動時配置的命令參數(shù),由app.js接收參數(shù),然后運行對應(yīng)的環(huán)境

我們需要安裝cross-env這個插件

npm i --save-dev cross-env

在package.json的scripts中配置:

...
"scripts": {
    "start": "cross-env NODE_ENV=production node app.js",
    "dev": "cross-env NODE_ENV=dev supervisor -w app.js app",
    "build": "webpack --config build/webpack.prod.config.js"
  }
...

這樣,使用 process.env.NODE_ENV 就可以獲取node啟動的環(huán)境參數(shù)。

這里我配置了 開發(fā)環(huán)境(dev) 和 生產(chǎn)環(huán)境(production)

開發(fā)環(huán)境: 不壓縮代碼,開啟devtool生成source-map,便于調(diào)試代碼;

生產(chǎn)環(huán)境: 是用webpack進(jìn)行打包、壓縮、混淆操作,將最終完整的代碼(應(yīng)用)輸出至dist目錄中,然后再啟動node服務(wù)器,運行應(yīng)用;

上述代碼中還用到了 supervisor插件,這是監(jiān)聽node配置文件(app.js)的更改,并自動重啟node的。

npm i --save-dev supervisor

前端層面使用webpack-dev-middleware和webpack-hot-middleware,實現(xiàn)了熱加載。

這樣,從中間層到前端都實現(xiàn)了熱加載。

node中間層配置

在根目錄下新建了config文件夾,將一些常用的配置/參數(shù)、方法抽出來,寫在了config/config.js 和 config/common.js中。

例如,中間層啟動的端口號、應(yīng)用的根目錄(path.resolve(__dirname,"../"))、后端服務(wù)器的ip、前端SEO的description和keywords等參數(shù),都放在了config.js中,通過AMD規(guī)范在所有使用的文件中統(tǒng)一引入,修改起來也方便。

app.js

var express = require("express");
var cookieParser = require("cookie-parser");
var path = require("path");
var localOptions = require("./build/localOptions");
var config = require("./config/config");
var bodyParser = require("body-parser");
var auth = require("./middleware/auth");
var log4js = require("./config/log4js");

process.env.NODE_ENV = process.env.NODE_ENV ? process.env.NODE_ENV : "production";
var isDev = process.env.NODE_ENV === "dev";
var app = express();
var port = config.port;


app.set("view engine", "pug");
// 設(shè)置模板文件路徑
if (isDev){
    app.set("views", path.resolve(__dirname, "src/Views"));
}else {
    app.set("views", path.resolve(__dirname, "dist/Views"));
}

// app.locals定義的鍵值對能在模板中直接訪問
app.locals.env = process.env.NODE_ENV || "dev";
app.locals.reload = true;

app.use(cookieParser());
app.use(bodyParser.urlencoded({extended: false}));


if (isDev) {
    // app.locals.pretty = true;
    // 開發(fā)環(huán)境,靜態(tài)文件使用熱插拔
    var webpack = require("webpack");
    var webpackDevMiddleware = require("webpack-dev-middleware");
    var webpackHotMiddleware = require("webpack-hot-middleware");
    var webpackDevConfig = require("./build/webpack.dev.config.js");

    var compiler = webpack(webpackDevConfig);
    // 熱插拔
    app.use(webpackDevMiddleware(compiler, {
        publicPath: webpackDevConfig.output.publicPath,
        noInfo: true,
        stats: "errors-only"
    }))
    app.use(webpackHotMiddleware(compiler, {
        heartbeat: 1000,
        noInfo: true,
    }));

    // 不能熱插拔的往下執(zhí)行
    var reload = require("reload");
    var http = require("http");
    var server = http.createServer(app);
    // reload(server, app);
    reload(app);
    server.listen(port, () => {
        console.log("App【dev】 is now running on port " + port + "!");
    });

    // 靜態(tài)目錄設(shè)置必須有,開發(fā)環(huán)境讀取的vendor.js不是內(nèi)存文件;
    // 靜態(tài)目錄設(shè)置必須放在reload后面,避免頁面引入reload.js報錯
    app.use(express.static(path.join(config.root, "src")));
    app.use("/", require(path.join(config.configRoot,"/routes")));
    
}else {
    // 線上環(huán)境不需要監(jiān)聽,只需開啟node服務(wù)即可
    // 設(shè)置node的靜態(tài)文件目錄
    app.use(express.static(path.join(config.root, "dist")));
    app.use("/",require(path.join(config.configRoot,"/routes")));
    // app.listen(process.env.PORT, () => {
    app.listen(port, () => {
        console.log("App【production】 is now running on port " + port + "!");
    })
}

// 捕捉 404錯誤 傳給 error路由
app.use("*", auth, (req, res, next) => {
    let err = new Error("Not Found");
    err.status = 404;
    next(err);
});

// 捕獲 error,跳轉(zhuǎn)至error頁面
app.use((err, req, res, next) => {
    const sc = err.status || 500;
    if(err.status == 405){
        res.redirect(config.cndesignOrigin + "/Home/GuideAuthentication");
        return;
    }
    res.status(sc);
    // 此處需寫入日志
    log4js.error("
 Status: "+ sc + "
 Message: " + err.message + "
 Href: " + localOptions.baseUrl + req.originalUrl + "
 User-agent: " + req.headers["user-agent"]);

    res.render("Error/404", {
        error: err,
        status: sc,
        message: err.message,
        userInfo: req.userInfo_ || { hasLogin: false }
    });
});

注意Error Handle的掛載的順序,一般掛載到app.use()下,且放在最后。

因為Error Handle的參數(shù)為4個,第一個參數(shù)err可以通過路由中的next(err)拋出,這樣所有的路由都可以隨時拋出error,讓Error Handle來捕獲。

來看一下目錄結(jié)構(gòu):

App
├─ .babelrc                         // babel的配置
├─ ReadMe                           
├─ app.js                           // 啟動文件
├─ build                            // webpack的配置文件
│    ├─ entrys.js                   // webpack打包js和css的入口文件
│    ├─ localOptions.js             // 前端開發(fā)者本地配置文件,本地ip等站點配置
│    ├─ postcss.config.js           // postcss的配置文件
│    ├─ webpack.dev.config.js       // 開發(fā)環(huán)境的webpack打包配置
│    ├─ webpack.dll.config.js       // webpack.DllReferencePlugin插件的配置文件
│    └─ webpack.prod.config.js      // 生產(chǎn)環(huán)境的webpack打包配置
├─ config                           // Model層文件:包括node服務(wù)器的配置、路由和代理接口
│    ├─ common.js                   // 中間層邏輯處理的公用方法
│    ├─ config.js                   // node服務(wù)器的配置
│    └─ routes                      // 路由和代理接口配置
│           ├─ default.js
│           ├─ designers.js
│           ├─ home.js
│           └─ index.js             // 路由和接口配置的入口文件
├─ package.json
└─ src                              // View層文件
       ├─ Components                // 公用組件
       │    ├─ base
       │    ├─ home
       │    ├─ index
       │    ├─ message
       │    ├─ modals
       │    ├─ page
       ├─ Views                     // 頁面
       │    ├─ Default
       │    ├─ Error
       │    ├─ Home
       │    ├─ Include
       │    ├─ Messages
       │    └─ Shared
       └─ assets                    // 靜態(tài)文件目錄
              ├─ Jcrop
              ├─ es5-shim-master
              ├─ images
              ├─ jquery-1.10.2.min.js
              ├─ jquery-ui-1.8.24.min.js
              └─ layui

歡迎繼續(xù)關(guān)注本博的更新
Node中間層實踐(一)——基于NodeJS的全棧式開發(fā)
Node中間層實踐(二)——搭建項目框架
Node中間層實踐(三)——webpack配置
Node中間層實踐(四)——模板引擎pug
Node中間層實踐(五)——express-中間層的邏輯處理

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/92710.html

相關(guān)文章

  • 如何打造一個令人愉悅的前端開發(fā)環(huán)境(三)

    摘要:的最后一個大招就是替換一些傳統(tǒng)的服務(wù)端語言,例如,,等,在業(yè)務(wù)層上面使用來開發(fā)服務(wù)端完全不成問題。更多的的使用細(xì)節(jié)和技巧建議關(guān)注美團(tuán)博客大搜車論壇下一篇我們開啟如何結(jié)合和搭建一個開發(fā)環(huán)境和項目目錄 往期回顧 前面2期都講得是瀏覽器端的東西比較多,包括Webpack,雖然是Node處理的,但是還是瀏覽器端用的多,對于現(xiàn)在的前端開發(fā)來說,不懂一點服務(wù)端的東西,簡直沒辦法活,一般的招聘要求都...

    cgh1999520 評論0 收藏0
  • Node間層實踐(一)——基于NodeJS的全棧式開發(fā)

    摘要:總結(jié)我覺得,以后基于的全棧式開發(fā)的模式將會越來越流行,這也會引領(lǐng)前端步入工程化時代。歡迎繼續(xù)關(guān)注本博的更新中間層實踐一基于的全棧式開發(fā)中間層實踐二搭建項目框架中間層實踐三配置中間層實踐四模板引擎中間層實踐五中間層的邏輯處理 版權(quán)聲明:更多文章請訪問我的個人站Keyon Y,轉(zhuǎn)載請注明出處。 前言 近期公司有個新項目,由于后端人手不足,我果斷的提議用node中間層的方案,得到了老大的支持...

    warkiz 評論0 收藏0
  • Node間層實踐(三)——webpack配置

    摘要:的意思是,如果碰到不能的情況,就整頁刷新首頁路由開發(fā)環(huán)境中使用了,需要將每一個的配置中寫上歡迎繼續(xù)關(guān)注本博的更新中間層實踐一基于的全棧式開發(fā)中間層實踐二搭建項目框架中間層實踐三配置中間層實踐四模板引擎中間層實踐五中間層的邏輯處理 版權(quán)聲明:更多文章請訪問我的個人站Keyon Y,轉(zhuǎn)載請注明出處。 這里沒什么可說的,webpack的配置和插件實在太多了,用的時候查文檔就行了。 項目地...

    kelvinlee 評論0 收藏0
  • 構(gòu)建前端項目

    摘要:解決思路服務(wù)器端渲染服務(wù)器端和前端公用同一個應(yīng)用,然后通過構(gòu)建工具及配置,確定哪些組件需要再服務(wù)器端渲染,那些組件需要再客戶端渲染。服務(wù)器端渲染,由框架與構(gòu)建工具配合,并依據(jù)一定的項目結(jié)構(gòu)和編碼方式,共同運行。 分離 為什么需要 前后端分離、web服務(wù)器與static服務(wù)器分離: 前端與后端耦合 (需求) 自動化、工程化的構(gòu)建前端的代碼 (基礎(chǔ)條件) 模塊化、組件化,項目共享代碼 (...

    mindwind 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<