UNPKG

@25sprout/react-starter

Version:

25sprout web starter with React

185 lines (178 loc) 4.37 kB
import path from 'path'; import webpack from 'webpack'; import atImport from 'postcss-import'; import cssnext from 'postcss-cssnext'; import HtmlWebpackPlugin from 'html-webpack-plugin'; import ExtractTextPlugin from 'extract-text-webpack-plugin'; import palette from './config/palette'; import media from './config/media'; import env from './config/env'; const extractText = new ExtractTextPlugin({ filename: '[name].[contenthash].css', allChunks: true, }); const extractGlobalText = new ExtractTextPlugin('vendor.[contenthash].css'); const webpackProdConfig = { devtool: 'source-map', entry: { app: './src/index.js', vendor: ['babel-polyfill', 'whatwg-fetch', 'react', 'react-container-helper', 'react-dom'], }, output: { path: path.join(__dirname, '_public'), filename: '[name].[chunkhash].js', chunkFilename: '[name].[chunkhash].chunk.js', publicPath: '', }, plugins: [ new webpack.DefinePlugin({ 'process.env': env, }), // Chunk js file for vendor // See https://webpack.js.org/guides/code-splitting-libraries/#manifest-file new webpack.optimize.CommonsChunkPlugin({ name: ['vendor', 'manifest'], minChunks: Infinity, }), new webpack.NoEmitOnErrorsPlugin(), new HtmlWebpackPlugin({ template: './src/index.html', minify: { removeComments: true, collapseWhitespace: true, removeRedundantAttributes: true, useShortDoctype: true, removeEmptyAttributes: true, removeStyleLinkTypeAttributes: true, removeScriptTypeAttributes: true, keepClosingSlash: true, minifyJS: true, minifyCSS: true, minifyURLs: true, }, inject: true, showErrors: false, filename: 'index.html', chunksSortMode: 'dependency', }), extractGlobalText, extractText, ], module: { rules: [ { test: /\.js?$/, include: [path.join(__dirname, 'src')], exclude: path.join(__dirname, 'node_modules'), loader: 'babel-loader', options: { presets: [['es2015', { loose: true, modules: false }], 'react', 'stage-3'], }, }, { test: /\.css$/, include: path.join(__dirname, 'src'), use: extractText.extract({ fallback: 'style-loader', use: [ { loader: 'css-loader', options: { sourceMap: process.env.NODE_ENV !== 'production', camelCase: true, modules: true, importLoaders: 1, localIdentName: '[name]__[local]___[hash:base64:5]', minimize: true, autoprefixer: false, }, }, { loader: 'postcss-loader', options: { sourceMap: process.env.NODE_ENV !== 'production' ? 'inline' : false, plugins: () => [ atImport(), cssnext({ features: { customProperties: { variables: palette, }, customMedia: { extensions: media, }, }, }), ], }, }, ], }), }, { test: /\.css$/, include: path.join(__dirname, 'node_modules'), use: extractGlobalText.extract({ fallback: 'style-loader', use: [ { loader: 'css-loader', options: { sourceMap: process.env.NODE_ENV !== 'production', minimize: true, autoprefixer: false, }, }, ], }), }, { test: /\.(jpe?g|png|gif)$/, include: path.join(__dirname, 'src'), loader: 'url-loader', options: { limit: 10000, name: './assets/[name]__[hash].[ext]', }, }, { test: /\.svg$/, include: path.join(__dirname, 'src'), use: [ 'babel-loader', 'svg-react-loader', { loader: 'svgo-loader', options: { plugins: [{ removeTitle: true }, { collapseGroups: false }], }, }, 'svg-css-modules-loader', { loader: 'string-replace-loader', options: { search: '%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22', replace: '', }, }, ], }, ], }, node: { fs: 'empty', }, resolve: { modules: ['node_modules'], }, }; // Minify and optimize the JavaScript if (process.env.NODE_ENV === 'production') { webpackProdConfig.plugins.push(new webpack.optimize.UglifyJsPlugin({ sourceMap: true, })); webpackProdConfig.plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true, })); } export default webpackProdConfig;