发布于 2026-01-06 0 阅读
0

Express、VueJS 和 PostgreSQL 入门指南

Express、VueJS 和 PostgreSQL 入门指南

佩夫尼

我们都听说过 MEAN(MongoDB Express Angular NodeJS 技术栈,或者最近出现MERN(MongoDB Express React NodeJS 技术

虽然市面上有很多使用这些技术栈的入门套件,但我想要的是类似但有一些改动的。我想把 MongoDB 换成 PostgreSQL,因为它功能强大,几乎可以胜任任何任务;我还想把 React 换成 VueJS,因为我发现 Vue 更容易上手,对新手更友好。

我没找到类似的东西,所以就自己做了一个。就叫它 PEVN(PostgreSQL Express View ueJS NodeJS )栈吧,我知道……一点创意都没有!

我花了几个小时才把所有东西都设置成我想要的样子。我把整个过程记录了下来,希望能帮到其他想做同样事情的人,具体内容如下。

TL;DR - https://github.com/jesalg/penv-starter

NodeJS

在开始之前,请确保已安装 NodeJS。我发现最简单的方法是通过 nvm 安装。Rails 开发人员会发现它与 rvm 非常相似。要安装 nvm,请运行以下命令,这些命令将安装 nvm 和最新版本的 NodeJS:

$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh | bash
$ source ~/.bash_profile
$ nvm install node
$ nvm use node
Enter fullscreen mode Exit fullscreen mode

表达

安装 Express 最简单的方法是使用生成器:

$ npm install express-generator -g
$ express pevn-starter
$ cd pevn-starter && npm install
Enter fullscreen mode Exit fullscreen mode

VueJS

现在我们已经有了一个基本应用,接下来进入有趣的部分。我们将把每个 Express 视图都当作一个独立的 VueJS 应用(MVVM 模式)来处理,它会从 DOM 中获取所需数据,或者向服务器发送 AJAX 请求。

因此,对于这个例子,假设我们有了 Jade 视图views/index.jade,我们希望将其关联的 VueJS 应用和样式放在 Jade 视图中client/css/index.cssclient/js/index.js以便/client/js/Index.vue当渲染 Jade 视图时,它会运行 Index Vue 应用。

所以我们需要告诉视图views/index.jade加载我们打包好的资源文件:

extends layout

block content
  #index(data-visitors-json="#{JSON.stringify(visitors)}")
  script(src="#{webpack_asset('index', 'js')}")
  link(rel='stylesheet', href="#{webpack_asset('index', 'css')}")
Enter fullscreen mode Exit fullscreen mode

我们的client/js/index.js程序将引导我们的 Index Vue 应用:

import Vue from 'vue'
import Index from './Index.vue'

new Vue({
  el: '#index',
  data: {
    visitors: []
  },
  render (createElement) {
    return createElement(Index)
  },
  beforeMount() {
    this.visitors = JSON.parse(this.$el.dataset.visitorsJson) //Grab this data from the DOM
  }
})
Enter fullscreen mode Exit fullscreen mode

我们的 Vue 应用位于client/js/Index.vue

<template>
    <div>
        <h1>Hello World</h1>
        <p>Welcome to PostgreSQL, Express, VueJS, NodeJS starter</p>
        <p>Here are the last 10 visitors:</p>
        <table>
          <thead>
            <th>ID</th>
            <th>IP</th>
            <th>User Agent</th>
          </thead>

          <tr v-for="(visitor, index) in visitors" :key="index">
              <td>{{ visitor.id }}</td>
              <td>{{ visitor.ip }}</td>
              <td>{{ visitor.user_agent }}</td>
          </tr>
        </table>
    </div>
</template>

<script>
export default {
  data() {
    return {
      visitors: []
    }
  },
  methods: {

  },
  created() {
    this.visitors = this.$parent.visitors; //Grab this data from the parent
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

暂时不用担心显示访客列表的逻辑,我们稍后再谈。

Webpack

为了创建视图的打包 index.js 资源文件,我们需要安装 Webpack、VueJS 及其相关依赖项:

$ npm install webpack extract-text-webpack-plugin assets-webpack-plugin babel-core babel-loader babel-preset-es2015 css-loader file-loader style-loader url-loader vue-template-compiler --save-dev
$ npm install vue express-webpack-assets webpack-dev-middleware webpack-hot-middleware
Enter fullscreen mode Exit fullscreen mode

接下来,我们在项目根目录创建 webpack.config.js 文件,并将以下内容粘贴到其中:

var path = require('path')
var webpack = require('webpack')
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var SaveHashes = require('assets-webpack-plugin');
var isProd = (process.env.NODE_ENV === 'production');

var config = {
  entry: {
    index: [
      path.join(__dirname, 'client/js/index.js'),
      path.join(__dirname, 'client/css/index.css')
    ],
  },
  output: {
    path: path.join(__dirname, 'public/dist/'),
    publicPath: '/dist/',
    filename: '[name].[hash].js'
  },
  resolve: {
    extensions: ['.js', '.vue'],
    alias: {
      vue: isProd ? 'vue/dist/vue.min.js' : 'vue/dist/vue.js',
    }
  },
  module: {
    rules: [{
        test: /\.vue$/,
        exclude: /node_modules/,
        use: [{
          loader: 'vue-loader'
        }]
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [{
          loader: 'babel-loader',
          options: {
            presets: ['es2015']
          }
        }]
      },
      {
        test: /\.svg/,
        use: {
          loader: 'svg-url-loader',
          options: {}
        }
      },
      {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: {
            loader: 'css-loader',
            options: {
              minimize: true
            }
          }
        })
      },
    ]
  },
  devtool: 'eval-source-map',
  plugins: [
    new SaveHashes({
      path: path.join(__dirname, 'config')
    }),
    new ExtractTextPlugin({
      publicPath: '/dist/',
      filename: '[name].[hash].css',
      allChunks: true
    }),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify('production')
      }
    })
  ]
}

if (isProd) {
  config.plugins.push(new webpack.optimize.UglifyJsPlugin());
}

module.exports = config
Enter fullscreen mode Exit fullscreen mode

我们的 Webpack 配置将确保客户端文件夹中的资源被编译成一个压缩的 JS 和 CSS 包,并带有可清除缓存的哈希文件名。

现在我们需要告知 Express 我们正在使用 Webpack,并且希望在启动时运行它。因此,请在 app.js 文件中添加以下代码:

var webpack = require('webpack')
var webpackDevMiddleware = require('webpack-dev-middleware')
var webpackHotMiddleware = require('webpack-hot-middleware')
var webpackAssets = require('express-webpack-assets')
.
.
.
// webpack setup
if (NODE_ENV === 'production') {
  app.use(express.static(__dirname + '/dist'));
} else {
  const compiler = webpack(config)
  app.use(webpackDevMiddleware(compiler, {
    publicPath: config.output.publicPath,
    stats: { colors: true }
  }))
  app.use(webpackHotMiddleware(compiler))
}
app.use(webpackAssets('./config/webpack-assets.json', {
  devMode: NODE_ENV !== 'production'
}));
.
.
.
Enter fullscreen mode Exit fullscreen mode

PostgreSQL

最后,我们通过安装sequelize ORM 及其相关依赖项来添加 pg 支持:

$ npm install sequelize pg pg-hstore --save
$ npm install sequelize-cli --save-dev
$ ./node_modules/.bin/sequelize init
Enter fullscreen mode Exit fullscreen mode

运行这些命令会生成一些设置代码,您只需要更新您的config/config.json连接信息即可:

{
  "development": {
    "username": "root",
    "password": null,
    "database": "pevn_development",
    "host": "127.0.0.1",
    "dialect": "postgres"
  },
  "test": {
    "username": "root",
    "password": null,
    "database": "pevn_test",
    "host": "127.0.0.1",
    "dialect": "postgres"
  },
  "production": {
    "username": "root",
    "password": null,
    "database": "pevn_production",
    "host": "127.0.0.1",
    "dialect": "postgres"
  }
}
Enter fullscreen mode Exit fullscreen mode

有了这些信息,我们就可以创建第一个模型并运行迁移了:

$ ./node_modules/.bin/sequelize model:generate --name Visitor --attributes ip:string,user_agent:string
$ ./node_modules/.bin/sequelize db:create
$ ./node_modules/.bin/sequelize db:migrate
Enter fullscreen mode Exit fullscreen mode

在本示例中,我们将创建一个名为 Visitors 的表,该表会在每次用户访问首页时记录用户的 IP 地址和 UserAgent 字符串,并输出最近 10 条记录:

var express = require('express');
var models = require('../models');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  models.Visitor.create({
    user_agent: req.get('User-Agent'),
    ip: req.ip,
  }).then(() => {
    models.Visitor.findAll({limit: 10, order: [['createdAt', 'DESC']]}).then((visitors) => {
      res.render('index', { title: 'PEVN Stack!', visitors: visitors });
    })
  });
});

module.exports = router;
Enter fullscreen mode Exit fullscreen mode

结论

至此,我们就完成了整个流程,形成了一个闭环。如果一切顺利,您现在应该能够使用以下命令在 4000 端口运行您的应用程序:

$ npm start
Enter fullscreen mode Exit fullscreen mode

您可能会注意到,每次更改服务器代码时,应用程序都需要重启,这可能会非常烦人。我们可以改用 nodemon,这样应用程序就可以在代码更改时自动重启:

$ npm install --save-dev nodemon
Enter fullscreen mode Exit fullscreen mode

在我们的配置中nodemon.json,我们可以设置当服务器端逻辑发生更改时,程序自动重启:

{
  "verbose": true,
  "ignore": ["public/"],
  "events": {
    "restart": "osascript -e 'display notification \"App restarted due to:\n'$FILENAME'\" with title \"nodemon\"'"
  },
  "watch": ["routes/"],
  "env": {
    "NODE_ENV": "development"
  },
  "ext": "js jade"
}
Enter fullscreen mode Exit fullscreen mode

最后,我们可以将 npm start 命令更新为:nodemon app.js

还有一些更有趣的功能,我为了方便快速入门就没一一介绍。例如,我们可以用 Babel 来运行 NodeJS 服务器逻辑,这样服务器端也能使用 ES6 语法了。期待社区提交这类增强功能的 pull request! :)

这篇文章最初发表在我的博客上。如果您喜欢这篇文章,请在社交媒体上分享并关注我的推特

文章来源:https://dev.to/jesalg/getting-started-with-express-vuejs--postgresql--24db