Jak włączyć / wyłączyć tryb programowania w ReactJS?

120

Zaczęto używać funkcji sprawdzania poprawności właściwości ReactJS , która, jak mówią dokumenty, działa tylko w „trybie programistycznym” ze względu na wydajność.

Wydaje się, że React sprawdza właściwości konkretnego komponentu, o którym pisałem, ale nie pamiętam, żebym jawnie włączał „tryb programowania”.

Próbowałem znaleźć sposób wyzwalania / przełączania trybu programowania, ale nie miałem szczęścia.

gdso
źródło
świetne, zwięzłe wyjaśnienie process.envdla użytkowników
webpacka

Odpowiedzi:

129

Druga odpowiedź zakłada, że ​​używasz zewnętrznych, gotowych plików z firmy React i chociaż jest to poprawne, większość ludzi nie zamierza lub powinna korzystać z Reacta jako pakietu. Co więcej, w tym momencie większość bibliotek i pakietów React również korzysta z tej samej konwencji wyłączania pomocników dev time podczas produkcji. Samo użycie zminimalizowanej reakcji pozostawi wszystkie te potencjalne optymalizacje również na stole.

Ostatecznie magia sprowadza się do osadzania odniesień do process.env.NODE_ENVReacta w całej bazie kodu; te działają jak przełącznik funkcji.

if (process.env.NODE_ENV !== "production")
  // do propType checks

Powyższy wzorzec jest najbardziej rozpowszechniony, podobnie jak inne biblioteki. Więc do „Wyłącz” tych kontroli musimy przełączać NODE_ENVsię"production"

Właściwym sposobem wyłączenia „trybu deweloperskiego” jest skorzystanie z wybranego pakietu.

webpack

Użyj DefinePluginw konfiguracji swojego webpacka w następujący sposób:

new webpack.DefinePlugin({
  "process.env.NODE_ENV": JSON.stringify("production")
})

Browserify

Użyj transformacji Envify i uruchom krok kompilacji browserify z NODE_ENV=production( "set NODE_ENV=production"w systemie Windows)

Wynik

Spowoduje to utworzenie pakunków wyjściowych, w których wszystkie wystąpienia process.env.NODE_ENVzastąpiono literałem ciągu:"production"

Premia

Podczas minimalizacji przekształconego kodu można skorzystać z „Eliminacji martwego kodu”. DCE występuje wtedy, gdy minifier jest wystarczająco inteligentny, aby zdać sobie sprawę, że: "production" !== "production"jest zawsze fałszywy, a więc po prostu usunie dowolny kod w bloku if, oszczędzając bajty.

panika klasztorna
źródło
1
Dokumentacja reagowania wyjaśnia również facebook.github.io/react/docs/ ...
asotog
1
Czy naprawdę potrzebujesz tam JSON.stringify („produkcja”)? A może wystarczy „produkcja”?
Vlad Nicula
4
@VladNicula to musi być '"production"'np. w podwójnym cudzysłowie, stringify robi to za Ciebie
monastic-panic
1
Możesz także użyć, JSON.stringify(process.env.NODE_ENV)aby można było przełączać za NODE_ENV=production webpack ...pomocą wiersza poleceń. Dodano bonus w postaci jawnego kodu =)
Henry Blyth
2
Właśnie dowiedziałem się, że to DefinePluginużycie można zastąpićnew webpack.EnvironmentPlugin(['NODE_ENV'])
Henry Blyth
50

Tak, nie jest to dobrze udokumentowane, ale na stronie pobierania ReactJS mówi o trybach rozwoju i produkcji:

Udostępniamy dwie wersje Reacta: nieskompresowaną wersję do programowania i zminimalizowaną wersję do produkcji. Wersja rozwojowa zawiera dodatkowe ostrzeżenia o typowych błędach, podczas gdy wersja produkcyjna zawiera dodatkowe optymalizacje wydajności i usuwa wszystkie komunikaty o błędach.

Zasadniczo niezminifikowana wersja Reacta jest w trybie „programistycznym”, a zminimalizowana wersja Reacta w trybie „produkcyjnym”.

Aby być w trybie „produkcyjnym”, wystarczy dołączyć wersję zminimalizowaną react-0.9.0.min.js

Edward M. Smith
źródło
2
Jeśli twój bundler minifikuje, nie sądzę, że usunie to debugowanie. Musisz uwzględnić zminimalizowaną wersję Reacta w swojej kompilacji produkcyjnej - tę zawartą w dystrybucji React - to właściwie inny kod niż niezminifikowana wersja, z tego, co rozumiem.
Edward M Smith
17
Jeśli npmbudujesz bezpośrednio z pakietu reagowania, użyj czegoś takiego jak envify, aby ustawić NODE_ENV = 'production'wykonywanie tych samych testów. @EdwardMSmith Daj mi znać, gdzie chciałbyś zobaczyć te informacje, a mogę je dodać (lub możesz po prostu przesłać PR)!
Sophie Alpert
2
@BenAlpert - powiedziałbym, że strona w przewodnikach lub poradach opisująca wdrożenie produkcyjne. Rzucę okiem i zobaczę, co mogę wymyślić. I nie zostały faktycznie wykonane do wdrożenia produkcyjnego, więc może trzeba pewne korekty. Prześlę PR.
Edward M Smith
1
Chciałem tylko dodać, że wersja dodatku nie wydaje się mieć włączonego trybu programowania, nawet wersja niezminimalizowana.
KallDrexx,
8
Nie sądzę, że jest to najlepsza odpowiedź, ponieważ niektórzy ludzie budują swoją reakcję za pomocą przeglądarki browserify, a odpowiedź wykorzystująca NODE_ENVpowinna znajdować się na górze.
Bjorn
16

Opublikowałem to gdzie indziej, ale szczerze mówiąc, tutaj byłoby lepsze miejsce.

Zakładając, że zainstalujesz React 15.0.1 z npm, import react from 'react'lub react = require('react')uruchomisz, ./mode_modules/react/lib/React.jsktóry jest surowym źródłem Reacta .

Dokumentacja React sugeruje użycie ./mode_modules/react/dist/react.jsdo rozwoju i react.min.jsprodukcji.

Powinieneś zminimalizować /lib/React.js lub /dist/react.jsuruchomisz produkcyjną, React wyświetli ostrzeżenie, że zminimalizowałeś kod nieprodukcyjny:

Warning: It looks like you're using a minified copy of the development build of React. When deploying React apps to production, make sure to use the production build which skips development warnings and is faster. See fb.me/react-minification for more details.

React-dom, redux, reag-redux zachowują się podobnie. Redux wyświetla komunikat ostrzegawczy. Uważam, że reakcja też.

Dlatego wyraźnie zachęcamy do korzystania z wersji produkcyjnej z /dist.

Jeśli jednak zminimalizujesz plik /dist zminimalizujesz wersje, UglifyJsPlugin z webpacka będzie narzekać.

WARNING in ../~/react/dist/react.js Critical dependencies: 4:478-485 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results. @ ../~/react/dist/react.js 4:478-4851

Nie możesz uniknąć tego komunikatu, ponieważ UglifyJsPlugin może wykluczać tylko fragmenty pakietu webpack, a nie pojedyncze pliki.

Sam korzystam z wersji rozwojowej i produkcyjnej /dist.

  • Webpack ma mniej pracy i kończy się nieco wcześniej. (YRMV)
  • Dokumentacja React twierdzi, że /dist/react.min.jsjest zoptymalizowana pod kątem produkcji. Nie przeczytałem żadnego dowodu na to'process.env': { NODE_ENV: JSON.stringify(IS_PRODUCTION ? 'production' : 'development') } plus uglify działa tak dobrze jak "/ dist / reaguj.min.js". Nie przeczytałem żadnego dowodu, że otrzymujesz ten sam wynikowy kod.
  • Dostaję 1 wiadomość ostrzegawczą od uglify zamiast 3 z ekosystemu reaguj / redux.

Możesz użyć webpacka do korzystania z /distwersji z:

resolve: {
    alias: {
      'react$': path.join(__dirname, 'node_modules', 'react','dist',
        (IS_PRODUCTION ? 'react.min.js' : 'react.js')),
      'react-dom$': path.join(__dirname, 'node_modules', 'react-dom','dist',
        (IS_PRODUCTION ? 'react-dom.min.js' : 'react-dom.js')),
      'redux$': path.join(__dirname, 'node_modules', 'redux','dist',
        (IS_PRODUCTION ? 'redux.min.js' : 'redux.js')),
      'react-redux$': path.join(__dirname, 'node_modules', 'react-redux','dist',
        (IS_PRODUCTION ? 'react-redux.min.js' : 'react-redux.js'))
    }
  }
JohnSz
źródło
1
W przypadku uruchamiania z pakietu webpack cli: const IS_PRODUCTION = process.argv.indexOf ('- p')! == -1;
Greg
2
To nie jest zalecane rozwiązanie (źródło: pracuję nad React). Prawidłowe rozwiązania są udokumentowane tutaj: Reactjs.org/docs/… . Jeśli nie zadziałają, zgłoś problem w repozytorium React, a my postaramy się pomóc.
Dan Abramov
4

W przypadku kompilacji opartej na pakiecie webpack skonfigurowałem osobny plik webpack.config.js dla DEV i PROD. W przypadku Prod rozwiąż alias jak poniżej

     alias: {
        'react$': path.join(__dirname, 'node_modules', 'react','dist','react.min.js'),
        'react-dom$': path.join(__dirname, 'node_modules', 'react-dom','dist','react-dom.min.js')
    }

Możesz znaleźć działający tutaj

Senthil
źródło
1
To nie jest zalecane rozwiązanie (źródło: pracuję nad React). Prawidłowe rozwiązania są udokumentowane tutaj: Reactjs.org/docs/… . Jeśli nie zadziałają, zgłoś problem w repozytorium React, a my postaramy się pomóc.
Dan Abramov
1

Jeśli pracujesz z czegoś takiego, jak ten samouczek dotyczący ReactJS.NET / Webpack , nie możesz używać process.env do włączania / wyłączania trybu programowania React, o ile wiem. Ten przykład łączy bezpośrednio zreak.js (patrz Index.cshtml ), więc wystarczy wybrać plik .min.js lub niezminifikowany wariant, zmieniając adres URL.

Nie jestem pewien, dlaczego tak jest, ponieważ plik webpack.config.js próbki zawiera komentarz, który wydaje się sugerować, externals: { react: 'React' }że wykona zadanie, ale następnie włącza reakcję bezpośrednio na stronę.

Roman Starkov
źródło
Jeśli dobrze zgadłem, to mówisz, że jeśli będziesz łączyć i minifikować za pomocą ReactJS.Net, nie będzie to korzystne minifikacja pliku programistycznego reag.js. W tym celu podczas sprzedaży pakietowej za pomocą testów #IF DEBUG należy jawnie zmienić adres URL na plik produkcyjny reag.js dostarczony ze strony pobierania Facebooka. Podobnie jest z reakcją-domem i Redux. Czy mam rację?
Faisal Mq
@FaisalMushtaq To część tego; w zależności od tego, w jaki sposób umieścisz reag.js, może być konieczne jawne przełączenie się na wersję zminimalizowaną. Ale naprawdę chciałem powiedzieć, że możliwe jest skonfigurowanie Reacta w taki sposób, że „oficjalny” sposób włączania trybu deweloperskiego nie zadziała.
Roman Starkov
0

Dla wyłącznie WebPACK użytkowników v4:

Określenie mode: productioni mode: developmentw konfiguracji WebPacka zdefiniuje process.env.NODE_ENVdomyślnie użycie DefinePlugin. Nie potrzeba dodatkowego kodu!

webpack.prod.js (pobrane z dokumentów)

const merge = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
  mode: 'production',
});

A w naszym JS:

console.log(process.env.NODE_ENV) // --> 'development' or 'production'

Dokumenty Webpack: https://webpack.js.org/guides/production/#specify-the-mode

Joe
źródło
0

Używam ręcznego procesu kompilacji, który działa przez Webpack, więc był to dla mnie proces dwuetapowy:

  1. Ustaw zmienną środowiskową z package.json za pomocą pakietu cross-env:

    "scripts": { "build-dev": "cross-env NODE_ENV=development webpack --config webpack.config.js", "build-prod": "cross-env NODE_ENV=production webpack --config webpack.config.js" }

  2. Zmień plik webpack.config.js, aby używał zmiennej środowiskowej (która jest przekazywana do Reacta w celu określenia, czy jesteśmy w trybie programistycznym, czy produkcyjnym) i wyłącz minimalizowanie utworzonego pakietu, jeśli jesteśmy w trybie programistycznym, abyśmy mogli zobaczyć aktualne nazwy naszych komponentów. W tym celu musimy użyć właściwości optymalizacji pakietu webpack w naszym pliku webpack.config.js :

    optimization: { nodeEnv: process.env.NODE_ENV, minimize: process.env.NODE_ENV === 'production' }

webpack v4.41.5, React v16.9.19, cross-env v7.0.0, node v10.16.14

John Galt
źródło