2017-05-04 214 views
9

因此,我正在制作一个React应用程序,然后将其部署到Heroku。一切工作在本地主机很好,没有任何错误,webpack也编译没有错误。我也在Heroku上设置了env变量。部署时出现的“找不到模块”错误

然而,当我把它部署到Heroku的,我得到了一个空白页面,这错误控制台(我需要正确和TodoApi已经想尽各种办法 - 进口等,它工作在本地主机没有问题):

我想弄明白它的日子,所以任何帮助非常感谢。

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); 
+2

是TodoApi的外包装? –

+1

哪些O.S.是你的本地主机? – Dez

回答

0

您需要TodoApi但这个包并不在你的package.json

在你TodoList.jsx组件存在

var TodoApi = require("TodoApi");

快速浏览回购显示该包不存在于任何地方。

+0

我已经将它包括在内,但问题仍然存在,所以该应用程序在localhost中工作,这只发生在我将其部署到Heroku时。我编辑过帖子并包含了我当前的TodoList组件。所以,TodoApi只是api文件夹中的一个jsx文件 – Smithy

+1

好的,那么问题是你需要指定'TodoApi'的路径。 'var TodoApi = require('../ api/TodoApi')' –

+0

谢谢,但我已经尝试过,所有的变体,进口和各种路径,似乎这不是一个问题。如果路径不好,我想应用程序会立刻在本地主机上断开....我也认为我应该尝试第1阶段和最新的巴贝尔预设,但我总是会得到相同的错误。我最好的猜想是它与Heroku有关,或者它如何读取路径,或许它会以不同于本地机器的方式来对待npm模块......? – Smithy

0

我认为你的问题在于你的webpack配置文件的一部分resolve。看起来resolve.modulesDirectories在部署到Heroku时不会正确地工作。我觉得用resolve.root而不是resolve.modulesDirectories配置解析'./app/components'和'./app/api'会更有意义。因此,请尝试遵循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'] 
} 
+0

尝试过,仍然是相同的... – Smithy

0

问题正是这样说的。 TodoApi。

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

首先,不知道你是否注意到了,但你(wan't到)包括node_modulesmodulesDirectories后来下module.loaders再次排除。幸运的是,它并没有包括在内,否则你仍然在建设,哈哈。除此之外,你可以只需删除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可能不在那里。

+0

p.s.许多用于开发的模块都在你的依赖关系中,应该放在你的devDependencies中。 (例如*加载器,测试,sass等)。你真的应该清理并检查你正在使用什么。一个好的清洁结构和代码风格开始将节省你的时间固定的东西... – stevenvanc

相关问题