web-dev-qa-db-ja.com

Gulpを使用する場合、React= Productionモードに設定する方法

プロダクションモードで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() {});
31
vgoklani

2017-編集:新しいプロジェクトのGulpでReactを設定しようとしている人:単に create-react-app を使用してください


ステップ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!!!!
28
Monarch Wadia

他の答えと似ていますが、うまくいけば誰かに出発点を与えます:

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に直接スキップすることに注意してください。

7
Chris

プロダクションモードでReact=.

NODE_ENV変数を設定するために、すでに面白みの面倒を見ています:

  • Gulpタスクの実行中に変数を設定します。

_NODE_ENV='production' gulp_

  • または、次のようにしてgulpfile内から設定します。

gulp.task('set-production-env', function() { return process.env.NODE_ENV = 'production'; });

1
Rakan Nimer

残念ながら、_process.env.NODE_ENV_の設定はBrowserifyでは効果がないため、上記の回答はいずれも機能しません。結果のバンドルにはまだ_process.env.NODE_ENV_参照が含まれているため、

  • Browserifyは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
    ...
_
0
Stefan Becker

また、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
0
mnv