在Heroku上托管带有打字稿和React应用的Express时的问题

时间:2018-07-03 04:59:01

标签: node.js reactjs express heroku webpack

托管我的应用程序时,出现以下错误

2018-07-03T23:32:25.175363+00:00 heroku[web.1]: Starting process with command `npm start`
2018-07-03T23:32:28.093779+00:00 heroku[web.1]: State changed from starting to crashed
2018-07-03T23:32:27.719911+00:00 app[web.1]: 
2018-07-03T23:32:27.719929+00:00 app[web.1]: > doombot@1.0.0 start /app
2018-07-03T23:32:27.719931+00:00 app[web.1]: > node src/server/dist/server.js
2018-07-03T23:32:27.719932+00:00 app[web.1]: 
2018-07-03T23:32:27.942441+00:00 app[web.1]: module.js:545
2018-07-03T23:32:27.942444+00:00 app[web.1]:     throw err;
2018-07-03T23:32:27.942446+00:00 app[web.1]:     ^
2018-07-03T23:32:27.942447+00:00 app[web.1]: 
2018-07-03T23:32:27.942449+00:00 app[web.1]: Error: Cannot find module '/app/src/server/dist/server.js'
2018-07-03T23:32:27.942451+00:00 app[web.1]:     at Function.Module._resolveFilename (module.js:543:15)
2018-07-03T23:32:27.942453+00:00 app[web.1]:     at Function.Module._load (module.js:470:25)
2018-07-03T23:32:27.942454+00:00 app[web.1]:     at Function.Module.runMain (module.js:690:10)
2018-07-03T23:32:27.942456+00:00 app[web.1]:     at startup (bootstrap_node.js:194:16)
2018-07-03T23:32:27.942457+00:00 app[web.1]:     at bootstrap_node.js:666:3
2018-07-03T23:32:27.960851+00:00 app[web.1]: npm ERR! code ELIFECYCLE
2018-07-03T23:32:27.961370+00:00 app[web.1]: npm ERR! errno 1
2018-07-03T23:32:27.965212+00:00 app[web.1]: npm ERR! doombot@1.0.0 start: `node src/server/dist/server.js`
2018-07-03T23:32:27.966189+00:00 app[web.1]: npm ERR! Exit status 1
2018-07-03T23:32:27.967067+00:00 app[web.1]: npm ERR! 
2018-07-03T23:32:27.967873+00:00 app[web.1]: npm ERR! Failed at the doombot@1.0.0 start script.
2018-07-03T23:32:27.968281+00:00 app[web.1]: npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
2018-07-03T23:32:28.070076+00:00 heroku[web.1]: Process exited with status 1
2018-07-03T23:32:28.010680+00:00 app[web.1]: 
2018-07-03T23:32:28.010886+00:00 app[web.1]: npm ERR! A complete log of this run can be found in:
2018-07-03T23:32:28.011019+00:00 app[web.1]: npm ERR!     /app/.npm/_logs/2018-07-03T23_32_27_989Z-debug.log

这是我的 package.json 文件

{
  "name": "doombot",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "tsc": "tsc",
    "start": "node src/server/dist/server.js",
    "heroku-postbuild": "webpack --config webpack.prod.js; tsc -p ./tsconfig.json",
    "server": "nodemon src/server/lib/server.ts",
    "client": "webpack-dev-server --open --config webpack.dev.js",
    "dev": "concurrently \"npm run server\" \"npm run client\""
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "engines": {
    "npm": "6.0.0",
    "node": "9.9.0"
  },
  "dependencies": {
    "@types/express": "^4.11.1",
    "antd": "^3.6.4",
    "app-root-path": "^2.1.0",
    "axios": "^0.18.0",
    "body-parser": "^1.18.3",
    "cors": "^2.8.4",
    "express": "^4.16.3",
    "prop-types": "^15.6.2",
    "react": "^16.4.1",
    "react-dom": "^16.4.1",
    "typescript": "2.9.1"
  },
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.4",
    "babel-plugin-import": "^1.8.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "clean-webpack-plugin": "^0.1.19",
    "concurrently": "^3.5.1",
    "css-loader": "^0.28.11",
    "eslint": "^4.19.1",
    "eslint-config-airbnb": "^16.1.0",
    "eslint-plugin-import": "^2.11.0",
    "eslint-plugin-jsx-a11y": "^6.0.3",
    "eslint-plugin-react": "^7.7.0",
    "html-webpack-plugin": "^3.2.0",
    "nodemon": "^1.17.3",
    "style-loader": "^0.20.3",
    "uglifyjs-webpack-plugin": "^1.2.7",
    "webpack": "^4.5.0",
    "webpack-cli": "^2.0.14",
    "webpack-dev-server": "^3.1.3",
    "webpack-merge": "^4.1.3"
  }
}

webpack.common.js

const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/client/index.js',
  plugins: [new CleanWebpackPlugin(['build']), new HtmlWebpackPlugin()],
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'build')
  }
};

webpack.dev.js

const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const path = require('path');

module.exports = merge(common, {
  mode: 'development',
  devtool: 'inline-source-map',
  devServer: {
    contentBase: './build',
    port: 3000,
    open: true,
    proxy: {
      '/api': 'http://localhost:4040'
    }
  }
});

webpack.prod.js

const webpack = require('webpack');
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const path = require('path');

module.exports = merge(common, {
  mode: 'production',
  devtool: 'source-map',
  plugins: [
    new UglifyJSPlugin({
      sourceMap: true
    }),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('production')
    })
  ]
});

和我的 tsconfig 文件

{
  "compilerOptions": {
    "module": "commonjs",
    "moduleResolution": "node",
    "pretty": true,
    "sourceMap": true,
    "target": "es6",
    "outDir": "./src/server/dist", // creates the dist directory & places compiles files here
    "baseUrl": "./src/server/lib"
  },
  "include": [
    "./src/server/lib/**/*.ts" // specifies that we should include all ts files within lib
  ],
  "exclude": ["node_modules"]
}

如果我理解正确,则由于未正确构建而未出现。我的问题是如何正确构建和运行我的应用程序?

如果您想查看我的完整代码,可以在这里找到它-https://github.com/albertogodinez/dooms-data

1 个答案:

答案 0 :(得分:5)

您缺少很多步骤。让我们回溯一下。

  • 您要告诉Heroku要启动您的应用,它应该运行node src/server/dist/server.js(因为您将其指定为start中的package.json脚本)。但是,server.js在Heroku上不存在,只有server.ts(即TypeScript文件)。
  • 因此,您必须告诉Heroku将TypeScript文件转换为Javascript-现在,您只是告诉它构建客户端(即通过webpack脚本中的heroku-postbuild) 。要解决此问题,您可以将该脚本更改为"webpack --mode production; tsc --project=tsconfig.json",
  • 但是,由于Heroku上未安装TypeScript编译器,因此也不起作用。因此,请确保将typescript添加到您的依赖项中(请注意,IIRC,Heroku不会安装devDependencies,因此请使其成为常规依赖项或tell Heroku to install devDependencies as well
  • 即使服务器随后正确运行,它也只能提供API。如果您还希望与客户保持联系,则必须告诉Express为其提供服务。您可以这样做:

app.use(
  express.static(
    path.join(__dirname, '../../compiled_frontend'),
    { index: false },
  ),
);

我认为这应该可以解决问题,但显然更多可能是错误的。巧合的是,我正在开发具有类似设置的应用程序,并且该应用程序是开源的-因此,give it a look随时可以获取灵感。