使用pm2部署vue项目

pm2简介

pm2 是一个带有负载均衡功能的Node应用的进程管理器。

npm i -g pm2

动态部署

(1)npm run dev可以写成:

pm2 start npm -- run dev

(2)也可以指定项目名称启动:

pm2 start npm --watch --name xxx -- run start

(3)还可以配置到package.json的scripts脚本中:

"scripts": {
    "dev": "node --icu-data-dir=node_modules/full-icu server.js",
    "build": "next build",
    "script": "node ./scripts/default-lang",
    "pm2": "pm2 start npm --name 'checkout-counter' -- run start",
    "start": "NODE_ENV=production node --icu-data-dir=node_modules/full-icu server.js",
    "pm2-test": "pm2 start npm --name 'checkout-counter' -- run start-test",
    "start-test": "NODE_ENV=test node --icu-data-dir=node_modules/full-icu server.js",
    "pm2-sandbox": "pm2 start npm --name 'checkout-counter' -- run start-sandbox",
    "start-sandbox": "NODE_ENV=sandbox node --icu-data-dir=node_modules/full-icu server.js",
    "pm2-develop": "pm2 start npm --name 'checkout-counter' -- run start-develop",
    "start-develop": "NODE_ENV=develop node --icu-data-dir=node_modules/full-icu server.js"
}

启动示例:

npm run pm2-test
  • server.js
// Polyfill Node with `Intl` that has data for all locales.
// See: https://formatjs.io/guides/runtime-environments/#server
const IntlPolyfill = require('intl');
Intl.NumberFormat = IntlPolyfill.NumberFormat;
Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;

const { readFileSync } = require('fs');
const { basename } = require('path');
const { createServer } = require('http');
const accepts = require('accepts');
const glob = require('glob');
const next = require('next');
const express = require('express');

const port = parseInt(process.env.PORT, 10) || 2027;
const env = process.env.NODE_ENV || 'dev';
const dev =
  process.env.NODE_ENV !== 'production' &&
  process.env.NODE_ENV !== 'test' &&
  process.env.NODE_ENV !== 'sandbox';
const app = next({ dev });
const handle = app.getRequestHandler();
const ecosystemEnv = require('./config/ecosystem.config');

// Get the supported languages by looking for translations in the `lang/` dir.
const supportedLanguages = glob.sync('./locales/lang/*.json').map(f => basename(f, '.json'));

// We need to expose React Intl's locale data on the request for the user's
// locale. This function will also cache the scripts by lang in memory.
const localeDataCache = new Map();
const getLocaleDataScript = locale => {
  const lang = locale.split('-')[0];
  if (!localeDataCache.has(lang)) {
    const localeDataFile = require.resolve(
      `@formatjs/intl-relativetimeformat/dist/locale-data/${lang}`
    );
    const localeDataScript = readFileSync(localeDataFile, 'utf8');
    localeDataCache.set(lang, localeDataScript);
  }
  return localeDataCache.get(lang);
};

// We need to load and expose the translations on the request for the user's
// locale. These will only be used in production, in dev the `defaultMessage` in
// each message description in the source code will be used.
const getMessages = locale => {
  return require(`./locales/lang/${locale}.json`);
};
//
// app.prepare().then(() => {
//   createServer((req, res) => {
//     const accept = accepts(req);
//     const locale = accept.language(supportedLanguages) || 'en-US';
//     // const locale = req.url.substring(req.url.indexOf('lang=')).slice(5);
//     // const lang = locale.split('-')[0];
//     req.locale = locale;
//     req.localeDataScript = getLocaleDataScript(locale);
//     req.messages = dev ? {} : getMessages(locale);
//     handle(req, res);
//   }).listen(port, err => {
//     if (err) throw err;
//     console.log(`> Ready on http://localhost:${port}`);
//   });
// });
let HOST = ecosystemEnv[process.env.NODE_ENV];
if (dev) {
  HOST = ecosystemEnv.develop;
} else {
  HOST = ecosystemEnv[process.env.NODE_ENV];
}
const devProxy = {
  '/api': {
    target: HOST,
    pathRewrite: { '^/api': '' },
    secure: false,
    changeOrigin: true,
  },
};

let server;
app
  .prepare()
  .then(() => {
    server = express();

    // Set up the proxy.
    if (devProxy) {
      const proxyMiddleware = require('http-proxy-middleware');
      Object.keys(devProxy).forEach(function(context) {
        server.use(proxyMiddleware(context, devProxy[context]));
      });
    }

    // Default catch-all handler to allow Next.js to handle all other routes
    server.all('*', (req, res) => {
      const accept = accepts(req);
      // console.log('accept', accept);
      const locale = accept.language(supportedLanguages) || 'en-US';
      // console.log('supportedLanguages', supportedLanguages);
      // console.log('locale', locale);
      // const locale = req.url.substring(req.url.indexOf('lang=')).slice(5);
      // const lang = locale.split('-')[0];
      req.locale = locale;
      req.localeDataScript = getLocaleDataScript(locale);
      req.messages = dev ? {} : getMessages(locale);
      handle(req, res);
    });

    server.listen(port, err => {
      if (err) {
        throw err;
      }
      console.log(`> Ready on port ${port} [${env}]`);
    });
  })
  .catch(err => {
    console.log('An error occurred, unable to start the server');
    console.log(err);
  });
  • config/ecosystem.config.js
module.exports = {
  develop: 'https://api-develop.appblog.cn',
  test: 'https://api-test.appblog.cn',
  sandbox: 'https://api-sandbox.appblog.cn',
  production: 'https://api.appblog.cn',
};

静态部署

为什么要使用pm2运行vue项目

可能很多人都会疑惑,使用vue做好的项目直接打包放在服务器上不就可以了吗?众所周知vue打包后会生成一个名为dist的静态资源文件夹,那么如果想要在云服务器访问这些资源只能通过 http://xxxx.com/dist/index.html 来访问。如果想要和vue脚手架搭建的本地项目一样 使用端口号来监听/运行项目(如:http://xxxx.com:8080 ),我们就需要自己搭建一个服务,然后通过pm2进行启动。

打包项目

npm run build  //vue脚手架默认打包命令,打包后会在当前项目文件夹创建一个名为dist的文件夹

搭建服务

首先在当前项目文件夹里创建一个bin目录,bin目录下创建一个js启动文件,名字随意(不可和别的项目启动文件冲突),这里命名的是demo.js

const express = require('express');  //npm下载并引入express模块 npm -express -D

const app = express();
app.use(express.static('./dist'))  // ./dist 为vue打包后dist文件夹的路径
app.listen(8080,function(err) {  //8080 想要监听项目的端口号
    if (err) {
        console.log(err)
    } else {
        console.log('项目启动成功')
    }
})

pm2启动项目

首先解释一下为什么要使用pm2启动项目,vue自带的启动服务命令只能在终端开启的情况下运行,如果关闭终端,则该项目的服务也会跟着一起关闭,而使用pm2命令启动的服务是一直运行的,就算关闭终端 项目服务也不会停止。

(1)启动服务

pm2 start demo.js  //启动名为demo.js 的启动文件

(2)关闭服务

pm2 stop demo.js

(3)重启服务

pm2 restart demo.js

(4)删除服务

pm2 delete demo.js

(5)查看服务列表

pm2 list

启动后在浏览器输入 http://xxxx.com:8080 即可访问项目

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/03/30/deploy-vue-projects-using-pm2/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
使用pm2部署vue项目
pm2简介 pm2 是一个带有负载均衡功能的Node应用的进程管理器。 npm i -g pm2 动态部署 (1)npm run dev可以写成: pm2 start npm -- run dev (2)也可以指……
<<上一篇
下一篇>>
文章目录
关闭
目 录