你如何配置 Webpack 以清除生产缩小的 React 警告?

Posted

技术标签:

【中文标题】你如何配置 Webpack 以清除生产缩小的 React 警告?【英文标题】:How do you configure Webpack to clear the React Warning for production minification? 【发布时间】:2017-11-10 11:02:59 【问题描述】:

我相信每个人都看到了这个错误,但它又出现了:

警告:您似乎正在使用 React 开发版本的缩小副本。将 React 应用程序部署到生产环境时,请确保使用跳过开发警告且速度更快的生产构建版本。详情请见https://facebook.github.io/react/docs/optimizing-performance.html#use-the-production-build。

当然,我按照提供的链接中的说明进行操作,尽管我已经对我的代码进行了所有必要的更新,但我仍然收到此错误。

根据我在 *** 和 Github 上看到的其他一些答案,通过 Webpack 插件 DefinePluginprocess.env.NODE_ENV 设置为 production 告诉 React 使用缩小版本进行构建。所以我在我的主应用程序组件中记录了process.env.NODE_ENV,实际上它被插件设置为production,但我仍然收到警告。

因此,即使环境变量被设置为生产环境,我也会收到警告,并且我的 React 开发工具会说:

此页面使用 React 的开发版本。 ??? 请注意,开发版本不适合生产。 确保在部署之前使用生产版本。

我似乎无法确定问题可能出在哪里,因为我已经完成了所有必要的更改以使生产构建工作。

这是我的webpack.config.js 文件:

const webpack = require('webpack');
const resolve = require('path').resolve;
const SRC_BASE = resolve(__dirname, 'src');
const merge = require('webpack-merge');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const argv = require('yargs').argv;
const HtmlWebpackPlugin = require('html-webpack-plugin');

const definePlugin = new webpack.DefinePlugin(
  __DEV__: JSON.stringify(JSON.parse(process.env.BUILD_DEV || 'true')),
  __PRERELEASE__: JSON.stringify(JSON.parse(process.env.BUILD_PRERELEASE || 'false')),
  __PRODUCTION__: JSON.stringify(JSON.parse(process.env.NODE_ENV === 'production' || 'false')),
  'process.env': 
    NODE_ENV: process.env.NODE_ENV === 'production' ? // set NODE_ENV to production or development
      JSON.stringify('production') : JSON.stringify('development'),
  ,
);

const loaderOptionsPlugin = new webpack.LoaderOptionsPlugin( options:  context: __dirname  );
const commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');
const cssOutput = new ExtractTextPlugin( filename: 'style.css', allChunks: true );
const sourceMapPlugin = new webpack.SourceMapDevToolPlugin( filename: '[name].map' );
const htmlPlugin = new HtmlWebpackPlugin(
  template: `$SRC_BASE/index.template.ejs`,
  filename: '../index.html', // relative to public/build/ so this is public/index.html
  inject: true,
  hash: true,
);

let config = 
  cache: true,
  entry: 
    main: ['babel-polyfill', resolve(SRC_BASE, 'index')],
  ,
  output: 
    path: resolve(__dirname, 'public/build'),
    filename: '[name].bundle.js',
    publicPath: '/build/',
    sourceMapFilename: '[name].map',
  ,
  resolve: 
    modules: [
      SRC_BASE,
      'node_modules',
    ],
    extensions: ['.js', '.jsx'],
  ,
  module: 
    rules: [
      
        test: [/\.jsx$/, /\.js$/],
        loader: 'babel-loader',
        exclude: /(local_modules|node_modules|bower_components)/,
        query: 
          presets: [
            'react',
            'es2015',
            'stage-1',
          ],
        ,
      ,
      
        test: /\.(eot|woff|woff2|ttf|svg|png|jpe?g|gif)(\?\S*)?$/,
        loader: 'file-loader',
      ,
      
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract(
          fallback: 'style-loader',
          use: 'css-loader!sass-loader',
        ),
      ,
    ],
  ,
  node: 
    fs: 'empty',
  ,
  plugins: [
    definePlugin,
    commonsPlugin,
    cssOutput,
    htmlPlugin,
    loaderOptionsPlugin,
    sourceMapPlugin,
  ],
;

// Only load dashboard if we're watching the code
if (argv.watch) 
  const DashboardPlugin = require('webpack-dashboard/plugin');
  config = merge(config,  plugins: [new DashboardPlugin()] );


if (process.env.NODE_ENV === 'production') 
  console.log('******* I AM MERGING PRODUCTION CONFIGS ******');
  console.log(`process.env.NODE_ENV = $process.env.NODE_ENV`);
  config = merge(config, 
    devtool: 'cheap-module-source-map',
    plugins: [
      new webpack.LoaderOptionsPlugin(
        minimize: true,
        debug: false,
      ),
      new webpack.optimize.UglifyJsPlugin(),
    ],
    module: 
      rules: [
         test: /redux-logger/, loader: 'null-loader' ,
      ],
    ,
  );


module.exports = config;

这是我运行 gulp build --productiongulpfile.js 任务:

/* Production Builds use this task */
gulp.task('webpack', (done) => 
  if (argv.production) 
    process.env.BUILD_DEV = false;
    process.env.NODE_ENV = 'production';
  

  const buildConfig = require('./webpack.config');
  const compiler = webpack(buildConfig);
  const tag = '[webpack]';
  const info = gutil.colors.green;
  const error = gutil.colors.red;
  const warning = gutil.colors.yellow;

  const filterStackTraces = err =>
      err.toString().split(/[\r\n]+/).filter(line => ! line.match(/^\s+at Parser/)).join(EOL);

  if (argv.watch) 
    compiler.watch(, (err, stats) => 
      const statDetails = stats.toJson();
      if (err) 
        gutil.log(error(tag), err.toString( colors: true ));
      
      else if (stats.hasErrors()) 
        statDetails.errors.forEach(ex => gutil.log(error(tag), filterStackTraces(ex)));
      
      else if (stats.hasWarnings()) 
        statDetails.warnings.forEach(wx => gutil.log(warning(tag), filterStackTraces(wx)));
      
      else 
        statDetails.chunks.forEach(chunk => 
          if (chunk.entry) gutil.log(info(tag), `Built $chunk.files[0] ($chunk.size bytes)`);
        );
        gutil.log(info(tag), 'Build complete');
      
    );
  
  else 
    compiler.run((err, stats) => 
      if (err) 
        return done(new gutil.PluginError('webpack', err));
      
      if (stats.hasErrors()) 
        const statDetails = stats.toJson();
        statDetails.errors.forEach(ex => gutil.log(error(tag), filterStackTraces(ex)));
        return done(new gutil.PluginError('webpack', 'Parse/ build error(s)'));
      
      gutil.log(gutil.colors.green(tag), stats.toString( colors: true ));
      done();
    );
  
);

gulp.task('build', ['webpack']);

【问题讨论】:

【参考方案1】:

在互联网上偶然发现了一些不同的方法来配置 webpack 以克服这个问题 I found a configuration option 在 UglifyJsPlugin 中清除了错误。

plugins: [
    new webpack.optimize.UglifyJsPlugin(
      include: /\.min\.js$/, <------This option fixed it
    )
  ]

尽管这清除了控制台中的警告,但我仍然看到我的 React 开发工具说它没有使用生产版本。

【讨论】:

这里的问题完全相同。你有没有运气修复它?【参考方案2】:

我也遇到过同样的问题,但似乎不是 webpack 的问题——可能与 Gulp 有关。您是否尝试过直接从命令行(即webpack --config webpack-build.config.js 或其他)使用配置运行 webpack?这很高兴地产生了一个没有警告的构建。这是我的 webpack 配置,由各种来源拼凑而成:

const path = require('path')
const webpack = require('webpack')

module.exports = 
  devtool: 'cheap-module-source-map',
  entry: './src/scripts/app',
  output: 
    path: path.join(__dirname, 'dist/scripts'),
    filename: 'bundle.js',
    publicPath: '/static/'
  ,
  module: 
    loaders: [
      
        test: /\.js$/,
        loader: 'babel-loader',
        query: 
          presets: ['env', 'react'] 
        
      
    ]
  ,
  plugins: [
    new webpack.DefinePlugin(
      'process.env':  
        NODE_ENV: JSON.stringify('production') 
      
    ),
    new webpack.LoaderOptionsPlugin(
      minimize: true,
      debug: false
    ),
    new webpack.optimize.UglifyJsPlugin(
      beautify: false,
      mangle: 
        screw_ie8: true,
        keep_fnames: true
      ,
      compress: 
        screw_ie8: true
      ,
      comments: false
    )
  ]

如果我追踪 gulp + webpack 发生了什么,我会写一个更新。

【讨论】:

以上是关于你如何配置 Webpack 以清除生产缩小的 React 警告?的主要内容,如果未能解决你的问题,请参考以下文章

如何设置 webpack 以缩小和组合 scss 和 javascript 之类的 CodeKit?

如何使用 webpack 和 angular2 为生产部署代码

使用 Tailwind 时如何使用 Webpack 缩小 CSS

[万字逐步详解]使用 webpack 打包 vue 项目(基础生产环境)

如何从我的 webpack 2 配置中创建/生成/导出文件以在我的 React 代码中使用?

webpack