プロダクションモードでReactを実行する必要があります。これはおそらく環境内のどこかで以下を定義する必要があります。
process.env.NODE_ENV = 'production';
問題は、これをNode.jsではなくTornado(a python web-server)の背後で実行していることです。また、Tornadoインスタンスを管理するためにSupervisordを使用しているため、実行環境でこれを設定します。
ただし、jspファイルをjavascriptにビルドするためにGulpを使用しています。
Gulp内でこれを何らかの方法で設定することは可能ですか?もしそうなら、どうすればReactが本番モードで実行されているかを確認できますか?
ここに私のGulpfile.jsがあります:
'use strict';
var gulp = require('gulp'),
babelify = require('babelify'),
browserify = require('browserify'),
browserSync = require('browser-sync'),
source = require('vinyl-source-stream'),
uglify = require('gulp-uglify'),
buffer = require('vinyl-buffer');
var vendors = [
'react',
'react-bootstrap',
'jquery',
];
gulp.task('vendors', function () {
var stream = browserify({
debug: false,
require: vendors
});
stream.bundle()
.pipe(source('vendors.min.js'))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest('build/js'));
return stream;
});
gulp.task('app', function () {
var stream = browserify({
entries: ['./app/app.jsx'],
transform: [babelify],
debug: false,
extensions: ['.jsx'],
fullPaths: false
});
vendors.forEach(function(vendor) {
stream.external(vendor);
});
return stream.bundle()
.pipe(source('build.min.js'))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest('build/js'));
});
gulp.task('watch', [], function () {
// gulp.watch(['./app/**/*.jsx'], ['app', browserSync.reload]);
gulp.watch(['./app/**/*.jsx'], ['app']);
});
gulp.task('browsersync',['vendors','app'], function () {
browserSync({
server: {
baseDir: './',
},
notify: false,
browser: ["google chrome"]
});
});
gulp.task('default',['browsersync','watch'], function() {});
ステップI:gulpfile.jsのどこかに以下を追加します
gulp.task('apply-prod-environment', function() {
process.env.NODE_ENV = 'production';
});
ステップII:デフォルトタスク(または、サービスの提供/ビルドに使用するタスク)に追加しますアプリ)
// before:
// gulp.task('default',['browsersync','watch'], function() {});
// after:
gulp.task('default',['apply-prod-environment', 'browsersync','watch'], function() {});
OPTIONAL:prodモードであることを絶対に確認したい場合は、ステップIのタスクの代わりに、わずかに強化されたタスクを実行します。
gulp.task('apply-prod-environment', function() {
process.stdout.write("Setting NODE_ENV to 'production'" + "\n");
process.env.NODE_ENV = 'production';
if (process.env.NODE_ENV != 'production') {
throw new Error("Failed to set NODE_ENV to production!!!!");
} else {
process.stdout.write("Successfully set NODE_ENV to production" + "\n");
}
});
NODE_ENVが「本番」に設定されていない場合、次のエラーがスローされます
[13:55:24] Starting 'apply-prod-environment'...
[13:55:24] 'apply-prod-environment' errored after 77 μs
[13:55:24] Error: Failed to set NODE_ENV to production!!!!
他の答えと似ていますが、うまくいけば誰かに出発点を与えます:
var vendorList = ['react', 'react-dom'];
gulp.task('vendor-dev', function() {
browserify()
.require(vendorList)
.bundle()
.on('error', handleErrors)
.pipe(source('vendor.js'))
.pipe(gulp.dest('./build/dev/js'));
});
gulp.task('vendor-production', function() {
process.env.NODE_ENV = 'production';
browserify()
.require(vendorList)
.bundle()
.on('error', handleErrors)
.pipe(source('vendor.js'))
.pipe(buffer())
.pipe(uglify({ mangle: false }))
.pipe(gulp.dest('./build/production/js'));
});
主な違いは、ベンダーライブラリをバンドルする前にNODE_ENVを明示的に設定していることです。 Gulpタスクは順番に実行されるとは限りません。
運用モードで実行していますか?
Uglifyの行(および以前のバッファー)を削除すると、devビルドと製品ビルドのサイズがほぼ同じであり、行数が一致することに気付くでしょう。
違いは、製品版には次のものが散らばっていることです。
"production" !== "production" ? [show dev error] : [no nothing]
ほとんどの評判の良いminify'ers(私は信じている)は、上記のような行き止まりのコードを取り除き、常に偽になります。
しかし、実際にどのように伝えるのですか?
もっとも簡単な方法は、実行中のアプリケーションのコンソールに移動して、次のように入力することです。
React.createClass.toString();
出力は次のようになります。
"function (e){var t=function(e,t,n){this.__reactAutoBindMap&&c(this),"[....and more and more]
反応ソースでcreateClassを見つけると、以下が表示されます。
createClass: function (spec) {
var Constructor = function (props, context, updater) {
// This constructor is overridden by mocks. The argument is used
// by mocks to assert on what gets mounted.
if ("production" !== 'production') {
"production" !== 'production' ? warning(this instanceof Constructor, 'Something is calling a React component directly. Use a factory or ' + 'JSX instead. See: react-legacyfactory') : undefined;
}
// Wire up auto-binding
if (this.__reactAutoBindMap) {
bindAutoBindMethods(this);
}
プロダクションモードで実行しており、minify'erを使用しているため、コンソール出力がthis.__reactAutobind
に直接スキップすることに注意してください。
プロダクションモードでReact=.
NODE_ENV変数を設定するために、すでに面白みの面倒を見ています:
_NODE_ENV='production' gulp
_
gulp.task('set-production-env', function() { return process.env.NODE_ENV = 'production'; });
残念ながら、_process.env.NODE_ENV
_の設定はBrowserifyでは効果がないため、上記の回答はいずれも機能しません。結果のバンドルにはまだ_process.env.NODE_ENV
_参照が含まれているため、
require()
React製品バージョンモジュール、残念ながら、このアプローチが正しい答えとして提供される唯一の場所ではありません:
正しいアプローチは、例えば.
Envifyトランスフォームをグローバルなものに切り替える必要があります。
_# note the "-g" instead of the usual "-t"
$ browserify ... -g [ envify --NODE_ENV production ] ....
_
または_gulpfile.js
_で
_browserify(...)
...
.transform('envify', {
global: true, // also apply to node_modules
NODE_ENV: debug ? 'development' : 'production',
})
...
.bundle()
...
.pipe(gulpif(!debug, babelMinify())) // my example uses gulp-babel-minify
...
_
また、gulp-environments
を使用すると便利です。
var environments = require('gulp-environments');
var production = environments.production;
gulp.src(paths.js)
.pipe(concat("app.js"))
// only minify the compiled JS in production mode
.pipe(production(uglify()))
.pipe(gulp.dest("./public/app/js/"));
運用モードでgulpを実行するには:
gulp build --env=production