Webpack.config for v2.2.0

时间:2017-01-29 00:44:26

标签: webpack webpack-2

Webpack已经发生了很大的变化,并没有找到适用于v2.2.0的有效Webpack.config。

我确实希望将我的Webpack.config从2.1迁移到2.2

我遇到了很多这样的错误:

ERROR in ./src/styles/core.scss
Module build failed: ReferenceError: window is not defined

那么我需要改变什么来使用v2.2?

我的档案是:

import webpack from 'webpack';
import cssnano from 'cssnano';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';

const cssModulesLoader = [
  'css?sourceMap&-minimize',
  'modules',
  'importLoaders=1',
  'localIdentName=[name]__[local]__[hash:base64:5]'
].join('&');

export default function(options) {
  const webpackConfig = {
    entry: [
      './src/index.js'
    ],
    output: {
      path: __dirname + '/public',
      publicPath: '/',
      filename: 'bundle.[hash].js'
    },
    plugins: [
      new HtmlWebpackPlugin({
        template: './src/index.html',
        favicon: './src/static/favicon.png',
        filename: 'index.html',
        inject: 'body'
      }),
      new ExtractTextPlugin({
        filename: 'styles.[hash].css',
        allChunks: true
      })
    ],
    module: {
      loaders: [{
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          cacheDirectory: true,
          plugins: ['transform-runtime'],
          presets: [
            ['es2015', {'modules': false}],
            'react',
            'stage-0'
          ],
          env: {
            production: {
              presets: ['react-optimize'],
              compact: true
            },
            test: {
              plugins: [
                ['__coverage__', {'only': 'src/'}],
                'babel-plugin-rewire'
              ]
            }
          }
        }
      }, {
        test: /\.json$/,
        loader: 'json'
      }, {
        test: /\.html$/,
        loader: 'html'
      }, {
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract({
          disable: options.dev,
          fallbackLoader: 'style-loader',
          loader: [cssModulesLoader, 'postcss', 'sass?sourceMap']
        })
      }, {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract({
          fallbackLoader: 'style-loader',
          loader: ['css-loader', 'postcss']
        })
      }]
    },
    resolve: {
      modules: ['node_modules'],
      extensions: ['', '.js', '.jsx', '.json'],
      alias: {}
    },
    globals: {},
    postcss: [
      cssnano({
        autoprefixer: {
          add: true,
          remove: true,
          browsers: ['last 2 versions']
        },
        discardComments: {
          removeAll: true
        },
        discardUnused: false,
        mergeIdents: false,
        reduceIdents: false,
        safe: true,
        sourcemap: true
      })
    ]
  };

  if (options.dev) {
    webpackConfig.devtool = 'source-map';
    webpackConfig.plugins.push(
      new webpack.DefinePlugin({
        '__DEV_': true
      })
    );
  }

  if (options.test) {
    process.env.NODE_ENV = 'test';
    webpackConfig.devtool = 'cheap-module-source-map';
    webpackConfig.resolve.alias.sinon = 'sinon/pkg/sinon.js';
    webpackConfig.module.noParse = [
      /\/sinon\.js/
    ];
    webpackConfig.module.loaders.push([
      {
        test: /sinon(\\|\/)pkg(\\|\/)sinon\.js/,
        loader: 'imports?define=>false,require=>false'
      }
    ]);
    // Enzyme fix, see:
    // https://github.com/airbnb/enzyme/issues/47
    webpackConfig.externals = {
      'react/addons': true,
      'react/lib/ExecutionEnvironment': true,
      'react/lib/ReactContext': 'window'
    };
    webpackConfig.plugins.push(
      new webpack.DefinePlugin({
        '__COVERAGE__': options.coverage,
        '__TEST_': true
      })
    );
  }

  if (options.prod) {
    process.env.NODE_ENV = 'production';
    webpackConfig.plugins.push(
      new webpack.LoaderOptionsPlugin({
        minimize: true,
        debug: false
      }),
      new webpack.DefinePlugin({
        'process.env': {
          'NODE_ENV': JSON.stringify('production'),
          '__PROD__': true
        }
      }),
      new webpack.optimize.OccurrenceOrderPlugin(),
      new webpack.optimize.DedupePlugin(),
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          unused: true,
          dead_code: true,
          warnings: false
        }
      })
    );
  }

  if (options.deploy) {
    webpackConfig.output.publicPath = '/MoonMail-UI/';
  }

  return webpackConfig;
}

1 个答案:

答案 0 :(得分:2)

对于任何尝试从Webpack 2.1迁移到2.2的人,这是我的新配置文件:

的package.json

{
"devDependencies": {
    "autoprefixer": "^6.4.0",
    "babel-cli": "^6.11.4",
    "babel-core": "^6.13.2",
    "babel-eslint": "^6.1.0",
    "babel-loader": "^6.2.4",
    "babel-plugin-__coverage__": "^11.0.0",
    "babel-plugin-rewire": "^1.0.0-rc-5",
    "babel-plugin-transform-runtime": "^6.15.0",
    "babel-polyfill": "^6.13.0",
    "babel-preset-es2015": "^6.13.2",
    "babel-preset-react": "^6.11.1",
    "babel-preset-react-optimize": "^1.0.1",
    "babel-preset-stage-0": "^6.5.0",
    "css-loader": "^0.25.0",
    "cssnano": "^3.7.3",
    "enzyme": "^2.4.1",
    "eslint": "^3.3.0",
    "eslint-config-standard": "^6.0.1",
    "eslint-config-standard-react": "^4.0.2",
    "eslint-plugin-babel": "^3.3.0",
    "eslint-plugin-promise": "^2.0.1",
    "eslint-plugin-react": "^6.1.0",
    "eslint-plugin-standard": "^2.0.0",
    "express": "^4.14.0",
    "extract-text-webpack-plugin": "^2.0.0-rc.2",
    "gh-pages": "^0.11.0",
    "html-loader": "^0.4.4",
    "html-webpack-plugin": "^2.24.1",
    "imports-loader": "^0.6.5",
    "json-loader": "^0.5.4",
    "mocha": "^3.0.2",
    "node-sass": "^3.8.0",
    "postcss-cssnext": "^2.9.0",
    "postcss-import": "^9.1.0",
    "postcss-loader": "^1.2.2",
    "sass": "^0.5.0",
    "sass-loader": "^4.1.1",
    "sinon": "^1.17.5",
    "sinon-chai": "^2.8.0",
    "style-loader": "^0.13.1",
    "url-loader": "^0.5.7",
    "webpack": "2.2.0",
    "webpack-dev-server": "2.2.0",
    "yargs": "^5.0.0"
  }
}

webpack.config.js

import webpack from 'webpack';
import cssnano from 'cssnano';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';

export default function(options) {
  const webpackConfig = {
    entry: [
      './src/index.js'
    ],
    output: {
      path: __dirname + '/public',
      publicPath: '/',
      filename: 'bundle.[hash].js'
    },
    plugins: [
      new HtmlWebpackPlugin({
        template: './src/index.html',
        favicon: './src/static/favicon.png',
        filename: 'index.html',
        inject: 'body'
      }),
        new ExtractTextPlugin({ filename: 'styles.[hash].css', disable: false, allChunks: true })
    ],
    module: {
      rules: [{
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        query: {
          cacheDirectory: true,
          plugins: ['transform-runtime'],
          presets: [
            ['es2015', {'modules': false}],
            'react',
            'stage-0'
          ],
          env: {
            production: {
              presets: ['react-optimize'],
              compact: true
            },
            test: {
              plugins: [
                ['__coverage__', {'only': 'src/'}],
                'babel-plugin-rewire'
              ]
            }
          }
        }
      }, {
        test: /\.json$/,
        loader: 'json'
      }, {
        test: /\.html$/,
        loader: 'html-loader'
      }, {
          test: /\.(css|scss)$/,
          loader: ExtractTextPlugin.extract({
              loader: [
                  { loader: 'css-loader?sourceMap&modules&importLoaders=1&localIdentName=[path]___[local]___[hash:base64:5]'},
                  { loader: 'sass-loader?sourceMap'},
                  { loader: 'postcss-loader?sourceMap' },
              ]
          })
      }]
    },
    resolve: {
      modules: ['node_modules'],
      extensions: ['.js', '.jsx', '.json'],
      alias: {}
    }
  };

  if (options.dev) {
    webpackConfig.devtool = 'source-map';
    webpackConfig.plugins.push(
      new webpack.DefinePlugin({
        '__DEV_': true
      })
    );
  }

  if (options.test) {
    process.env.NODE_ENV = 'test';
    webpackConfig.devtool = 'cheap-module-source-map';
    webpackConfig.resolve.alias.sinon = 'sinon/pkg/sinon.js';
    webpackConfig.module.noParse = [
      /\/sinon\.js/
    ];
    webpackConfig.module.loaders.push([
      {
        test: /sinon(\\|\/)pkg(\\|\/)sinon\.js/,
        loader: 'imports?define=>false,require=>false'
      }
    ]);
    // Enzyme fix, see:
    // https://github.com/airbnb/enzyme/issues/47
    webpackConfig.externals = {
      'react/addons': true,
      'react/lib/ExecutionEnvironment': true,
      'react/lib/ReactContext': 'window'
    };
    webpackConfig.plugins.push(
      new webpack.DefinePlugin({
        '__COVERAGE__': options.coverage,
        '__TEST_': true
      })
    );
  }

  if (options.prod) {
    process.env.NODE_ENV = 'production';
    webpackConfig.plugins.push(
      new webpack.LoaderOptionsPlugin({
        minimize: true,
        debug: false
      }),
      new webpack.DefinePlugin({
        'process.env': {
          'NODE_ENV': JSON.stringify('production'),
          '__PROD__': true
        }
      }),
      new webpack.optimize.OccurrenceOrderPlugin(),
      new webpack.optimize.DedupePlugin(),
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          unused: true,
          dead_code: true,
          warnings: false
        }
      })
    );
  }

  if (options.deploy) {
    webpackConfig.output.publicPath = '/MoonMail-UI/';
  }

  return webpackConfig;
}

postcss.config.js

module.exports = {
    plugins: {
        'postcss-import': {},
        'postcss-cssnext': {
            browsers: ['last 2 versions', '> 5%'],
        },
    },
}

如果你不使用url-resolve,你可以删除它:

{ loader: 'sass-loader'}, // remove this line
{ loader: 'resolve-url-loader'} // remove this line

有关此内容的更多信息,请访问:https://github.com/postcss/postcss-loader/issues/92