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,
},
}),
],
})
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"
}
},
}
}
This is my current bundle information which i got from bundle analyzer plugin,
Current bundle information
I want to move the jquery to a separate chunk and extract css into a separate single css bundle, is there any other optimization which i can do to reduce my bundle size?
My current webpack is this
webpack.base.js
/**
* COMMON WEBPACK CONFIGURATION
*/
const path = require('path');
const webpack = require('webpack');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
// const BundleAnalyzerPlugin = require('webpack-bundle-
analyzer').BundleAnalyzerPlugin;
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const autoprefixer = require('autoprefixer');
// Remove this line once the following warning goes away (it was meant
webpack loader authors not users):
// 'DeprecationWarning: loaderUtils.parseQuery() received a non-string
value which can be problematic,
be replaced with getOptions()
// in the next major version of loader-utils.'
process.noDeprecation = true;
const environment = require('../../environments/environment');
let publicDeployPath = '/';
const loaderOptions = {};
if (!environment.isLocal) {
publicDeployPath = environment.blobContainerPath;
loaderOptions.root = environment.blobContainerPath;
loaderOptions.minimize = true;
}
module.exports = (options) => ({
entry: options.entry,
output: Object.assign({ // Compile into js/build.js
path: path.resolve(process.cwd(), 'build'),
publicPath: publicDeployPath,
}, options.output), // Merge with env dependent settings
module: {
rules: [
{
test: /\.js$/, // Transform all .js files required somewhere with
Babel
use: {
loader: 'babel-loader',
options: options.babelQuery,
},
},
{
test: /\.jsx$/, // Transform all .js files required somewhere with
Babel
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: options.babelQuery,
},
},
{
// Preprocess our own .css files
// This is the place to add your own loaders (e.g. sass/less etc.)
test: /\.css$/,
// exclude: /node_modules/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [{
loader: 'css-loader',
options: loaderOptions,
}, {
loader: 'postcss-loader',
options: {
plugins: () => [autoprefixer()],
},
},
] }, true),
},
// {
// // Preprocess 3rd party .css files located in node_modules
// test: /\.css$/,
// include: /node_modules/,
// loader: ExtractTextPlugin.extract({
// fallback: 'style-loader',
// use: [{
// loader: 'css-loader',
// options: loaderOptions,
// },
// ] }, true),
// },
{
test: /\.mp3$/,
loader: 'url-loader?limit=10000&mimetype=audio/mpeg',
options: {
publicPath: publicDeployPath,
},
},
{
test: /\.(eot|svg|otf|ttf|woff|woff2)$/,
loader: 'file-loader',
options: {
publicPath: publicDeployPath,
},
},
{
test: /\.(jpg|png|gif)$/,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
publicPath: publicDeployPath,
progressive: true,
optimizationLevel: 7,
interlaced: false,
pngquant: {
quality: '65-90',
speed: 4,
},
},
},
],
},
{
test: /\.html$/,
use: 'html-loader',
},
{
test: /\.json$/,
use: 'json-loader',
},
{
test: /\.(mp4|webm)$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
},
},
},
],
},
plugins: options.plugins.concat([
new webpack.ProvidePlugin({
// make fetch available
fetch: 'exports-loader?self.fetch!whatwg-fetch',
}),
// new BundleAnalyzerPlugin(),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'root.jQuery': 'jquery',
}),
// Always expose NODE_ENV to webpack, in order to use
`process.env.NODE_ENV`
// inside your code for any environment checks; UglifyJS will
automatically
// drop any unreachable code.
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
},
}),
new AddAssetHtmlPlugin({ filepath: path.resolve(process.cwd(),
'app/vendor/VidyoConnector.js'), hash: true }),
new webpack.NamedModulesPlugin(),
]),
resolve: {
modules: ['app', 'node_modules'],
extensions: [
'.js',
'.jsx',
'.react.js',
],
mainFields: [
'browser',
'jsnext:main',
'main',
],
},
devtool: options.devtool,
target: 'web', // Make web variables accessible to webpack, e.g. window
performance: options.performance || {},
node: {
fs: 'empty',
},
});
webpack.production.js
// Important modules this config uses
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const pathsToClean = [
'build',
];
const cleanOptions = {
root: path.resolve(__dirname, '..'),
verbose: true,
dry: false,
allowExternal: true,
};
module.exports = require('./webpack.base.babel')({
// In production, we skip all hot-reloading stuff
entry: [
path.join(process.cwd(), 'app/app.js'),
],
// Utilize long-term caching by adding content hashes (not compilation hashes) to compiled assets
output: {
filename: '[name].[chunkhash].js',
chunkFilename: '[name].[chunkhash].chunk.js',
},
plugins: [
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'reactjs',
filename: 'reactjs.[chunkhash].js',
minChunks: (module) => (
// If module has a path, and inside of the path exists the name "somelib",
// and it is used in 3 separate chunks/entries, then break it out into
// a separate chunk with chunk keyname "my-single-lib-chunk", and filename "my-single-lib-chunk.js"
module.resource && (/react/).test(module.resource)
),
}),
new CleanWebpackPlugin(pathsToClean, cleanOptions),
new ExtractTextPlugin({ filename: 'style.[hash].css', disable: false, allChunks: true }),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'vendor.[chunkhash].js',
minChunks: (module) => (
// If module has a path, and inside of the path exists the name "somelib",
// and it is used in 3 separate chunks/entries, then break it out into
// a separate chunk with chunk keyname "my-single-lib-chunk", and filename "my-single-lib-chunk.js"
module.context && module.context.includes('node_modules')
),
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production'),
}),
// Minify and optimize the index.html
new HtmlWebpackPlugin({
template: 'app/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,
}),
new HtmlWebpackPlugin({ // Also generate a invalid page html
filename: 'ppVideoInvalid.html',
template: 'app/ppVideoInvalid.html',
}),
new HtmlWebpackPlugin({ // Generate a test client html
filename: 'testClient.html',
template: 'app/TestInterface/testClient.html',
}),
],
performance: {
assetFilter: (assetFilename) => !(/(\.map$)|(^(main\.|favicon\.))/.test(assetFilename)),
},
});
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/,
}
};
The error I get once and once again is this:
Uncaught (in promise) TypeError: Cannot read property 'call' of undefined
The same happened in three different machines, always with different files that fail.
When I trace the file that is breaking and I open it and save it webpack re compiles and the error disappears. I can trace it because in the call stack I find this where it fails:
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__base_base_icon__ = __webpack_require__(567);
In this case I know that is the base_icon.jsx file. It happens randomly with different files. There is some cache or something like that in webpack 2 that is producing this weird behavior?
This same project in Webpack 1 worked perfectly. This problem has appear since we migrated to Webpack 2.
My webpack configuration is the following:
var indexFile = '/index.html'
if (PROJECT) {
indexFile = '/projects/'+PROJECT+'/'+PROJECT+'_index.html'
}
const common = {
entry: {
main: ['babel-polyfill', path.join(__dirname, 'src/main.jsx')],
themes: ['babel-polyfill', path.join(__dirname, 'src/projects/themes/themes_main.jsx')],
common: [
//'bodymovin',
path.join(__dirname, 'src/animations/bodymovin'),
'check-types',
'classnames',
'moment',
'qs',
'react',
'react-addons-css-transition-group',
'react-addons-shallow-compare',
'react-addons-transition-group',
'react-css-modules',
'react-date-picker',
'react-dom',
'react-dropzone',
'react-redux',
'react-router',
'react-router-redux',
'redux',
'redux-form',
'redux-infinite-scroll',
'redux-saga',
'reselect',
'superagent',
'superagent-defaults',
'superagent-promise-plugin',
'react-intercom'
]
},
output: {
path: path.resolve(__dirname, 'build/assets'),
publicPath: publicPath,
filename: '[name].js'
},
resolve: {
modules: [path.resolve(__dirname, 'src'), path.resolve(__dirname, 'node_modules')],
extensions: ['.js', '.jsx'],
alias: {
config: 'config/'+config+'.js'
}
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]&sourceMap',
{
loader: 'postcss-loader',
options: {
plugins: function(webpack) {
return [
postcssImport,
precss,
hexrgba,
cssnext,
inlineSvg,
svgo,
math
]
}
}
}
]
})
},
{
test: /\.jsx?$/,
use: {
loader: 'babel-loader',
query: {
presets: ['react', ['es2015', {modules: false}], 'stage-0'],
compact: false
}
},
exclude: /node_modules/,
},
{
test: /\.(eot|ttf|woff|woff2)$/,
use: [
'file-loader?name=media/fonts/[name].[ext]'
]
},
{
test: /\.(png|gif|jpe?g|svg)$/i,
use: [
'file-loader?hash=sha512&digest=hex&name=media/image/[name]-[hash].[ext]'
]
},
{
test: /\.(webm|mp4)$/,
use: [
'file-loader?hash=sha512&digest=hex&name=media/video/[name]-[hash].[ext]'
]
}
]
}
}
const commonPlugins = [
new webpack.optimize.CommonsChunkPlugin(
{
name: ['common']
}
),
new ExtractTextPlugin({
filename: 'main.css'
})
]
if (TARGET === 'start' || !TARGET) {
module.exports = merge(common, {
plugins: [
...commonPlugins,
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin()
],
devtool: 'inline-source-map',
devServer: {
historyApiFallback: {
index: indexFile
},
hot: true,
inline: true,
stats: 'errors-only',
host: '0.0.0.0',
port: 8008,
watchOptions: {
ignored: /node_modules/,
aggregateTimeout: 300,
poll: 1000
},
disableHostCheck: true
},
})
}
if (TARGET === 'build') {
var exports = merge(common, {
plugins: [
...commonPlugins,
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
screw_ie8: true,
warnings: false,
comments: false,
mangle: true
}),
new CopyWebpackPlugin([
{ from: './src/assets/reset.css' }
])
]
})
fs.readFile('./src'+indexFile, function (err, data) {
if (err) throw err;
var newIndex = data.toString().replace(/\/assets\//g, publicPath)
fs.writeFile('./build/index.html', newIndex, function(err) {
if(err) {
return console.log(err);
}
})
})
console.log(util.inspect(exports, {showHidden: false, depth: null, colors: true}), '\n')
module.exports = exports
}
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'],
}
}