javascript 使用 Gulp 时如何将 React 设置为生产模式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32526281/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 15:25:06  来源:igfitidea点击:

How to set React to production mode when using Gulp

javascriptpythonflaskreactjstornado

提问by vgoklani

I need to run React in production mode, which presumably entails defining the following somewhere in the enviornment:

我需要在生产模式下运行 React,这大概需要在环境中的某处定义以下内容:

process.env.NODE_ENV = 'production';

The issue is that I'm running this behind Tornado (a python web-server), not Node.js. I also use Supervisord to manage the tornado instances, so it's not abundantly clear how to set this in the running environment.

问题是我在 Tornado(一个 python 网络服务器)而不是 Node.js 后面运行它。我也使用 Supervisord 来管理 Tornado 实例,所以在运行环境中如何设置它不是很清楚。

I do however use Gulp to build my jsx files to javascript.

但是,我确实使用 Gulp 将我的 jsx 文件构建为 javascript。

Is it possible to somehow set this inside Gulp? And if so, how do I check that React is running in production mode?

是否有可能以某种方式在 Gulp 中设置它?如果是这样,我如何检查 React 是否在生产模式下运行?

Here is my Gulpfile.js:

这是我的 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() {});

采纳答案by Monarch Wadia

2017 - Edit: anyone trying to set up React in Gulp for a new project: Just use create-react-app

2017 - 编辑:任何试图在 Gulp 中为新项目设置 React 的人:只需使用create-react-app



Step I:Add the following to your gulpfile.js somewhere

第 I 步:将以下内容添加到您的 gulpfile.js 某处

gulp.task('apply-prod-environment', function() {
    process.env.NODE_ENV = 'production';
});

Step II:Add it to your default task (or whichever task you use to serve/build your app)

第 II 步:将其添加到您的默认任务(或您用于服务/构建应用程序的任何任务)

// before: 
// gulp.task('default',['browsersync','watch'], function() {});
// after:
   gulp.task('default',['apply-prod-environment', 'browsersync','watch'], function() {});


OPTIONAL:If you want to be ABSOLUTELY CERTAIN that you are in prod mode, you can create the following slightly enhanced task instead of the one in Step I:

可选:如果您想绝对确定您处于生产模式,您可以创建以下稍微增强的任务,而不是步骤 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");
    }
});

Which will throw the following error if NODE_ENV is ever not set to 'production'

如果 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!!!!

回答by Chris

Similar to the other answers, but hopefully gives someone a starting point:

与其他答案类似,但希望给某人一个起点:

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'));
});

The main difference is I am explicitly setting the NODE_ENV prior to bundling the vendor libraries. Gulp tasks aren't guaranteed to run in order.

主要区别在于我在捆绑供应商库之前明确设置了 NODE_ENV。Gulp 任务不能保证按顺序运行。

Am I running in production mode?

我是否在生产模式下运行?

If you remove the uglify line (and prior buffer) you will notice that both the dev and production builds are near identical in size - and match in line count.

如果您删除 uglify 行(和先前的缓冲区),您会注意到开发版本和生产版本的大小几乎相同 - 并且行数匹配。

The difference is the production version will be littered with:

不同之处在于生产版本将充斥着:

"production" !== "production" ? [show dev error] : [no nothing]

Most reputable minify'ers (I believe) will strip out deadend code, such as the above, which will always result in false.

大多数有信誉的 minify'ers(我相信)会去除死角代码,例如上面的代码,这总是会导致错误。

But really how do I tell?

但我真的要怎么说呢?

Easiest method to be sure, would be goto the console of your running application and type:

最简单的方法是转到正在运行的应用程序的控制台并键入:

React.createClass.toString();

The output should be:

输出应该是:

"function (e){var t=function(e,t,n){this.__reactAutoBindMap&&c(this),"[....and more and more]

If you find the createClass in the react source, you will see:

如果在react源码中找到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);
      }

Notice how the console output skips straight through to this.__reactAutobind, because you are running in production mode, and using an minify'er, all the !== 'production' warngins and checks have been skipped over.

请注意控制台输出如何直接跳到this.__reactAutobind,因为您正在生产模式下运行,并且使用 minify'er,所有 !== '生产' 警告和检查都已被跳过。

回答by Stefan Becker

Unfortunately none of the above answers work, because setting process.env.NODE_ENVhas no effect in Browserify. The resulting bundle still has process.env.NODE_ENVreferences in it and hence

不幸的是,上述答案process.env.NODE_ENV均无效,因为设置在 Browserify 中无效。结果包中仍然有process.env.NODE_ENV引用,因此

  • Browserify will not require()the React production version modules,
  • the minifier will not be able to remove dead code, and
  • the application will still be running in debug mode.
  • Browserify 不会require()响应生产版本模块,
  • 压缩器将无法删除死代码,并且
  • 应用程序仍将在调试模式下运行。

This is unfortunately not the only place where this approach is offered as the correct answer :-(

不幸的是,这不是唯一提供这种方法作为正确答案的地方:-(



The correct approach can be found in e.g.

正确的方法可以在例如

You need to switch the envify transform to be a global one, e.g.

您需要将 envify 转换为全局转换,例如

# note the "-g" instead of the usual "-t"
$ browserify ... -g [ envify --NODE_ENV production ] ....

or in gulpfile.js

或在 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
    ...

回答by Rakan Nimer

To set React in production mode you need to set your NODE_ENV variable to production and uglify your JS as an extra step.

要将 React 设置为生产模式,您需要将 NODE_ENV 变量设置为生产,并将您的 JS 丑化为一个额外的步骤。

You're already taking care of the uglification, for setting your NODE_ENV variable :

您已经在处理丑化问题,以设置您的 NODE_ENV 变量:

  • Set the variable while running the gulp task :
  • 在运行 gulp 任务时设置变量:

NODE_ENV='production' gulp

NODE_ENV='production' gulp

  • OR set it from inside your gulpfile by doing something like this :
  • 或者通过执行以下操作从您的 gulpfile 内部设置它:

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

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

回答by mnv

Also you may use handy way with gulp-environments:

您也可以使用方便的方式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/"));

To run gulp in production mode:

在生产模式下运行 gulp:

gulp build --env=production