Updated webpack to the latest version(2.6.1), so the webpack config file, that came with the boilerplate, became outdated...
Looked at the official documentation on migration, but still a bit lost regarding how exactly i need to update my config file:
'use strict';
const path = require('path');
const webpack = require('webpack');
const NODE_ENV = process.env.NODE_ENV;
const SaveAssetsJson = require('assets-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
devtool: '#source-map',
// Capture timing information for each module
profile: false,
// Switch loaders to debug mode
debug: false,
// Report the first error as a hard error instead of tolerating it
bail: true,
entry: [
'babel-polyfill',
'./assets/main.jsx',
],
output: {
path: 'public/dist/',
pathInfo: true,
publicPath: '/dist/',
filename: 'bundle.[hash].min.js',
},
resolve: {
root: path.join(__dirname, ''),
modulesDirectories: [
'web_modules',
'node_modules',
'assets',
'assets/components',
],
extensions: ['', '.webpack.js', '.web.js', '.js', '.jsx'],
},
resolveLoader: {
},
plugins: [
new CleanWebpackPlugin(['public/dist'], {
verbose: true,
dry: false,
}),
new webpack.optimize.UglifyJsPlugin({
minimize: true,
output: {
comments: false,
},
compress: {
warnings: false,
screw_ie8: true,
},
}),
new SaveAssetsJson({
path: process.cwd(),
filename: 'assets.json',
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
},
}),
],
query: {presets: ['es2015', 'react'] },
module: {
rules: [
{
use: [
"style-loader",
"css-loader",
"autoprefixer-loader",
]
},
{
test: /\.scss$/, // sass files
loader: 'style!css!autoprefixer?browsers=last 2 version!sass?outputStyle=expanded',
},
{
test: /\.(ttf|eot|svg|woff)(\?[a-z0-9]+)?$/, // fonts files
loader: 'file-loader?name=[path][name].[ext]',
},
{
test: /\.jsx?$/, // react files
exclude: /node_modules/,
loaders: ['babel?presets[]=es2015,presets[]=stage-0,presets[]=react'],
include: path.join(__dirname, 'assets'),
},
],
noParse: /\.min\.js/,
}
};
In the end there were few deletion of the deprecated plugin calls and restructuring some of the fields. Here is the 2.6.1 compatible version, the parts of the file that were changed:
'use strict';
module.exports = {
devtool: '#source-map',
// Capture timing information for each module
profile: false,
// Switch loaders to debug mode
//debug: false,
// Report the first error as a hard error instead of tolerating it
bail: true,
entry: [
'babel-polyfill',
'./assets/main.jsx',
],
output: {
path: '/public/dist/', //This has to be an absolute path
publicPath: '/dist/',
filename: 'bundle.[hash].min.js',
},
resolve: {
//merging root and modules
modules: [
path.join(__dirname, ''),
'web_modules',
'node_modules',
'assets',
'assets/components',
],
extensions: [ '.webpack.js', '.web.js', '.js', '.jsx'], //Removed empty entry
},
resolveLoader: {
},
plugins: [
new CleanWebpackPlugin(['public/dist'], {
verbose: true,
dry: false,
}),
new webpack.optimize.UglifyJsPlugin({
minimize: true,
sourceMap: true, //added this
output: {
comments: false,
},
compress: {
warnings: false,
screw_ie8: true,
},
}),
new SaveAssetsJson({
path: process.cwd(),
filename: 'assets.json',
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
},
}),
],
module: {
//Modules are slightly differently listed now
rules: [
{
test: /\.(css|scss)$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "sass-loader" // compiles Sass to CSS
}]
},
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015', "stage-0", 'react']
}
}
}
],
noParse: /\.min\.js/,
}
};
Related
I would like to use a sequential number such as 1.js, 2.js,... for chunkFileName in production mode of webpack v5. I set [index].js for naming but webpack gives me following error:
Error: Conflict: Multiple chunks emit assets to the same filename
[index].js (chunks 179 and 216)
Here's my config for webpack:
var config = {
devtool: 'eval-source-map',
cache: true,
entry: {
main: path.join(__dirname, "app", "App.js"),
},
output: {
path: path.join(__dirname, 'scripts', 'js'),
filename: '[name].js',
chunkFilename: '[name].js',
sourceMapFilename: '[file].map',
publicPath: '/scripts/js/'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
babelrc: false,
presets: [
['es2015', { modules: false }],
'react',
],
plugins: [
'syntax-dynamic-import',
'transform-object-rest-spread',
'transform-class-properties',
'transform-object-assign',
],
}
},
},
{
// Preprocess our own .css files
// This is the place to add your own loaders (e.g. sass/less etc.)
// for a list of loaders, see https://webpack.js.org/loaders/#styling
test: /\.css$/,
exclude: /node_modules/,
use: [
'style-loader',
'css-loader',
]
}
],
},
optimization: {
minimize: false,
splitChunks: {
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
chunks: "all"
}
},
}
},
plugins: [
new CompressionPlugin({
algorithm: 'gzip',
test: /\.(js)$|\.(css)$|\.(html)$|\.eot?.+$|\.ttf?.+$|\.woff?.+$|\.svg?.+$/,
//threshold: 10240,
//minRatio: 0
})
],
resolve: {
extensions: ['.js', '.jsx', '.css', '.ts'],
alias: {
'react-loadable': path.resolve(__dirname, 'app/app.js'),
},
},
};
if (process.env.NODE_ENV === 'production') {
const TerserPlugin = require("terser-webpack-plugin");
config.devtool = false;
config.output.chunkFilename = '[index].js';
config.optimization = {
minimize: true,
minimizer: [new TerserPlugin()],
splitChunks: {
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
chunks: "all",
}
},
}
},
config.plugins = [
new webpack.optimize.AggressiveMergingPlugin(),
new webpack.DefinePlugin({
'process.env': { NODE_ENV: JSON.stringify('production') }
}),
new CompressionPlugin({
algorithm: 'gzip',
test: /\.(js)$|\.(css)$|\.(html)$|\.eot?.+$|\.ttf?.+$|\.woff?.+$|\.svg?.+$/,
//threshold: 10240,
//minRatio: 0
})
];
}
module.exports = config;
Does anyone know where is the problem? Thank you in advance!
I've found my answer! There is a config for webpack's optimization section which can be set and it gives us a sequential numbers as chunkFileName and its chunkIds which should set to natural. So:
config.optimization = {
chunkIds: "natural",
minimize: true,
minimizer: [new TerserPlugin()],
splitChunks: {
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
chunks: "all"
}
},
}
}
I've a React application with perfectly working SSR and Webpack code-splitting.
My webpack.config.js looks like this:
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ServerMiniCssExtractPlugin = require("./server/utils/serverMiniCssExtractPlugin");
module.exports = [{
name: 'react-app',
mode: 'development',
devtool: 'eval',
cache: true,
entry: {
main: [
'babel-polyfill',
'webpack-hot-middleware/client',
'./react/index.tsx',
],
},
output: {
path: `${__dirname}/dist/__build__`,
filename: '[name].js',
chunkFilename: '[name].js',
publicPath: '/__build__/',
},
module: {
rules: [{
test: /\.(ts|js)x?$/,
loader: 'babel-loader',
exclude: [/node_modules/],
}, {
test: /\.scss$/,
oneOf: [{
resourceQuery: /^\?raw$/,
use: [MiniCssExtractPlugin.loader, {
loader: 'css-loader',
options: {
modules: true,
sourceMap: true,
camelCase: false,
localIdentName: '[local]',
},
}, 'sass-loader', 'postcss-loader'],
}, {
use: [MiniCssExtractPlugin.loader, {
loader: 'css-loader',
options: {
modules: true,
sourceMap: true,
camelCase: true,
localIdentName: '[path]___[name]__[local]___[hash:base64:5]',
},
}, 'sass-loader', 'postcss-loader'],
}]
}],
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.DefinePlugin({
'process.env': {
CLIENT: JSON.stringify(true),
},
}),
new webpack.IgnorePlugin(/^vertx$/),
new MiniCssExtractPlugin({
filename: "style.css",
chunkFilename: "style.chunk.[id].css"
}),
],
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /node_modules/,
name: 'vendor',
enforce: true
},
},
},
},
}, {
name: 'server-side rendering',
mode: 'development',
devtool: 'eval',
cache: true,
entry: [
'./react/ssr.tsx',
],
target: 'node',
output: {
path: `${__dirname}/dist/__server__/`,
filename: 'ssr.js',
publicPath: '/__server__/',
libraryTarget: 'commonjs2',
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
},
module: {
rules: [{
test: /\.(ts|js)x?$/,
exclude: [/node_modules/, /.+\.config.js/],
loader: 'babel-loader',
}, {
test: /\.scss$/,
oneOf: [{
resourceQuery: /^\?raw$/,
use: [ServerMiniCssExtractPlugin.loader, {
loader: 'css-loader',
options: {
modules: true,
sourceMap: true,
camelCase: false,
localIdentName: '[local]',
},
}, 'sass-loader', 'postcss-loader'],
}, {
use: [ServerMiniCssExtractPlugin.loader, {
loader: 'css-loader',
options: {
modules: true,
sourceMap: true,
camelCase: true,
localIdentName: '[path]___[name]__[local]___[hash:base64:5]',
},
}, 'sass-loader', 'postcss-loader'],
}]
}],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.DefinePlugin({
'process.env': {
SERVER: JSON.stringify(true),
},
}),
new webpack.IgnorePlugin(/^vertx$/),
new ServerMiniCssExtractPlugin({
filename: "style.css",
chunkFilename: "style.chunk.[id].css"
}),
],
}];
... and it generates chunks for both js and css that using the app are loaded correctly when moving from the different pages, all mapped with react-router.
The problem is that when I reload one of the pages the needed css chunks are loaded once rendered and not linked directly in the page from the SSR, so for a second I have FOUC.
Since I would like using React-Helmet to inject in the page head the needed css chunks when I SSR the app how I can get in the code the list of chunks file names that are needed for the page that I reload?
Let say that the page needs:
0.js
2.js
style.chunk.0.css
style.chunk.2.css
How I can get the list of these files so I can generate dynamically the links in the page head?
Thanks.
Use the webpack-manifest-plugin to generate a manifest.json file that will include a list of all your chunks.
In your webpack.config.js:
var ManifestPlugin = require('webpack-manifest-plugin');
module.exports = {
// ...
plugins: [
new ManifestPlugin()
]
};
This will generate a manifest.json file in your root output directory with a mapping of all source file names to their corresponding output file, for example:
{
"mods/alpha.js": "mods/alpha.1234567890.js",
"mods/omega.js": "mods/omega.0987654321.js"
}
I tried to migrate to webpack from 3, I changed loaders to rules, changed System.import() to import(), upgraded all the packages, changed the ts loader from awesome-typescript-loader and removed the new webpack.NamedModulesPlugin() but during the build I have this error:
ERROR in ./node_modules/sql-parser/lib/compiled_parser.js
Module parse failed: Invalid labeled declaration (394:26)
You may need an appropriate loader to handle this file type.
| lstack.length = lstack.length - n;
| }
| _token_stack: function lex() {
| var token;
| token = lexer.lex() || EOF;
# ./node_modules/sql-parser/lib/parser.js 9:13-41
# ./node_modules/sql-parser/lib/sql_parser.js
# ./node_modules/sql-parser/index.js
# ./src/reducers/bands.js
# ./src/reducers/transients.js
# ./src/reducers/index.js
# ./src/main.js
# multi babel-polyfill ./src/main
How can I fix it?
EDIT
webpack.config.js
var path = require('path')
var webpack = require('webpack')
var paths = {
src: path.resolve(__dirname, '../src'),
test: path.resolve(__dirname, '../test'),
viewers: path.resolve(__dirname, '../src', 'components', 'viewers'),
vendor: path.resolve(__dirname, '../vendor'),
build: path.resolve(__dirname, '../build'),
dist: path.resolve(__dirname, '../dist'),
}
var config = {
entry: ['babel-polyfill', path.resolve(paths.src, 'main')],
output: {
path: paths.build,
pathinfo: true,
filename: 'js/[name].bundle.js',
chunkFilename: 'js/[id].bundle.js',
// publicPath: '/'
},
resolve: {
extensions: ['.js', '.json', '.jsx', '.ts', '.tsx'],
alias: {
'spread-view': path.resolve(paths.vendor, 'spread-view'),
spreadjs: path.resolve(paths.vendor, 'spreadjs'),
},
},
stats: {
colors: true,
reasons: true,
},
performance: {
hints: false,
},
module: {
rules: [
{
test: /\.ts|\.tsx$/,
include: [paths.src, paths.test],
use: 'ts-loader',
},
{
// enforce: 'pre',
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['es2015'],
},
},
],
// use: 'source-map-loader',
// include: [paths.src, paths.test],
},
{
test: /\.jsx?$/,
include: [paths.src, paths.test],
use: 'babel-loader',
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.json$/,
type: 'javascript/auto',
use: 'json-loader',
},
{
test: /\.yml$/,
type: 'javascript/auto',
use: ['json-loader', 'yaml-loader'],
},
{
test: /\.(cur|ico|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/,
exclude: /\/favicon.ico$/,
use: 'file-loader?name=media/[name].[hash:8].[ext]',
},
{
test: /\/favicon.ico$/,
include: paths.src,
use: 'file-loader?name=favicon.ico?[hash:8]',
},
{
test: /\.html$/,
use: 'html-loader?attrs=false', //link:href
},
// SQLite script loader
{
test: /\.sql$/,
use: 'sqlite-loader',
},
],
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
}),
// new webpack.NamedModulesPlugin(),
],
node: {
fs: 'empty',
net: 'empty',
tls: 'empty',
},
}
module.exports = {
paths: paths,
config: config,
}
webpack.config.debug.js
var webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var merge = require('webpack-merge')
var config = require('./webpack.config').config
module.exports = merge.smart(config, {
bail: true,
devtool: 'inline-source-map',
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('debug'),
},
}),
new HtmlWebpackPlugin({
inject: true,
template: 'index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
}),
],
})
Why my react app fails on production build after upgrading to react 16 ?
After upgrading react to version 16 my app stoped working on production build, when running development works fine. If I downgrade to React 15.6 it still works fine on both prod and dev enviroments.
I am using: "webpack": "^3.5.6", and "react": "^16.0.0",
I am getting the following error:
Uncaught ReferenceError: require is not defined
My webpack prod configuration:
const path = require('path');
const merge = require("webpack-merge");
const webpack = require("webpack");
const config = require("./webpack.base.babel");
const OfflinePlugin = require('offline-plugin');
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = merge(config, {
// devtool: "nosources-source-map",
devtool: "source-map",
// In production, we skip all hot-reloading stuff
entry: [
'babel-polyfill', // Needed for redux-saga es6 generator support
path.join(process.cwd(), 'src/client/app.js'), // Start with app.js
],
performance: {
assetFilter: (assetFilename) => !(/(\.map$)|(^(main\.|favicon\.))/.test(assetFilename)),
},
plugins: [
new webpack.LoaderOptionsPlugin({
minimize: true
}),
new HtmlWebpackPlugin({
template: "src/client/index.html",
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
inject: true,
}),
// Shared code
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
children: true,
minChunks: 2,
async: true,
}),
// Avoid publishing files when compilation fails
new webpack.NoEmitOnErrorsPlugin(),
// Put it in the end to capture all the HtmlWebpackPlugin's
// assets manipulations and do leak its manipulations to HtmlWebpackPlugin
new OfflinePlugin({
relativePaths: false,
publicPath: '/',
// No need to cache .htaccess. See http://mxs.is/googmp,
// this is applied before any match in `caches` section
excludes: ['.htaccess'],
caches: {
main: [':rest:'],
// All chunks marked as `additional`, loaded after main section
// and do not prevent SW to install. Change to `optional` if
// do not want them to be preloaded at all (cached only when first loaded)
additional: ['*.chunk.js'],
},
// Removes warning for about `additional` section usage
safeToUseOptionalCaches: true,
AppCache: false,
}),
]
});
How can i fix it ?
webpack.base.babel.js
// Common Webpack configuration used by webpack.config.development and webpack.config.production
const path = require("path");
const webpack = require("webpack");
const autoprefixer = require("autoprefixer");
const e2c = require("electron-to-chromium");
const GLOBALS = require('../bin/helpers/globals');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const isProd = process.env.NODE_ENV === 'production';
const postcssLoaderOptions = {
plugins: [
autoprefixer({
browsers: e2c.electronToBrowserList("1.4")
}),
],
sourceMap: !isProd,
};
GLOBALS['process.env'].__CLIENT__ = true;
module.exports = {
target: 'web', // Make web variables accessible to webpack, e.g. window
output: {
filename: 'js/[name].[hash].js',
chunkFilename: 'js/[name].[hash].chunk.js',
path: path.resolve(process.cwd(), 'build'),
publicPath: "/"
},
resolve: {
modules: ["node_modules"],
alias: {
client: path.resolve(process.cwd(), "src/client"),
shared: path.resolve(process.cwd(), "src/shared"),
server: path.resolve(process.cwd(), "src/server")
},
extensions: [".js", '.jsx', ".json", ".scss"],
mainFields: ["browser", "module", 'jsnext:main', "main"],
},
plugins: [
new webpack.NormalModuleReplacementPlugin(
/\/Bundles.js/,
'./AsyncBundles.js'
),
new webpack.IgnorePlugin(/vertx/),
new webpack.ProvidePlugin({
Promise: 'imports-loader?this=>global!exports-loader?global.Promise!es6-promise',
fetch: "imports-loader?this=>global!exports-loader?global.fetch!whatwg-fetch", // fetch API
$: "jquery",
jQuery: "jquery",
}),
new webpack.DefinePlugin(GLOBALS),
new ExtractTextPlugin({
filename: "css/[name].[hash].css",
disable: false,
allChunks: true
})
],
module: {
noParse: /\.min\.js$/,
rules: [
// JavaScript / ES6
{
test: /\.(js|jsx)?$/,
include: [
path.resolve(process.cwd(), "src/client"),
path.resolve(process.cwd(), "src/shared"),
],
exclude: /node_modules/,
use: "babel-loader"
},
// Json
{
test: /\.json$/,
use: 'json-loader',
},
//HTML
{
test: /\.html$/,
include: [
path.resolve(process.cwd(), "src/client"),
],
use: [
{
loader: "html-loader",
options: {
minimize: true
}
}
]
},
// Images
// Inline base64 URLs for <=8k images, direct URLs for the rest
{
test: /\.(png|jpg|jpeg|gif|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: "url-loader",
options: {
limit: 8192,
name: "images/[name].[ext]?[hash]"
}
}
},
// Fonts
{
test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
}
},
{
test: /\.(ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
use: 'file-loader'
},
// Styles
{
test: /\.scss$/,
include: [
path.resolve(process.cwd(), "src/client"),
path.resolve(process.cwd(), "src/shared"),
],
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [
{
loader: "css-loader",
options: {
sourceMap: true,
modules: true,
importLoaders: 1,
localIdentName: '[local]_[hash:base64:3]'
}
},
{
loader: "postcss-loader",
options: postcssLoaderOptions
},
{
loader: "sass-loader",
options: {
sourceMap: true,
outputStyle: "compressed"
}
}
]
})
},
]
}
};
The fix was rly simple.
I just needed to remove this line noParse: /\.min\.js/
Which does :
Prevent webpack from parsing any files matching the given regular
expression(s). Ignored files should not have calls to import, require,
define or any other importing mechanism.
I have tried endlessly to integrate a loader for React-Flexbox-Grid into my web pack config (shown below), but I receive error:
errors — client:119./~/flexboxgrid/dist/flexboxgrid.css
Module parse failed: /Users/---project-path---/node_modules/flexboxgrid/dist/flexboxgrid.css Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
This is the first time I have had to add in something like this, so I am not sure if I have been adding the 'include: /flexboxgrid/' in the correct place (I added it under the development/production rules), but it just returns the same error! Clearly what I am doing is wrong.
ps. I am using react-redux-webpack2-boilerplate
const webpack = require('webpack');
const path = require('path');
const DashboardPlugin = require('webpack-dashboard/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const autoprefixer = require('autoprefixer');
const nodeEnv = process.env.NODE_ENV || 'development';
const isProduction = nodeEnv === 'production';
const jsSourcePath = path.join(__dirname, './source');
const buildPath = path.join(__dirname, './build');
const imgPath = path.join(__dirname, './source/assets/img');
const sourcePath = path.join(__dirname, './source');
if (process.env.NODE_ENV == "production") {
var env = JSON.stringify(require("./production-env.js"));
} else {
var env = JSON.stringify(require("./development-env.js"));
}
// Common plugins
const plugins = [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity,
filename: 'vendor-[hash].js',
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(nodeEnv),
APPDATA: env,
},
}),
new webpack.NamedModulesPlugin(),
new HtmlWebpackPlugin({
template: path.join(sourcePath, 'index.html'),
path: buildPath,
filename: 'index.html',
}),
new webpack.LoaderOptionsPlugin({
options: {
postcss: [
autoprefixer({
browsers: [
'last 3 version',
'ie >= 10',
],
}),
],
context: sourcePath,
},
}),
];
// Common rules
const rules = [{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
'babel-loader',
],
},
{
test: /\.(png|gif|jpg|svg)$/,
include: imgPath,
use: 'url-loader?limit=20480&name=assets/[name]-[hash].[ext]',
},
];
if (isProduction) {
// Production plugins
plugins.push(
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false,
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
screw_ie8: true,
conditionals: true,
unused: true,
comparisons: true,
sequences: true,
dead_code: true,
evaluate: true,
if_return: true,
join_vars: true,
},
output: {
comments: false,
},
}),
new ExtractTextPlugin('style-[hash].css')
);
// Production rules
rules.push({
test: /\.scss$/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader!postcss-loader!sass-loader',
}),
});
} else {
// Development plugins
plugins.push(
new webpack.HotModuleReplacementPlugin(),
new DashboardPlugin()
);
// Development rules
rules.push({
test: /\.scss$/,
exclude: /node_modules/,
use: [
'style-loader',
// Using source maps breaks urls in the CSS loader
// https://github.com/webpack/css-loader/issues/232
// This comment solves it, but breaks testing from a local network
// https://github.com/webpack/css-loader/issues/232#issuecomment-240449998
// 'css-loader?sourceMap',
'css-loader',
'postcss-loader',
'sass-loader?sourceMap',
],
});
}
module.exports = {
devtool: isProduction ? 'eval' : 'source-map',
context: jsSourcePath,
entry: {
js: './index.js',
vendor: [
'babel-polyfill',
'es6-promise',
'immutable',
'isomorphic-fetch',
'react-dom',
'react-redux',
'react-router',
'react',
'redux-thunk',
'redux',
],
},
output: {
path: buildPath,
publicPath: '/',
filename: 'app-[hash].js',
},
module: {
rules,
},
resolve: {
extensions: ['.webpack-loader.js', '.web-loader.js', '.loader.js', '.js', '.jsx'],
modules: [
path.resolve(__dirname, 'node_modules'),
jsSourcePath,
],
},
plugins,
devServer: {
contentBase: isProduction ? './build' : './source',
historyApiFallback: true,
port: 3000,
compress: isProduction,
inline: !isProduction,
hot: !isProduction,
host: '0.0.0.0',
stats: {
assets: true,
children: false,
chunks: false,
hash: false,
modules: false,
publicPath: false,
timings: true,
version: false,
warnings: true,
colors: {
green: '\u001b[32m',
},
},
},
};
Its better to transform class properties.This kind of loader will help to solve this
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-0'],
plugins: ['react-html-attrs', 'transform-class-properties', 'transform-decorators-legacy'],
}
}