{"id":1879,"date":"2023-03-30T22:37:29","date_gmt":"2023-03-30T14:37:29","guid":{"rendered":"https:\/\/www.appblog.cn\/?p=1879"},"modified":"2023-04-22T09:02:27","modified_gmt":"2023-04-22T01:02:27","slug":"deploy-vue-projects-using-pm2","status":"publish","type":"post","link":"https:\/\/www.appblog.cn\/index.php\/2023\/03\/30\/deploy-vue-projects-using-pm2\/","title":{"rendered":"\u4f7f\u7528pm2\u90e8\u7f72vue\u9879\u76ee"},"content":{"rendered":"<h2>pm2\u7b80\u4ecb<\/h2>\n<p>pm2 \u662f\u4e00\u4e2a\u5e26\u6709\u8d1f\u8f7d\u5747\u8861\u529f\u80fd\u7684Node\u5e94\u7528\u7684\u8fdb\u7a0b\u7ba1\u7406\u5668\u3002<\/p>\n<pre><code class=\"language-bash\">npm i -g pm2<\/code><\/pre>\n<p><!-- more --><\/p>\n<h2>\u52a8\u6001\u90e8\u7f72<\/h2>\n<p>\uff081\uff09<code>npm run dev<\/code>\u53ef\u4ee5\u5199\u6210\uff1a<\/p>\n<pre><code class=\"language-bash\">pm2 start npm -- run dev<\/code><\/pre>\n<p>\uff082\uff09\u4e5f\u53ef\u4ee5\u6307\u5b9a\u9879\u76ee\u540d\u79f0\u542f\u52a8\uff1a<\/p>\n<pre><code class=\"language-bash\">pm2 start npm --watch --name xxx -- run start<\/code><\/pre>\n<p>\uff083\uff09\u8fd8\u53ef\u4ee5\u914d\u7f6e\u5230package.json\u7684scripts\u811a\u672c\u4e2d\uff1a<\/p>\n<pre><code class=\"language-json\">&quot;scripts&quot;: {\n    &quot;dev&quot;: &quot;node --icu-data-dir=node_modules\/full-icu server.js&quot;,\n    &quot;build&quot;: &quot;next build&quot;,\n    &quot;script&quot;: &quot;node .\/scripts\/default-lang&quot;,\n    &quot;pm2&quot;: &quot;pm2 start npm --name &#039;checkout-counter&#039; -- run start&quot;,\n    &quot;start&quot;: &quot;NODE_ENV=production node --icu-data-dir=node_modules\/full-icu server.js&quot;,\n    &quot;pm2-test&quot;: &quot;pm2 start npm --name &#039;checkout-counter&#039; -- run start-test&quot;,\n    &quot;start-test&quot;: &quot;NODE_ENV=test node --icu-data-dir=node_modules\/full-icu server.js&quot;,\n    &quot;pm2-sandbox&quot;: &quot;pm2 start npm --name &#039;checkout-counter&#039; -- run start-sandbox&quot;,\n    &quot;start-sandbox&quot;: &quot;NODE_ENV=sandbox node --icu-data-dir=node_modules\/full-icu server.js&quot;,\n    &quot;pm2-develop&quot;: &quot;pm2 start npm --name &#039;checkout-counter&#039; -- run start-develop&quot;,\n    &quot;start-develop&quot;: &quot;NODE_ENV=develop node --icu-data-dir=node_modules\/full-icu server.js&quot;\n}<\/code><\/pre>\n<p>\u542f\u52a8\u793a\u4f8b\uff1a<\/p>\n<pre><code class=\"language-bash\">npm run pm2-test<\/code><\/pre>\n<ul>\n<li><code>server.js<\/code><\/li>\n<\/ul>\n<pre><code class=\"language-javascript\">\/\/ Polyfill Node with `Intl` that has data for all locales.\n\/\/ See: https:\/\/formatjs.io\/guides\/runtime-environments\/#server\nconst IntlPolyfill = require(&#039;intl&#039;);\nIntl.NumberFormat = IntlPolyfill.NumberFormat;\nIntl.DateTimeFormat = IntlPolyfill.DateTimeFormat;\n\nconst { readFileSync } = require(&#039;fs&#039;);\nconst { basename } = require(&#039;path&#039;);\nconst { createServer } = require(&#039;http&#039;);\nconst accepts = require(&#039;accepts&#039;);\nconst glob = require(&#039;glob&#039;);\nconst next = require(&#039;next&#039;);\nconst express = require(&#039;express&#039;);\n\nconst port = parseInt(process.env.PORT, 10) || 2027;\nconst env = process.env.NODE_ENV || &#039;dev&#039;;\nconst dev =\n  process.env.NODE_ENV !== &#039;production&#039; &amp;&amp;\n  process.env.NODE_ENV !== &#039;test&#039; &amp;&amp;\n  process.env.NODE_ENV !== &#039;sandbox&#039;;\nconst app = next({ dev });\nconst handle = app.getRequestHandler();\nconst ecosystemEnv = require(&#039;.\/config\/ecosystem.config&#039;);\n\n\/\/ Get the supported languages by looking for translations in the `lang\/` dir.\nconst supportedLanguages = glob.sync(&#039;.\/locales\/lang\/*.json&#039;).map(f =&gt; basename(f, &#039;.json&#039;));\n\n\/\/ We need to expose React Intl&#039;s locale data on the request for the user&#039;s\n\/\/ locale. This function will also cache the scripts by lang in memory.\nconst localeDataCache = new Map();\nconst getLocaleDataScript = locale =&gt; {\n  const lang = locale.split(&#039;-&#039;)[0];\n  if (!localeDataCache.has(lang)) {\n    const localeDataFile = require.resolve(\n      `@formatjs\/intl-relativetimeformat\/dist\/locale-data\/${lang}`\n    );\n    const localeDataScript = readFileSync(localeDataFile, &#039;utf8&#039;);\n    localeDataCache.set(lang, localeDataScript);\n  }\n  return localeDataCache.get(lang);\n};\n\n\/\/ We need to load and expose the translations on the request for the user&#039;s\n\/\/ locale. These will only be used in production, in dev the `defaultMessage` in\n\/\/ each message description in the source code will be used.\nconst getMessages = locale =&gt; {\n  return require(`.\/locales\/lang\/${locale}.json`);\n};\n\/\/\n\/\/ app.prepare().then(() =&gt; {\n\/\/   createServer((req, res) =&gt; {\n\/\/     const accept = accepts(req);\n\/\/     const locale = accept.language(supportedLanguages) || &#039;en-US&#039;;\n\/\/     \/\/ const locale = req.url.substring(req.url.indexOf(&#039;lang=&#039;)).slice(5);\n\/\/     \/\/ const lang = locale.split(&#039;-&#039;)[0];\n\/\/     req.locale = locale;\n\/\/     req.localeDataScript = getLocaleDataScript(locale);\n\/\/     req.messages = dev ? {} : getMessages(locale);\n\/\/     handle(req, res);\n\/\/   }).listen(port, err =&gt; {\n\/\/     if (err) throw err;\n\/\/     console.log(`&gt; Ready on http:\/\/localhost:${port}`);\n\/\/   });\n\/\/ });\nlet HOST = ecosystemEnv[process.env.NODE_ENV];\nif (dev) {\n  HOST = ecosystemEnv.develop;\n} else {\n  HOST = ecosystemEnv[process.env.NODE_ENV];\n}\nconst devProxy = {\n  &#039;\/api&#039;: {\n    target: HOST,\n    pathRewrite: { &#039;^\/api&#039;: &#039;&#039; },\n    secure: false,\n    changeOrigin: true,\n  },\n};\n\nlet server;\napp\n  .prepare()\n  .then(() =&gt; {\n    server = express();\n\n    \/\/ Set up the proxy.\n    if (devProxy) {\n      const proxyMiddleware = require(&#039;http-proxy-middleware&#039;);\n      Object.keys(devProxy).forEach(function(context) {\n        server.use(proxyMiddleware(context, devProxy[context]));\n      });\n    }\n\n    \/\/ Default catch-all handler to allow Next.js to handle all other routes\n    server.all(&#039;*&#039;, (req, res) =&gt; {\n      const accept = accepts(req);\n      \/\/ console.log(&#039;accept&#039;, accept);\n      const locale = accept.language(supportedLanguages) || &#039;en-US&#039;;\n      \/\/ console.log(&#039;supportedLanguages&#039;, supportedLanguages);\n      \/\/ console.log(&#039;locale&#039;, locale);\n      \/\/ const locale = req.url.substring(req.url.indexOf(&#039;lang=&#039;)).slice(5);\n      \/\/ const lang = locale.split(&#039;-&#039;)[0];\n      req.locale = locale;\n      req.localeDataScript = getLocaleDataScript(locale);\n      req.messages = dev ? {} : getMessages(locale);\n      handle(req, res);\n    });\n\n    server.listen(port, err =&gt; {\n      if (err) {\n        throw err;\n      }\n      console.log(`&gt; Ready on port ${port} [${env}]`);\n    });\n  })\n  .catch(err =&gt; {\n    console.log(&#039;An error occurred, unable to start the server&#039;);\n    console.log(err);\n  });<\/code><\/pre>\n<ul>\n<li><code>config\/ecosystem.config.js<\/code><\/li>\n<\/ul>\n<pre><code class=\"language-javascript\">module.exports = {\n  develop: &#039;https:\/\/api-develop.appblog.cn&#039;,\n  test: &#039;https:\/\/api-test.appblog.cn&#039;,\n  sandbox: &#039;https:\/\/api-sandbox.appblog.cn&#039;,\n  production: &#039;https:\/\/api.appblog.cn&#039;,\n};<\/code><\/pre>\n<h2>\u9759\u6001\u90e8\u7f72<\/h2>\n<h3>\u4e3a\u4ec0\u4e48\u8981\u4f7f\u7528pm2\u8fd0\u884cvue\u9879\u76ee<\/h3>\n<p>\u53ef\u80fd\u5f88\u591a\u4eba\u90fd\u4f1a\u7591\u60d1\uff0c\u4f7f\u7528vue\u505a\u597d\u7684\u9879\u76ee\u76f4\u63a5\u6253\u5305\u653e\u5728\u670d\u52a1\u5668\u4e0a\u4e0d\u5c31\u53ef\u4ee5\u4e86\u5417\uff1f\u4f17\u6240\u5468\u77e5vue\u6253\u5305\u540e\u4f1a\u751f\u6210\u4e00\u4e2a\u540d\u4e3adist\u7684\u9759\u6001\u8d44\u6e90\u6587\u4ef6\u5939\uff0c\u90a3\u4e48\u5982\u679c\u60f3\u8981\u5728\u4e91\u670d\u52a1\u5668\u8bbf\u95ee\u8fd9\u4e9b\u8d44\u6e90\u53ea\u80fd\u901a\u8fc7 <a target=\"_blank\" rel=\"noopener\" href=\"http:\/\/xxxx.com\/dist\/index.html\">http:\/\/xxxx.com\/dist\/index.html<\/a> \u6765\u8bbf\u95ee\u3002\u5982\u679c\u60f3\u8981\u548cvue\u811a\u624b\u67b6\u642d\u5efa\u7684\u672c\u5730\u9879\u76ee\u4e00\u6837 \u4f7f\u7528\u7aef\u53e3\u53f7\u6765\u76d1\u542c\/\u8fd0\u884c\u9879\u76ee\uff08\u5982\uff1a<a target=\"_blank\" rel=\"noopener\" href=\"http:\/\/xxxx.com:8080\">http:\/\/xxxx.com:8080<\/a> \uff09\uff0c\u6211\u4eec\u5c31\u9700\u8981\u81ea\u5df1\u642d\u5efa\u4e00\u4e2a\u670d\u52a1\uff0c\u7136\u540e\u901a\u8fc7pm2\u8fdb\u884c\u542f\u52a8\u3002<\/p>\n<h3>\u6253\u5305\u9879\u76ee<\/h3>\n<pre><code class=\"language-bash\">npm run build  \/\/vue\u811a\u624b\u67b6\u9ed8\u8ba4\u6253\u5305\u547d\u4ee4\uff0c\u6253\u5305\u540e\u4f1a\u5728\u5f53\u524d\u9879\u76ee\u6587\u4ef6\u5939\u521b\u5efa\u4e00\u4e2a\u540d\u4e3adist\u7684\u6587\u4ef6\u5939<\/code><\/pre>\n<h3>\u642d\u5efa\u670d\u52a1<\/h3>\n<p>\u9996\u5148\u5728\u5f53\u524d\u9879\u76ee\u6587\u4ef6\u5939\u91cc\u521b\u5efa\u4e00\u4e2abin\u76ee\u5f55\uff0cbin\u76ee\u5f55\u4e0b\u521b\u5efa\u4e00\u4e2ajs\u542f\u52a8\u6587\u4ef6\uff0c\u540d\u5b57\u968f\u610f\uff08\u4e0d\u53ef\u548c\u522b\u7684\u9879\u76ee\u542f\u52a8\u6587\u4ef6\u51b2\u7a81\uff09\uff0c\u8fd9\u91cc\u547d\u540d\u7684\u662f<code>demo.js<\/code><\/p>\n<pre><code class=\"language-javascript\">const express = require(&#039;express&#039;);  \/\/npm\u4e0b\u8f7d\u5e76\u5f15\u5165express\u6a21\u5757 npm -express -D\n\nconst app = express();\napp.use(express.static(&#039;.\/dist&#039;))  \/\/ .\/dist \u4e3avue\u6253\u5305\u540edist\u6587\u4ef6\u5939\u7684\u8def\u5f84\napp.listen(8080,function(err) {  \/\/8080 \u60f3\u8981\u76d1\u542c\u9879\u76ee\u7684\u7aef\u53e3\u53f7\n    if (err) {\n        console.log(err)\n    } else {\n        console.log(&#039;\u9879\u76ee\u542f\u52a8\u6210\u529f&#039;)\n    }\n})<\/code><\/pre>\n<h3>pm2\u542f\u52a8\u9879\u76ee<\/h3>\n<p>\u9996\u5148\u89e3\u91ca\u4e00\u4e0b\u4e3a\u4ec0\u4e48\u8981\u4f7f\u7528pm2\u542f\u52a8\u9879\u76ee\uff0cvue\u81ea\u5e26\u7684\u542f\u52a8\u670d\u52a1\u547d\u4ee4\u53ea\u80fd\u5728\u7ec8\u7aef\u5f00\u542f\u7684\u60c5\u51b5\u4e0b\u8fd0\u884c\uff0c\u5982\u679c\u5173\u95ed\u7ec8\u7aef\uff0c\u5219\u8be5\u9879\u76ee\u7684\u670d\u52a1\u4e5f\u4f1a\u8ddf\u7740\u4e00\u8d77\u5173\u95ed\uff0c\u800c\u4f7f\u7528pm2\u547d\u4ee4\u542f\u52a8\u7684\u670d\u52a1\u662f\u4e00\u76f4\u8fd0\u884c\u7684\uff0c\u5c31\u7b97\u5173\u95ed\u7ec8\u7aef \u9879\u76ee\u670d\u52a1\u4e5f\u4e0d\u4f1a\u505c\u6b62\u3002<\/p>\n<p>\uff081\uff09\u542f\u52a8\u670d\u52a1<\/p>\n<pre><code class=\"language-bash\">pm2 start demo.js  \/\/\u542f\u52a8\u540d\u4e3ademo.js \u7684\u542f\u52a8\u6587\u4ef6<\/code><\/pre>\n<p>\uff082\uff09\u5173\u95ed\u670d\u52a1<\/p>\n<pre><code class=\"language-bash\">pm2 stop demo.js<\/code><\/pre>\n<p>\uff083\uff09\u91cd\u542f\u670d\u52a1<\/p>\n<pre><code class=\"language-bash\">pm2 restart demo.js<\/code><\/pre>\n<p>\uff084\uff09\u5220\u9664\u670d\u52a1<\/p>\n<pre><code class=\"language-bash\">pm2 delete demo.js<\/code><\/pre>\n<p>\uff085\uff09\u67e5\u770b\u670d\u52a1\u5217\u8868<\/p>\n<pre><code class=\"language-bash\">pm2 list<\/code><\/pre>\n<p>\u542f\u52a8\u540e\u5728\u6d4f\u89c8\u5668\u8f93\u5165 <a target=\"_blank\" rel=\"noopener\" href=\"http:\/\/xxxx.com:8080\">http:\/\/xxxx.com:8080<\/a> \u5373\u53ef\u8bbf\u95ee\u9879\u76ee<\/p>\n","protected":false},"excerpt":{"rendered":"<p>pm2\u7b80\u4ecb pm2 \u662f\u4e00\u4e2a\u5e26\u6709\u8d1f\u8f7d\u5747\u8861\u529f\u80fd\u7684Node\u5e94\u7528\u7684\u8fdb\u7a0b\u7ba1\u7406\u5668\u3002 npm i -g pm2 \u52a8\u6001\u90e8\u7f72 \uff08 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[35],"tags":[294],"class_list":["post-1879","post","type-post","status-publish","format-standard","hentry","category-vue","tag-pm2"],"_links":{"self":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/1879","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/comments?post=1879"}],"version-history":[{"count":0,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/1879\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/media?parent=1879"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/categories?post=1879"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/tags?post=1879"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}