摘要:項目地址腳手架使用過,的同學都清楚,官方推薦的安裝方式是通過專用的來快速搭建一個由編譯打包的項目框架。用在層的模塊化,在中間層實現了模塊化。這樣,從中間層到前端都實現了熱加載。
版權聲明:更多文章請訪問我的個人站Keyon Y,轉載請注明出處。
項目地址:https://github.com/KeyonY/NodeMiddle
腳手架?使用過angular2,vue2的同學都清楚,官方推薦的安裝方式是通過專用的angular-cli、vue-cli來快速搭建一個由webpack編譯、打包的項目框架。
受這兩個工具的啟發,我在項目之初開發一個基于webpack的項目框架:
使用express搭載webpack-dev-middleware和webpack-hot-middleware進行熱加載
內置dev(開發環境)和 production(生產環境)兩種啟動方式
技術選型 node開發框架express和koa二選一。
express的更貼近Web Framework這一概念;
express功能極簡,完全是由路由和中間件構成一個的 web 開發框架:從本質上來說,一個 Express 應用就是在調用各種中間件;
koa使用co作為底層運行框架,使用它完全忘記了什么時候回調函數或者callbackshell;
express歷史更久,裝機量大,文檔完整,第三方的中間件也很多;
我選擇了express作為node開發框架。
模板引擎由于之前用node寫過restFul的網站(詳見我的博客-NodeJS開發個人博客網站),比較熟悉jade,所以這次直接選擇了pug作為服務器端模板引擎。
pug是一個比較靈活的服務器端模板,express配置起來也很簡單,在根目錄的app.js文件中配置
// 設置模板引擎的類型
app.set("view engine", "pug");
// 設置模板文件路徑
app.set("views", path.resolve(__dirname, "src/Views"));
這樣,在express渲染時候使用 res.render("Home/index", {}),指定對應的頁面模板路徑就行了,第二個參數 是要在pug頁面使用的數據內容,json格式。
中間層與后端的異步通信其實就是個ajax庫,所以我選擇了axios,vue2官方推薦的ajax庫,內置的axios.all(),可以在中間層代理多個后端請求一并返回,輕松實現Bigpipe。
模塊化因為是網站前臺頁面,需要考慮SEO,無法使用前端框架,所以換個思路,使用webpack+es6/AMD來實現模塊化。
于是,使用webpack作為打包機+View層的模塊化,從前端層面實現了模塊化和組件化。
es6用在Contorl層的模塊化,在node中間層實現了模塊化。
app.js作為項目的啟動文件,是express的配置文件,同時也是運行開發環境 / 生產環境的配置文件。
通過node啟動時配置的命令參數,由app.js接收參數,然后運行對應的環境
我們需要安裝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啟動的環境參數。
這里我配置了 開發環境(dev) 和 生產環境(production)
開發環境: 不壓縮代碼,開啟devtool生成source-map,便于調試代碼;
生產環境: 是用webpack進行打包、壓縮、混淆操作,將最終完整的代碼(應用)輸出至dist目錄中,然后再啟動node服務器,運行應用;
上述代碼中還用到了 supervisor插件,這是監聽node配置文件(app.js)的更改,并自動重啟node的。
npm i --save-dev supervisor
前端層面使用webpack-dev-middleware和webpack-hot-middleware,實現了熱加載。
這樣,從中間層到前端都實現了熱加載。
node中間層配置在根目錄下新建了config文件夾,將一些常用的配置/參數、方法抽出來,寫在了config/config.js 和 config/common.js中。
例如,中間層啟動的端口號、應用的根目錄(path.resolve(__dirname,"../"))、后端服務器的ip、前端SEO的description和keywords等參數,都放在了config.js中,通過AMD規范在所有使用的文件中統一引入,修改起來也方便。
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"); // 設置模板文件路徑 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; // 開發環境,靜態文件使用熱插拔 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, })); // 不能熱插拔的往下執行 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 + "!"); }); // 靜態目錄設置必須有,開發環境讀取的vendor.js不是內存文件; // 靜態目錄設置必須放在reload后面,避免頁面引入reload.js報錯 app.use(express.static(path.join(config.root, "src"))); app.use("/", require(path.join(config.configRoot,"/routes"))); }else { // 線上環境不需要監聽,只需開啟node服務即可 // 設置node的靜態文件目錄 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,跳轉至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的參數為4個,第一個參數err可以通過路由中的next(err)拋出,這樣所有的路由都可以隨時拋出error,讓Error Handle來捕獲。
來看一下目錄結構:
App ├─ .babelrc // babel的配置 ├─ ReadMe ├─ app.js // 啟動文件 ├─ build // webpack的配置文件 │ ├─ entrys.js // webpack打包js和css的入口文件 │ ├─ localOptions.js // 前端開發者本地配置文件,本地ip等站點配置 │ ├─ postcss.config.js // postcss的配置文件 │ ├─ webpack.dev.config.js // 開發環境的webpack打包配置 │ ├─ webpack.dll.config.js // webpack.DllReferencePlugin插件的配置文件 │ └─ webpack.prod.config.js // 生產環境的webpack打包配置 ├─ config // Model層文件:包括node服務器的配置、路由和代理接口 │ ├─ common.js // 中間層邏輯處理的公用方法 │ ├─ config.js // node服務器的配置 │ └─ 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 // 靜態文件目錄 ├─ Jcrop ├─ es5-shim-master ├─ images ├─ jquery-1.10.2.min.js ├─ jquery-ui-1.8.24.min.js └─ layui
歡迎繼續關注本博的更新
Node中間層實踐(一)——基于NodeJS的全棧式開發
Node中間層實踐(二)——搭建項目框架
Node中間層實踐(三)——webpack配置
Node中間層實踐(四)——模板引擎pug
Node中間層實踐(五)——express-中間層的邏輯處理
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92710.html
摘要:的最后一個大招就是替換一些傳統的服務端語言,例如,,等,在業務層上面使用來開發服務端完全不成問題。更多的的使用細節和技巧建議關注美團博客大搜車論壇下一篇我們開啟如何結合和搭建一個開發環境和項目目錄 往期回顧 前面2期都講得是瀏覽器端的東西比較多,包括Webpack,雖然是Node處理的,但是還是瀏覽器端用的多,對于現在的前端開發來說,不懂一點服務端的東西,簡直沒辦法活,一般的招聘要求都...
摘要:總結我覺得,以后基于的全棧式開發的模式將會越來越流行,這也會引領前端步入工程化時代。歡迎繼續關注本博的更新中間層實踐一基于的全棧式開發中間層實踐二搭建項目框架中間層實踐三配置中間層實踐四模板引擎中間層實踐五中間層的邏輯處理 版權聲明:更多文章請訪問我的個人站Keyon Y,轉載請注明出處。 前言 近期公司有個新項目,由于后端人手不足,我果斷的提議用node中間層的方案,得到了老大的支持...
摘要:的意思是,如果碰到不能的情況,就整頁刷新首頁路由開發環境中使用了,需要將每一個的配置中寫上歡迎繼續關注本博的更新中間層實踐一基于的全棧式開發中間層實踐二搭建項目框架中間層實踐三配置中間層實踐四模板引擎中間層實踐五中間層的邏輯處理 版權聲明:更多文章請訪問我的個人站Keyon Y,轉載請注明出處。 這里沒什么可說的,webpack的配置和插件實在太多了,用的時候查文檔就行了。 項目地...
閱讀 2027·2023-04-26 01:33
閱讀 1659·2023-04-26 00:52
閱讀 1035·2021-11-18 13:14
閱讀 5393·2021-09-26 10:18
閱讀 2901·2021-09-22 15:52
閱讀 1488·2019-08-29 17:15
閱讀 3016·2019-08-29 16:11
閱讀 1038·2019-08-29 16:11