繁体   English   中英

部署时Heroku上“找不到模块”错误

[英]“Cannot find module” error on Heroku when deploying

所以,我正在使用React创建一个应用程序,然后我将它部署到Heroku。 一切都在localhost中运行良好,没有任何错误,webpack也编译没有错误。 我也在Heroku上设置了env变量。

但是,当我将它部署到Heroku时,我得到一个空白的屏幕,并在控制台中出现此错误(我正确地要求TodoApi并尝试了各种方式 - 导入等,它在localhost中工作没有问题):

我试图找出它好几天,所以任何帮助都非常感谢。

Uncaught Error: Cannot find module "TodoApi"
    at bundle.js:20
    at Object.<anonymous> (bundle.js:20)
    at t (bundle.js:1)
    at Object.<anonymous> (bundle.js:20)
    at t (bundle.js:1)
    at Object.<anonymous> (bundle.js:3)
    at Object.<anonymous> (bundle.js:3)
    at t (bundle.js:1)
    at Object.<anonymous> (bundle.js:1)
    at t (bundle.js:1)

这是我的webpack和package.json文件:

var webpack = require('webpack');
var path = require('path');
var envFile = require('node-env-file');

process.env.NODE_ENV = process.env.NODE_ENV || 'development';

try {
    envFile(path.join(__dirname, 'config/' + process.env.NODE_ENV + '.env'));
} catch(e) {

}

module.exports = {
  entry: [
    'script!jquery/dist/jquery.min.js',
    'script!foundation-sites/dist/js/foundation.min.js',
    './app/app.jsx'
  ],
  externals: {
      jquery: 'jQuery'
  },
  plugins: [
      new webpack.ProvidePlugin({
          '$': 'jquery',
          'jQuery': 'jquery'
      }),
      new webpack.optimize.UglifyJsPlugin({
          compressor: {
              warnings: false
          }
      }),
      new webpack.DefinePlugin({
        'process.env': {
          NODE_ENV: JSON.stringify(process.env.NODE_ENV),
          API_KEY: JSON.stringify(process.env.API_KEY),
          AUTH_DOMAIN: JSON.stringify(process.env.AUTH_DOMAIN),
          DATABASE_URL: JSON.stringify(process.env.DATABASE_URL),
          STORAGE_BUCKET: JSON.stringify(process.env.STORAGE_BUCKET),
          MESSAGING_SENDER_ID: JSON.stringify(process.env.MESSAGING_SENDER_ID)
        }
      })
  ],
  output: {
    path: __dirname,
    filename: './public/bundle.js'
  },
  resolve: {
    root: __dirname,
    modulesDirectories: [
        'node_modules',
        './app/components',
        './app/api'
    ],
    alias: {
        app: 'app',
        applicationStyles: 'app/styles/app.scss',
        actions: 'app/actions/actions.jsx',
        reducers: 'app/reducers/reducers.jsx',
        configureStore: 'app/store/configureStore.jsx'
    },
    extensions: ['', '.js', '.jsx']
  },
  module: {
    loaders: [
      {
        loader: 'babel-loader',
        query: {
          presets: ['react', 'es2015', 'stage-0']
        },
        test: /\.jsx?$/,
        exclude: /(node_modules|bower_components)/
      }
    ]
  },
  devtool: process.env.NODE_ENV === 'production' ? undefined : 'cheap-module-eval-source-map'
};


{
  "name": "reactapp",
  "version": "1.0.0",
  "description": "ReactApp",
  "main": "index.js",
  "scripts": {
    "test": "NODE_ENV=test karma start",
    "build": "webpack",
    "start": "npm run build && node server.js"
  },
  "author": "John Smith",
  "license": "MIT",
  "dependencies": {
    "axios": "^0.16.0",
    "babel-core": "^6.5.1",
    "babel-loader": "^6.2.2",
    "babel-preset-es2015": "^6.5.0",
    "babel-preset-react": "^6.5.0",
    "babel-preset-stage-0": "^6.5.0",
    "css-loader": "^0.23.1",
    "deep-freeze-strict": "^1.1.1",
    "expect": "^1.20.2",
    "express": "^4.13.4",
    "firebase": "^3.9.0",
    "foundation-sites": "^6.3.1",
    "jquery": "^2.2.1",
    "moment": "^2.18.1",
    "node-env-file": "^0.1.8",
    "node-sass": "^4.5.2",
    "react": "^0.14.7",
    "react-addons-test-utils": "^0.14.6",
    "react-dom": "^0.14.7",
    "react-redux": "^5.0.4",
    "react-router": "^2.0.0",
    "redux": "^3.6.0",
    "redux-mock-store": "^1.2.3",
    "redux-thunk": "^2.2.0",
    "sass-loader": "^6.0.3",
    "script-loader": "^0.6.1",
    "style-loader": "^0.13.0",
    "uuid": "^3.0.1",
    "webpack": "^1.12.13"
  },
  "devDependencies": {
    "karma": "^0.13.22",
    "karma-chrome-launcher": "^0.2.3",
    "karma-mocha": "^0.2.2",
    "karma-mocha-reporter": "^2.2.3",
    "karma-sourcemap-loader": "^0.3.7",
    "karma-webpack": "^1.8.1",
    "mocha": "^2.5.3"
  }
}

var React = require('react');
var { connect } = require('react-redux');
import Todo from 'Todo';
var TodoApi = require('TodoApi');

export var TodoList = React.createClass ({
    render: function() {
        var { todos, showCompleted, searchText } = this.props;
        var renderTodos = () => {
            var filteredTodos = TodoApi.filterTodos(todos, showCompleted, searchText);

            if(filteredTodos.length === 0) {
                return (
                    <p className="container__message">No tasks</p>
                );
            }
            return filteredTodos.map((todo) => {
                return (
                    //add unique key prop to keep track of individual components
                    <Todo key={todo.id} {...todo} />
                );
            });
        };
        return (
            <div>
                {renderTodos()}
            </div>
        );  
    }
});

export default connect(
    (state) => {
        return state;
    }
)(TodoList);

您需要TodoApipackage.json中不存在此包

在您的TodoList.jsx组件中

var TodoApi = require("TodoApi");

快速查看仓库显示该包在任何地方都不存在。

我认为您的问题在于resolve部分webpack配置文件。 似乎resolve.modulesDirectories在部署到Heroku时无法正常工作。 我觉得它更有意义的配置与解决您的“./app/components'和” ./app/api” resolve.root而不是resolve.modulesDirectories 因此,尝试以下resolve配置,可能它将与Heroku一起使用。

resolve: {
    root: [
        __dirname,
        path.resolve(__dirname, "app/components"),
        path.resolve(__dirname, "app/api")
    ],
    modulesDirectories: [ 'node_modules' ],
    alias: {
        app: 'app',
        applicationStyles: 'app/styles/app.scss',
        actions: 'app/actions/actions.jsx',
        reducers: 'app/reducers/reducers.jsx',
        configureStore: 'app/store/configureStore.jsx'
    },
    extensions: ['', '.js', '.jsx']
}

问题正是它所说的。 TodoApi。

在本地它会工作,因为TodoApi可能在你的“node_modules”目录中。 (你没有在index.html中本地包含它吗?)问题是它没有打包到部署包中。 这就是为什么它不起作用。

首先,不知道你是否注意到了,但你(wan't到)包括根据modulesDirectories后来下再次排除module.loaders node_modules。 幸运的是,它没有包含,否则你仍然会建设,哈哈。 除此之外,你可以删除 modulesDirectories段落。 并且永远不要认为将node_modules作为目录包含在任何内容中是个好主意。 ;)

我会采取以下措施来带来一些结构,这样你就可以清楚地看到包含的内容和不包含的内容。 在您的顶部webpack定义一些绝对目录:

// Absolute directories
const root    = (...dir) => path.resolve(__dirname, ...dir);
const lib     = root('lib'),
      src     = root('src'), // or 'app'
      project = root('.');

这你知道确定了什么目录分配,它更容易阅读。 然后设置您的输入文件。

const entry   = root('app/app.jsx'); 

并在模块导出下更改它:

root: src,
context: src,
entry: entry,
...

我总是将上下文设置为我的src目录,这意味着到目前为止webpack与src是顶级目录有关。 删除其他内容。

我还会评论出Uglify插件,而你还没有构建工作,只是为了排除可能产生错误的东西。

安装webpack-bundle-analyzer

npm i --save-dev webpack-bundle-analyzer

并将其添加到您的webpack插件中,如下所示:

      new BundleAnalyzerPlugin({
        analyzerMode: 'server',
        analyzerHost: 'localhost',
        analyzerPort: 9002,
        reportFilename: 'report.html',
        openAnalyzer: true,
        // Log level. Can be 'info', 'warn', 'error' or 'silent'.
        logLevel: 'info'
      })

这将在构建后打开包的漂亮图形视图。 其中一个块需要提到“TodoApi”,然后你很好。 如果您首先添加BundleAnalyzerPlugin而不更改代码,那么您可以看到TodoApi可能不在那里。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM