2017-05-04 94 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

相關問題