Heroku中的Multi Build Pack无法找到包或服务器

时间:2018-02-07 07:02:37

标签: python node.js reactjs heroku flask

问题摘要:

当部署到Heroku烧瓶/反应应用程序时,我无法一次运行两个buildpack并使应用程序正常运行。我通常遇到2个问题中的1个,具体取决于我如何设置项目。

  1. 如果我在package.json postinstall脚本中指示Heroku到cd static && npm --dev install && npm run build:production,我的bundle.js文件将无法找到,据说我的所有组件都无法访问:
  2. 以下是成功构建后终端从Heroku获得的示例错误:

    ERROR in ./src/containers/HomeContainer/index.js
    remote: Module not found: Error: Cannot resolve 'file' or 'directory'      ../../components/IntroSection in /tmp/build_d95bc1f5e53719f4bd91a1a3/static/src/containers/HomeContainer
    remote: resolve file
    
    1. 如果我指示Heroku到cd static && npm --dev install && npm run build:production && npm start我看到应用程序正确构建并尝试侦听服务器端口。然而,最终终端出局并且从未完成它似乎?
    2. 以下是终端向最后一个命令的显示方式:

      remote:        > node bin/server.js
      remote:        
      remote:        Listening on: {"address":"::","family":"IPv6","port":8080}
      remote:        webpack built e95b297d680022fe in 23191ms
      

      终端在这里停了下来。

      在这两种情况下,我都可以访问应用程序的python端没问题。问题是让客户端(react / redux)呈现。当在任一版本中本地运行它时,它的功能完全正常。没有组件错误,服务器启动。顺便说一下,我被告知Heroku需要root中的package.json来帮助它运行设置。结果,我现在有2个package.json文件。一个在root中,一个在static中。 root中的那个只是帮助它下载node / npm并将其推送到另一个package.json文件(我想?)。

      以下是我可以尝试进一步调试问题的一些细节:

      - Procfile:

      web: gunicorn main:app
      

      - Heroku上的Buildpacks:

      heroku buildpacks:set heroku/python
      heroku buildpacks:add heroku/nodejs
      

      - root中的Package.json:

      {
        "name": "something",
        "version": "0.0.1",
        "engines": { "node": "6.11.1", "npm": "3.10.10" },
        "scripts": {
          "postinstall": "cd static && npm --dev install && npm run build:production && npm start"
        }
      }
      

      - Package.json in static:

      {
        "name": "redux-easy-boilerplate",
        "version": "1.3.3",
        "description": "",
        "scripts": {
          "clean": "rimraf dist",
          "build": "webpack --progress --verbose --colors --display-error-details --config webpack/common.config.js",
          "build:production": "npm run clean && npm run build",
          "lint": "eslint src",
          "start": "node bin/server.js",
          "test": "karma start"
        },
        "repository": {
          "type": "git",
          "url": ""
        },
        "keywords": [
          "react",
          "reactjs",
          "boilerplate",
          "redux",
          "hot",
          "reload",
          "hmr",
          "live",
          "edit",
          "webpack"
        ],
        "author": "https://github.com/anorudes, https://github.com/keske",
        "license": "MIT",
        "devDependencies": {
          "autoprefixer": "6.5.3",
          "axios": "^0.15.3",
          "babel-core": "^6.4.5",
          "babel-eslint": "^7.1.1",
          "babel-loader": "^6.2.1",
          "babel-plugin-import": "^1.2.1",
          "babel-plugin-react-transform": "^2.0.0",
          "babel-plugin-transform-decorators-legacy": "^1.3.4",
          "babel-polyfill": "^6.3.14",
          "babel-preset-es2015": "^6.3.13",
          "babel-preset-react": "^6.3.13",
          "babel-preset-react-hmre": "^1.0.1",
          "babel-preset-stage-0": "^6.3.13",
          "bootstrap": "^3.3.5",
          "bootstrap-loader": "^1.2.0-beta.1",
          "bootstrap-sass": "^3.3.6",
          "bootstrap-webpack": "0.0.5",
          "classnames": "^2.2.3",
          "css-loader": "^0.26.4",
          "csswring": "^5.1.0",
          "deep-equal": "^1.0.1",
          "eslint": "^3.4.0",
          "eslint-config-airbnb": "13.0.0",
          "eslint-plugin-import": "^2.2.0",
          "eslint-plugin-jsx-a11y": "^3.0.1",
          "eslint-plugin-react": "^6.1.2",
          "expect": "^1.13.4",
          "exports-loader": "^0.6.2",
          "expose-loader": "^0.7.1",
          "express": "^4.13.4",
          "express-open-in-editor": "^1.1.0",
          "extract-text-webpack-plugin": "^1.0.1",
          "file-loader": "^0.9.0",
          "gapi": "0.0.3",
          "history": "^4.4.1",
          "http-proxy": "^1.12.0",
          "imports-loader": "^0.6.5",
          "jasmine-core": "^2.4.1",
          "jquery": "^3.1.0",
          "jwt-decode": "^2.1.0",
          "karma": "^1.2.0",
          "karma-chrome-launcher": "^2.0.0",
          "karma-mocha": "^1.1.1",
          "karma-webpack": "^1.7.0",
          "less": "^2.7.2",
          "less-loader": "^2.2.3",
          "lodash": "^4.5.1",
          "material-ui": "^0.16.4",
          "mocha": "^3.0.2",
          "morgan": "^1.6.1",
          "node-sass": "^3.4.2",
          "postcss-import": "^9.0.0",
          "postcss-loader": "^1.1.1",
          "q": "^1.4.1",
          "qs": "^6.1.0",
          "rc-datepicker": "^4.0.1",
          "react": "^15.3.1",
          "react-addons-css-transition-group": "^15.3.1",
          "react-bootstrap": "^0.31.0",
          "react-calendar-component": "^1.0.0",
          "react-date-picker": "^5.3.28",
          "react-datepicker": "^0.37.0",
          "react-document-meta": "^2.0.0-rc2",
          "react-dom": "^15.1.0",
          "react-forms": "^2.0.0-beta33",
          "react-hot-loader": "^1.3.0",
          "react-loading-order-with-animation": "^1.0.0",
          "react-onclickoutside": "^5.3.3",
          "react-redux": "^4.3.0",
          "react-router": "3.0.0",
          "react-router-redux": "^4.0.0",
          "react-tap-event-plugin": "^2.0.1",
          "react-transform-hmr": "^1.0.1",
          "redux": "^3.2.1",
          "redux-form": "^6.0.1",
          "redux-logger": "2.7.4",
          "redux-thunk": "^2.1.0",
          "resolve-url-loader": "^1.4.3",
          "rimraf": "^2.5.0",
          "sass-loader": "^4.0.0",
          "style-loader": "^0.13.0",
          "url-loader": "^0.5.7",
          "webpack": "^1.12.11",
          "webpack-dev-middleware": "^1.5.0",
          "webpack-dev-server": "^1.14.1",
          "webpack-hot-middleware": "^2.6.0",
          "webpack-merge": "^1.0.2",
          "yargs": "^6.5.0"
        },
        "dependencies": {
          "ant-design-pro": "^0.3.1",
          "antd": "^3.0.0",
          "lodash": "^4.17.4",
          "prop-types": "^15.6.0",
          "react-bootstrap": "^0.31.0",
          "redux-devtools-extension": "^2.13.2"
        }
      }
      

      这是我当前的设置,因此您可以了解构建的执行方式。

      ROOT
      ├──/application
      │   ├── models.py
      │   ├── app.py
      ├──/static
      │   ├──/bin
      │   ├──/dist
      │   │   ├──bundle.js
      │   ├──/node_modules
      │   ├──/src
      │   │   ├──/actions
      │   │   ├──/components
      │   │   │   ├──/examplecomponenthere
      │   │   │   │   ├──index.js (for example component)
      │   │   ├──/constants
      │   │   ├──/containers
      │   │   ├──/reducers
      │   │   ├──/store
      │   │   ├──/webpack
      │   ├──index.html
      │   ├──package.json (the true one)
      │   ├──server.js
      ├──/tests
      ├──config.py
      ├──index.py
      ├──main.py
      ├──package.json (one to help heroku start)
      ├──procfile
      ├──requirements.txt.
      ├──setup.py
      ├──tests.py
      

      这是我的server.js文件(不确定是否需要):

      const http = require('http');
      const express = require('express');
      const httpProxy = require('http-proxy');
      const path = require('path');
      
      const proxy = httpProxy.createProxyServer({});
      
      const app = express();
      
      app.use(require('morgan')('short'));
      
      (function initWebpack() {
          const webpack = require('webpack');
          const webpackConfig = require('./webpack/common.config');
      
          const compiler = webpack(webpackConfig);
      
          app.use(require('webpack-dev-middleware')(compiler, {
              noInfo: true, publicPath: webpackConfig.output.publicPath,
          }));
      
          app.use(require('webpack-hot-middleware')(compiler, {
              log: console.log, path: '/__webpack_hmr', heartbeat: 10 * 1000,
          }));
      
          app.use(express.static(path.join(__dirname, '/')));
      }());
      
      app.all(/^\/api\/(.*)/, (req, res) => {
          proxy.web(req, res, { target: 'http://0.0.0.0:8081' });
      });
      
      app.get(/.*/, (req, res) => {
          res.sendFile(path.join(__dirname, '/index.html'));
      });
      
      
      const server = http.createServer(app);
      server.listen(process.env.PORT || 8080, () => {
          const address = server.address();
          console.log('Listening on: %j', address);
          console.log(' -> that probably means: http://0.0.0.0:%d', address.port);
      });
      

      结论 最后要注意的是,在本地我通常使用manage.py runserver脚本启动python端。然后我打开另一个终端,cd进入静态并执行npm start

      我在尝试让heroku在这里为这个多buildpack工作时非常沮丧。任何帮助将非常感激!即使它是一个教程,我可以了解更多并开始剖析问题,或者我可能错误地接近此生产设置?

1 个答案:

答案 0 :(得分:1)

你不应该在postinstall脚本中使用npm start。您希望每次web dyno重新启动时都运行node.js服务器,而不是每次安装应用程序时都运行。

此外,对于Heroku,您应该在heroku-postbuild脚本中运行“静态”组件的构建,而不是在安装后脚本中运行。

除此之外,您需要通过将config var NPM_CONFIG_PRODUCTION设置为false,或者将它们从“devDependencies”移动到“dependencies”,使Heroku可以使用任何构建依赖项(例如webpack等)。

有关详细信息,请参阅here