代码之家  ›  专栏  ›  技术社区  ›  vgoklani

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

  •  33
  • vgoklani  · 技术社区  · 9 年前

    我需要在生产模式下运行React,这可能需要在环境中定义以下内容:

    process.env.NODE_ENV = 'production';
    

    问题是我运行的是Tornado(一个python web服务器),而不是Node.js。我还使用Supervisord来管理龙卷风实例,因此在运行环境中如何设置它并不十分清楚。

    然而,我确实使用Gulp将jsx文件构建为javascript。

    有没有可能把这个放在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() {});
    
    5 回复  |  直到 9 年前
        1
  •  28
  •   Community Ian Goodfellow    4 年前

    2017年-编辑:任何试图为新项目在Gulp建立React的人:使用 create-react-app


    第一步: 将以下内容添加到gulpfile中。js某处

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

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

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

    可选: 如果您想绝对确定您处于生产模式,可以创建以下稍微增强的任务,而不是步骤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从未设置为“production”,则会引发以下错误

    [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!!!!
    
        2
  •  8
  •   Chris    8 年前

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

    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任务不能保证按顺序运行。

    我是否以生产模式运行?

    如果您删除了丑陋的行(以及先前的缓冲区),您将注意到开发和生产版本的大小几乎相同,并且行数也匹配。

    不同的是,生产版本将充斥着:

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

    我相信,大多数有信誉的迷你人都会去掉死端代码,比如上面的代码,这总是会导致错误。

    但我该怎么说呢?

    最容易确定的方法是转到正在运行的应用程序的控制台并键入:

    React.createClass.toString();
    

    输出应为:

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

    如果在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);
          }
    

    注意控制台输出如何直接跳转到 this.__reactAutobind ,因为您正在以生产模式运行,并且使用了一个小型“呃,所有!==”生产警告和检查被跳过。

        3
  •  2
  •   Stefan Becker    7 年前

    不幸的是,上述答案都不起作用,因为设置 process.env.NODE_ENV 在Browserify中无效。生成的捆绑包仍然具有 进程.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
        ...
    
        4
  •  1
  •   Rakan Nimer    9 年前

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

    您已经在处理设置NODE_ENV变量的错误:

    • 在运行gulf任务时设置变量:

    NODE_ENV='production' gulp

    • 或者通过以下操作从gulpfile中设置:

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

        5
  •  0
  •   Nick    7 年前

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

    要在生产模式下运行gulf:

    gulp build --env=production