2017-11-05 9 views
0

동형 반응 앱이 있습니다. app/src/디렉토리 내에 server.js 파일이 있습니다.ES6이있는 firebase에서 동일 형상 단일 페이지 앱을 실행할 수 없습니다.

Server.js는

import path from 'path'; 
import express from 'express'; 
import cookieParser from 'cookie-parser'; 
import bodyParser from 'body-parser'; 
import expressJwt, { UnauthorizedError as Jwt401Error } from 'express-jwt'; 
import nodeFetch from 'node-fetch'; 
import React from 'react'; 
import ReactDOM from 'react-dom/server'; 
import PrettyError from 'pretty-error'; 
import App from './components/App'; 
import Html from './components/Html'; 
import { ErrorPageWithoutStyle } from './routes/error/ErrorPage'; 
import errorPageStyle from './routes/error/ErrorPage.css'; 
import createFetch from './createFetch'; 
import router from './router'; 
import assets from './assets.json'; // eslint-disable-line import/no-unresolved 
import configureStore from './store/configureStore'; 
import { setRuntimeVariable } from './actions/runtime'; 
import config from './config'; 

const app = express(); 

// 
// Tell any CSS tooling (such as Material UI) to use all vendor prefixes if the 
// user agent is not known. 
// ----------------------------------------------------------------------------- 
global.navigator = global.navigator || {}; 
global.navigator.userAgent = global.navigator.userAgent || 'all'; 

// 
// Register Node.js middleware 
// ----------------------------------------------------------------------------- 
app.use(express.static(path.resolve(__dirname, 'public'))); 
app.use(cookieParser()); 
app.use(bodyParser.urlencoded({ extended: true })); 
app.use(bodyParser.json()); 

// 
// Authentication 
// ----------------------------------------------------------------------------- 
app.use(
    expressJwt({ 
    secret: config.auth.jwt.secret, 
    credentialsRequired: false, 
    getToken: req => req.cookies.id_token, 
    }), 
); 
// Error handler for express-jwt 
app.use((err, req, res, next) => { 
    // eslint-disable-line no-unused-vars 
    if (err instanceof Jwt401Error) { 
    console.error('[express-jwt-error]', req.cookies.id_token); 
    // `clearCookie`, otherwise user can't use web-app until cookie expires 
    res.clearCookie('id_token'); 
    } 
    next(err); 
}); 

if (__DEV__) { 
    app.enable('trust proxy'); 
} 

// 
// Register server-side rendering middleware 
// ----------------------------------------------------------------------------- 
app.get('*', async (req, res, next) => { 
    try { 
    const css = new Set(); 

    // Universal HTTP client 
    const fetch = createFetch(nodeFetch, { 
     baseUrl: config.api.serverUrl, 
     cookie: req.headers.cookie, 
    }); 

    const initialState = { 
     user: req.user || null, 
    }; 

    const store = configureStore(initialState, { 
     fetch, 
     // I should not use `history` on server.. but how I do redirection? follow universal-router 
    }); 

    store.dispatch(
     setRuntimeVariable({ 
     name: 'initialNow', 
     value: Date.now(), 
     }), 
    ); 

    // Global (context) variables that can be easily accessed from any React component 
    // https://facebook.github.io/react/docs/context.html 
    const context = { 
     // Enables critical path CSS rendering 
     // https://github.com/kriasoft/isomorphic-style-loader 
     insertCss: (...styles) => { 
     // eslint-disable-next-line no-underscore-dangle 
     styles.forEach(style => css.add(style._getCss())); 
     }, 
     fetch, 
     // You can access redux through react-redux connect 
     store, 
     storeSubscription: null, 
    }; 

    const route = await router.resolve({ 
     ...context, 
     pathname: req.path, 
     query: req.query, 
    }); 

    if (route.redirect) { 
     res.redirect(route.status || 302, route.redirect); 
     return; 
    } 

    const data = { ...route }; 
    data.children = ReactDOM.renderToString(
     <App context={context} store={store}> 
     {route.component} 
     </App>, 
    ); 
    data.styles = [{ id: 'css', cssText: [...css].join('') }]; 
    data.scripts = [assets.vendor.js]; 
    if (route.chunks) { 
     data.scripts.push(...route.chunks.map(chunk => assets[chunk].js)); 
    } 
    data.scripts.push(assets.client.js); 
    data.app = { 
     apiUrl: config.api.clientUrl, 
     state: context.store.getState(), 
    }; 

    const html = ReactDOM.renderToStaticMarkup(<Html {...data} />); 
    res.status(route.status || 200); 
    res.send(`<!doctype html>${html}`); 
    } catch (err) { 
    next(err); 
    } 
}); 

// 
// Error handling 
// ----------------------------------------------------------------------------- 
const pe = new PrettyError(); 
pe.skipNodeFiles(); 
pe.skipPackage('express'); 

// eslint-disable-next-line no-unused-vars 
app.use((err, req, res, next) => { 
    console.error(pe.render(err)); 
    const html = ReactDOM.renderToStaticMarkup(
    <Html 
     title="Internal Server Error" 
     description={err.message} 
     styles={[{ id: 'css', cssText: errorPageStyle._getCss() }]} // eslint-disable-line no-underscore-dangle 
    > 
     {ReactDOM.renderToString(<ErrorPageWithoutStyle error={err} />)} 
    </Html>, 
); 
    res.status(err.status || 500); 
    res.send(`<!doctype html>${html}`); 
}); 

// 
// Launch the server 
// ----------------------------------------------------------------------------- 
if (!module.hot) { 
    app.listen(config.port,() => { 
    console.info(`The server is running at http://localhost:${config.port}/`); 
    }); 
} 

// 
// Hot Module Replacement 
// ----------------------------------------------------------------------------- 
if (module.hot) { 
    app.hot = module.hot; 
    module.hot.accept('./router'); 
} 

export default app; 

나는 중포 기지를 사용하여 내 응용 프로그램을 배포 할. 응용 프로그램은 응용 프로그램/기능/즉 SRC 내부에 정의 된 중포 기지 기능과 기능이 동일한 상위 디렉토리가

{ 
    "database": { 
    "rules": "database.rules.json" 
    }, 
    "hosting": { 
    "public": "build", 
    "ignore": [ 
     "firebase.json", 
     "**/.*", 
     "**/node_modules/**" 
    ], 
    "rewrites": [ 
     { 
     "source": "**", 
     "function": "app" 
     } 
    ] 
    } 
} 

-이를 위해 나는 설정 firebase.json과 같이 있습니다. 함수 디렉토리는 node_modules을 적절하게 구성했으며 다른 기능을 테스트 할 때 작동합니다.

문제 - 응용 프로그램/기능을 내하는 index.js 파일과 같이이다 -

import app from '../src/server'; 
import functions from 'firebase-functions'; 

// // Create and Deploy Your First Cloud Functions 
// // https://firebase.google.com/docs/functions/write-firebase-functions 
// 
// exports.helloWorld = functions.https.onRequest((request, response) => { 
// response.send("Hello from Firebase!"); 
// }); 

exports.app = functions.https.onRequest(app); 

중포 기지가 지원 ES6 나던 불평한다. 이 기능을 ES6에서 작동 시키려면 어떻게합니까? function/index.js 파일을 ES5로 간단하게 변경할 수는 없으며 요구 사항이 해결 될 때 희망 사항이 작동 할 것이라는 희망을 갖기 때문에 내부의 모든 것이 ES5 일 것으로 기대할 수 있습니다. 전체 코드베이스가 ES6에있는 경우에는 그렇지 않습니다.

답변

0

이 문제에 대한 해결책을 찾았습니다.

함수 /로 '디렉토리'디렉토리를 만듭니다.

당신의 ./dist 또는 기능에 ./build (빌드 파일이 존재하는 곳) /의 모든 내용은 건설 프로젝트

복사 구축

기능 /하는 index.js 다음과 같이 수정 -

const app = require('./build/bundle.js').default; 
const functions = require('firebase-functions'); 

// // Create and Deploy Your First Cloud Functions 
// // https://firebase.google.com/docs/functions/write-firebase-functions 
// 
// exports.helloWorld = functions.https.onRequest((request, response) => { 
// response.send("Hello from Firebase!"); 
// }); 

exports.app = functions.https.onRequest(app); 

매력처럼 작동