Как установить режим "Реагировать в производство" при использовании Gulp
Мне нужно запустить React в режиме производства, который предположительно предполагает определение следующего в enviornment:
process.env.NODE_ENV = 'production';
Проблема в том, что я запускаю это за Tornado (веб-сервер python), а не 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() {});
Ответы
Ответ 1
2017 - Изменить: любой, кто пытается настроить React в Gulp для нового проекта: Просто используйте 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() {});
ДОПОЛНИТЕЛЬНО: Если вы хотите быть абсолютным, что вы находитесь в режиме 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 никогда не установлен в '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
Подобно другим ответам, но, надеюсь, дает кому-то исходную точку:
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" !== "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]
Если вы обнаружите 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
, потому что вы работаете в режиме производства и с помощью minify'er все предупреждения и проверки 'production' были пропущены.
Ответ 3
Чтобы установить режим "Реакт в рабочем режиме", вам нужно настроить свою переменную NODE_ENV на производство и активировать JS как дополнительный шаг.
Вы уже заботитесь об угасании, для установки своей переменной NODE_ENV:
- Задайте переменную во время выполнения задачи gulp:
NODE_ENV='production' gulp
- ИЛИ установите его внутри вашего gulpfile, выполнив что-то вроде этого:
gulp.task('set-production-env', function() {
return process.env.NODE_ENV = 'production';
});
Ответ 4
Также вы можете использовать удобный способ с 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
Ответ 5
К сожалению, ни один из вышеперечисленных ответов не работает, потому что установка process.env.NODE_ENV
не влияет на Browserify. Полученный в результате пакет все еще имеет process.env.NODE_ENV
ссылки в нем и, следовательно,
- Browserify не будет
require()
версиями модулей версии React,
- minifier не сможет удалить мертвый код и
- приложение все еще будет работать в режиме отладки.
Это, к сожалению, не единственное место, где этот подход предлагается в качестве правильного ответа: - (
Правильный подход можно найти, например,
Вам нужно переключить преобразование 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
...