Mam aplikację izomorphic React, która działa zarówno w przeglądarce, jak i na serwerze. Zbudowałem ten sam kod dla obu, uruchamiając dwie oddzielne kompilacje Webpacka poprzez dwa różne punkty wejścia i różne konfiguracje.Zewnętrzne elementy zewnętrzne w węźle i przeglądarce
Problem polega na tym, że plik zewnętrzny, który istnieje w oknie przeglądarki za pomocą zewnętrznego znacznika skryptu (Google Maps w tym przypadku) oczywiście nie będzie istnieć podczas pracy w węźle na serwerze. Kod jest identyczny z wyjątkiem pliku punktu wejścia.
index.html:
// index.html
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=XXX"></script>
uproszczony config:
// Server Webpack config
{
entry: 'server.js',
target: 'node',
externals: {
google: google
}
}
// Client Webpack config
{
entry: 'client.js',
target: 'browser',
externals: {
google: google
}
}
Komponent:
// The view which builds and runs fine in
// the client but doesn't run on the server.
var React = require('react'),
css = require('./style.css'),
google = require('google'); // Nope, not on the server obviously!
var Component = React.createClass({
render: function() {
return (
<div>
// Do maps stuff
</div>
);
}
});
module.exports = Component;
Moje pytanie brzmi jak mam sobie z tym poradzić?
Error: Cannot find module 'google'
Obecnie mam rozwiązanie, którego w ogóle nie lubię.
// Server Webpack config
{
entry: 'server.js',
target: 'node',
externals: {
google: google
},
plugins: [
new webpack.DefinePlugin({ 'ENV.browser': false }),
]
}
// Client Webpack config
{
entry: 'client.js',
target: 'browser',
externals: {
google: google
},
plugins: [
new webpack.DefinePlugin({ 'ENV.browser': true }),
]
}
// The component
var React = require('react'),
css = require('./style.css');
if (ENV.browser) {
var google = require('google');
}
var Component = React.createClass({
render: function() {
return (
<div>
if (ENV.browser) {
// Do maps stuff
}
</div>
);
}
});
module.exports = Component;
Dzięki wygląda to wygodne! A co, kiedy faktycznie zacznę uzyskiwać dostęp do właściwości obiektu zewnętrznego? Czy po prostu sprawdzisz, czy istnieje przed rozpoczęciem pracy z nim? –
To by działało. 'NormalModuleReplacementPlugin' pozwala na przeprogramowanie twojego żądania do dowolnego modułu, więc możesz również stworzyć prostą próbę modułu i użyć go na serwerze. Jeśli odwołujesz się tylko do zmiennej 'google' w metodzie cyklu życia" componentDidMount', nie ma to znaczenia, ponieważ nigdy nie zostanie wyrzucone z użycia 'React.renderToString'. –
Zastanawiałem się nad tym, co to jest, ale jest to świetny argument na temat 'componentDidMount'. To jest pewność, której szukałem. Dziękuję Ci! –