Node JS后端項目開發(fā)與生產(chǎn)環(huán)境總結(jié)

Node

原文地址:Node JS后端項目開發(fā)與生產(chǎn)環(huán)境總結(jié)

Node JS常用后端框架有express、koa、sails。國產(chǎn)框架有個egg js,已經(jīng)在cnode投入生產(chǎn)了,還有個think js,類似think php,在此支持一波。每個框架在開發(fā)環(huán)境與生產(chǎn)環(huán)境都有所不同,這里以koa為例

開發(fā)環(huán)境與生產(chǎn)環(huán)境的區(qū)別

建立在后臺模板渲染(ejs, pug)的基礎(chǔ)上。前后分離架構(gòu)請參考webpack熱更新實現(xiàn)

開發(fā)環(huán)境

  • 熱更新
  • 錯誤處理
  • 前端js代碼自動打包

生產(chǎn)環(huán)境

  • 靜態(tài)緩存(static cache)
  • 內(nèi)容壓縮(gzip)
  • 日志文件
  • 進(jìn)程守護(hù)
  • 強(qiáng)制https
  • 404處理
  • 負(fù)載均衡
  • 前端js代碼混淆壓縮

開發(fā)環(huán)境配置

熱更新(nodemon)

nodemon在js文件變化后悔重新運(yùn)行程序,在package.jsonscripts中添加:

dev: 'nodemon server.js'
npm run dev

nodemon還有許多可選配置,具體參閱nodemon文檔

錯誤處理

以koa為例

app.on('error', err => {
  log.error('server error', err)
});

如若想要將錯誤拋出到瀏覽器頁面和美化錯誤頁面,express可用express-error-handlerkoa可用onerror

前端js代碼自動打包(webpack)

由于是后臺模板渲染,所以沒法用webpack-dev-server進(jìn)行自動刷新。能做的就是利用webpackwatch在前端js改變后自動打包,當(dāng)然還是免不了手動刷新

// webpack.config.js
const config = {
    entry: {
        app: path.resolve(root, './modules/app.js'),
        about: path.resolve(root, './modules/about.js'),
    },
    output: {
        path: path.resolve(root, './dist'),
        publicPath: path.resolve(root, './dist'),
        filename: '[name].js'
    },
    module: {
        rules: [
            {
                test: /(\.js)$/,
                use: {
                    loader: "babel-loader",
                },
                exclude: /node_modules/
            }
        ]
    },
    devtool: '#eval-source-map',
    watch: true,
    watchOptions:{
        poll:1000,//監(jiān)測修改的時間(ms)
        ignored:/node_modules/,//不監(jiān)測
    }
};

注意一定要開啟source-map,不然無法定位報錯位置。為通知webpack是生產(chǎn)還是開發(fā)環(huán)境,可以使用cross-env,然后在package.jsonscripts中添加:

"watch": "cross-env NODE_ENV=development webpack --watch webpack.config.js"

開發(fā)時應(yīng)運(yùn)行兩個命令:

// nodemon
npm run dev

// webpack
npm run watch

生產(chǎn)環(huán)境

生產(chǎn)環(huán)境一般使用pm2,pm2已經(jīng)幫我們完成了進(jìn)程守護(hù)和負(fù)載均衡,內(nèi)部實現(xiàn)原理在此不再贅述,具體參考pm2文檔

// 生成pm2配置文件ecosystem.config.js
pm2 ecosystem

生成的配置文件已包含了生產(chǎn)環(huán)境的基本本質(zhì)。跟多配置請參考pm2文檔,在package.json文件的scripts中添加

"prd": "pm2 start ecosystem.config.js --env production"

生產(chǎn)環(huán)境下運(yùn)行

npm run prd

這時我們可以通過process全局變量獲取到環(huán)境狀態(tài),在app.js中添加

const prdEnv = process.env.NODE_ENV == 'production'

靜態(tài)緩存

const staticCache = require('koa-static-cache')
if(prdEnv) {
    // 靜態(tài)緩存
    app.use(staticCache(path.join(__dirname, 'public'), {
        maxAge: 365 * 24 * 60 * 60
    }))
}

gzip

const compress = require('koa-compress')
if(prdEnv) {
    // gzip
    app.use(compress({
        filter: function (content_type) {
            return /text/i.test(content_type)
        },
        threshold: 2048,
        flush: require('zlib').Z_SYNC_FLUSH
    }))
}

日志文件

類似nginxaccess.logerror.log,利用fs模塊的appendFile方法來輸出日志。首先在項目根目錄下新建文件夾logs

const fs = require('fs')
const path = require('path')
if(prdEnv) {
    // logger
    app.use(async(ctx, next) => {
        const start = new Date()
        await next()
        const ms = new Date() - start
        fs.appendFile(path.join(__dirname, 'logs', ctx.status < 400 ? 'access.log' : 'error.log'), `[${start.toLocaleString()}] ${ctx.status} ${ctx.method} ${ctx.url} - ${ms}ms\r\n`)
    })
}

強(qiáng)制https

// force https
app.use((ctx, next) => {
    if(ctx.protocol == 'http') {
        ctx.redirect(ctx.href.replace('http', 'https'))
    } else {
        return next()
    }
})

404處理

建立一個模板命名為notFound.pug,在路由之后渲染

// 404
app.use(async (ctx) => {
    await ctx.render('notFound')
})

前端js代碼壓縮混淆

在webpack中添加插件

// webpack.config.js
// 提取公共js
new webpack.optimize.CommonsChunkPlugin({name: 'common'})

// 壓縮代碼
new webpack.optimize.UglifyJsPlugin({
    sourceMap: false,
    parallel: true,
    mangle: true,
    compress: {
        warnings: false,
        drop_debugger: true,
        drop_console: true
    }
})

// package.json
"build": "cross-env NODE_ENV=production webpack --config webpack.config.js"

發(fā)布應(yīng)用時需運(yùn)行

npm run build

npm run prd
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容