使用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全栈技术分享
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论