I am using react-hot-loader and webpack-hot-middleware with express for live reload but it is not working. webpack listens for the changes but is not shown on the browser. Have i missed something?
webpack-config.js
if (!process.env.NODE_ENV) {
process.env.NODE_ENV = 'development'
}
const isDevelopment = process.env.NODE_ENV === 'development';
const VENDOR_LIBS = [
'react', 'react-dom', 'redux', 'react-redux',
'react-router', 'react-router-redux', 'lodash',
'express'
];
const entryPath = path.join(__dirname, 'src/index.js');
const config = {
entry: {
bundle: isDevelopment ? [
'webpack-hot-middleware/client?reload=true',
'react-hot-loader/patch',
entryPath
] : entryPath,
vendor: isDevelopment ? [
'react-hot-loader/patch',
VENDOR_LIBS
] : VENDOR_LIBS,
},
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
filename: isDevelopment ? '[name].[hash].js' : '[name].[chunkhash].js',
},
devtool: 'source-map',
module: {
rules: [
{
loader: ExtractTextPlugin.extract({
loader: 'css-loader'
}),
test: /\.css$/,
},
{
use: ['babel-loader'],
test: /\.js$/,
exclude: /node_modules/,
},
],
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify(isDevelopment ? 'development' : 'production')
}
}),
new HtmlWebpackPlugin({
inject: true,
template: 'src/index.html',
minify: {
removeComments: false,
collapseWhitespace: false,
}
}),
new ExtractTextPlugin('style.css'),
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest']
}),
],
};
isDevelopment && config.plugins.push(new webpack.HotModuleReplacementPlugin());
!isDevelopment && config.plugins.push(
new webpack.optimize.AggressiveMergingPlugin(),
new webpack.optimize.UglifyJsPlugin({
output: {
comments: false,
screw_ie8: true
},
})
);
module.exports = config;
package.json
"scripts": {
"pre-start": "webpack",
"start-dev": "node server.js --development",
"start-prod": "rimraf dist && webpack && node server.js --production"
},
server.js
if (process.env.NODE_ENV !== 'production') {
console.log('DEVOLOPMENT ENVIRONMENT: Turning on WebPack Middleware...');
const webpack = require('webpack');
const webpackConfig = require('./webpack.config');
const compiler = webpack(webpackConfig);
app.use(require('webpack-dev-middleware')(compiler, {
noInfo: true,
hot: true,
historyApiFallback: true,
publicPath: webpackConfig.output.publicPath,
contentBase: './dist/',
stats: {
colors: true,
'errors-only': true
}
}));
app.use(require('webpack-hot-middleware')(compiler));
} else {
app.use(express.static(__dirname + '/dist'));
}
app.get('*', function (request, response) {
response.sendFile(__dirname + '/dist/index.html');
});
app.listen(port);
console.log(`server started on port: ${port}`);
I am not sure, but, is it problem due to chunkhash?
UPDATE
index.js
ReactDOM.render(
<AppContainer>
<Root store={store} history={history} />
</AppContainer>
, document.querySelector('#app'));
if (module.hot) {
module.hot.accept('./components/root', () => {
ReactDOM.render(
<AppContainer>
<Root store={store} history={history} />
</AppContainer>
, document.querySelector('#app'));
});
}
Related
I decided to give webpack a shot and am using a starter kit for a small project. I'm not sure where I am going wrong but I want to add a new directory of files and access them like any other build.In this case it is the folder "particles.js-master". When I add a directory I cannot seem to access anything in the folder. I'm assuming I have to add an output or the like to the webpack config? Any advice would be greatly appreciated, thanks :)
here is my project structure
webpack:
const path = require('path');
const webpack = require('webpack');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const PreloadWebpackPlugin = require('preload-webpack-plugin');
const CssUrlRelativePlugin = require('css-url-relative-plugin');
const glob = require('glob');
const IS_DEV = process.env.NODE_ENV === 'dev';
const config = {
mode: IS_DEV ? 'development' : 'production',
devtool: IS_DEV ? 'eval' : 'source-map',
entry: './src/js/index.js',
output: {
filename: 'js/[name].[hash].js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.scss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: IS_DEV,
},
},
'css-loader',
'sass-loader',
],
},
{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
name: '[name].[ext]',
fallback: 'file-loader',
outputPath: 'public/images',
},
},
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65,
},
pngquant: {
quality: '65-90',
speed: 4,
},
gifsicle: {
interlaced: false,
},
webp: {
quality: 75,
},
},
},
],
},
],
},
plugins: [
new CleanWebpackPlugin(),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'windows.jQuery': 'jquery',
}),
new CopyWebpackPlugin([
{
from: './src/public',
to: 'public',
},
]),
new MiniCssExtractPlugin({
filename: IS_DEV ? 'css/[name].css' : 'css/[name].[contenthash].css',
chunkFilename: 'css/[id].css',
}),
new webpack.HashedModuleIdsPlugin(),
new PreloadWebpackPlugin({
include: 'initial',
}),
new CssUrlRelativePlugin(),
],
devServer: {
contentBase: path.join(__dirname, 'src'),
},
optimization: {
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /node_modules/,
chunks: 'initial',
name: 'vendor',
priority: 10,
enforce: true,
},
},
},
minimizer: [],
},
};
if (!IS_DEV) {
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
config.optimization.minimizer.push(
new TerserPlugin(),
new OptimizeCSSAssetsPlugin({})
);
}
const files = glob.sync('./src/*.html');
files.forEach(file => {
config.plugins.push(
new HtmlWebPackPlugin({
filename: path.basename(file),
template: file,
favicon: path.resolve(__dirname, './src/public/icon.ico'),
minify: !IS_DEV,
})
);
});
module.exports = config;
My project is using 3 webpack files (one common, and two for dev/prod env) and .babelrc file for babel config
.babelrc
{
"presets": ["#babel/preset-env"],
"plugins": ["angularjs-annotate"]
}
webpack.common.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const webpack = require("webpack");
const WebpackBar = require('webpackbar');
const pathPublic = "/public/path/";
const pathFonts = "/fonts/";
module.exports = {
devtool: "eval",
entry: {
app: "./src/js/app.index.js",
},
module: {
rules: [{
test: /\.(gif|png|jpe?g)$/i,
use: ["file-loader"],
}, {
test: /\.(woff|woff2|ttf|eot|svg|otf)(\?v=\d+\.\d+\.\d+)?$/,
use: [{
loader: 'file-loader',
options: {
publicPath: pathPublic + pathFonts,
name: "[name].[ext]",
outputPath: pathFonts,
chunks: true
}
}]
}, {
test: /\.css$/,
use: [
{loader: "style-loader"},
{loader: MiniCssExtractPlugin.loader},
{loader: "css-loader"}
]
}, {
test: /\.scss$/,
use: [
{loader: "style-loader"},
{loader: MiniCssExtractPlugin.loader},
{loader: "css-loader"},
{loader: "sass-loader"}
]
}, {
test: /\.less$/,
use: [
{loader: "style-loader"},
{loader: MiniCssExtractPlugin.loader, options: {publicPath: pathPublic}},
{loader: "css-loader"},
{loader: "less-loader"}
]
}]
},
plugins: [
new WebpackBar(),
new CleanWebpackPlugin(["frontend/dist", "static/"], {root: __dirname + "/.."}),
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({
collapseWhitespace: false,
template: path.join(__dirname, "src/assets/html/index.proto.html"),
title: 'SC app front page',
inject: "html",
hash: true
}),
new ScriptExtHtmlWebpackPlugin({defaultAttribute: "defer"}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
}),
new MiniCssExtractPlugin({
filename: "styles.min.css",
})
],
stats: {
children: false,
colors: true
},
};
webpack.prod.js
const merge = require('webpack-merge');
const common = require('./webpack.common');
const path = require('path');
const pathDist = path.resolve(__dirname, "dist");
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = merge(common, {
mode: "production",
output: {
filename: "[name].min.js",
publicPath: "/public/path/",
chunkFilename: "npm.[id].[chunkhash].min.js",
path: pathDist
},
optimization: {
runtimeChunk: "single",
minimizer: [
new UglifyJsPlugin({
sourceMap: false,
uglifyOptions: {
compress: true,
output: {comments: false},
}
}),
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.(css|sass|scss|less)$/g,
cssProcessor: require("cssnano")({
safe: true,
normalizeWhitespaces: true,
discardDuplicates: true,
discardComments: {
removeAll: true,
}
})
})
],
splitChunks: {
chunks: "all",
maxInitialRequests: Infinity,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
maxSize: 249856, // 244 KiB Webpack recommended size
},
}
},
}
});
webpack.dev.js
const merge = require('webpack-merge');
const common = require('./webpack.common');
const path = require('path');
const pathDist = path.resolve(__dirname, "dist");
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = merge(common, {
mode: "development",
devtool: "inline-source-map",
output: {
filename: "[name].min.js",
publicPath: "/public/path/",
chunkFilename: "npm.[id].[chunkhash].min.js",
path: pathDist
},
optimization: {
minimizer: [
new UglifyJsPlugin({
sourceMap: true,
uglifyOptions: {
compress: true,
output: {comments: false}
}
}),
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.(css|sass|scss|less)$/g,
cssProcessor: require("cssnano")({
safe: true,
normalizeWhitespaces: true,
discardDuplicates: true,
discardComments: {
removeAll: true,
},
})
})
]
},
devServer: {
contentBase: pathDist
}
});
the problem is that when i do dev build, es6 class names remains unchanged, but when i do prod build, es6 class names changes and this will crush angularjs DI process.
EXAMPLE:
Let's say there is 2 classes (one service and one controller)
/**
* build-dev: MyService.prototype.constructor.name = "MyService"
* build-prod: MyService.prototype.constructor.name = "MyService__MyService"
*/
class MyService {
serviceMethod() {
// DO STUFF
}
}
/**
* build-dev: MyCtrl.prototype.constructor.name = "MyCtrl"
* build-prod: MyCtrl.prototype.constructor.name = "MyCtrl__MyCtrl"
*/
class MyCtrl {
constructor(MyService) {
this.MyService = MyService;
}
ctrlMethod() {
this.MyService.serviceMethod()
}
}
and those classes are registered with angularjs DI this way
angular.module("MyApp")
.controller(MyCtrl.prototype.constructor.name, MyCtrl)
.service(MyService.prototype.constructor.name, MyService)
now pay attention at class annotations (build-dev, build-prod)
I've integrated PostCSS into Webpack, using a separate postcss.config.js file.
I want to enable cssnano when doing production builds, and disable it for development builds. How can I do this?
Here is my webpack.config.js
const webpack = require('webpack');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const path = require('path');
module.exports = (env, argv) =>
{
//const isProduction = (process.env.WEBPACK_MODE === 'production')
const isProduction = argv.mode === 'production' || process.env.NODE_ENV === 'production';
const config = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
chunkFilename: '[name].[contenthash].js'
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
// fallback to style-loader in development
//process.env.NODE_ENV !== 'production' ? 'style-loader' : MiniCssExtractPlugin.loader,
{
loader: MiniCssExtractPlugin.loader,
options: {
sourceMap: true
}
},
//'css-loader?-url',
{
loader: 'css-loader',
options: {
minimize: true,
sourceMap: true,
url: false
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
{
loader: 'resolve-url-loader',
options: {
sourceMap: true,
debug: false
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
outputStyle: 'compressed',
sourceMapContents: false
}
}
]
}
]
},
plugins: [
new CleanWebpackPlugin('dist', {
watch: true
}),
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: isProduction ? "live.[contenthash].css" : "live.css",
chunkFilename: "[name].[contenthash].css"
}),
new ManifestPlugin()
]
}
return config;
}
Here is my postcss.config.js
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-url'),
require('autoprefixer'),
require('cssnano')({
preset: 'default',
})
]
}
Secondly, is a separate postcss.config.js recommended? I see some examples where the PostCSS plugins are defined in webpack.config.js, and others where it's all done in the separate file.
Option 1. Use webpack merge
With webpack-merge, you can create conditional configurations based on the NODE_ENV and merge them in one single configuration at execution time, the advantage is that you don't create duplication of code and everything can be done in one file, the only disadvantage is using a new package.
const ENV = process.env.NODE_ENV
let Config = {
//Other shared configurations by production and development
plugins: [
new webpack.ProgressPlugin(),
new CopyWebpackPlugin([
{ from: 'public', to: 'public' },
])
]
}
if (ENV === 'production') {
Config = merge(Config, {
plugins: [
new MiniCssExtractPlugin({
filename: "public/styles.css"
}),
new OptimizeCSSAssetsPlugin({
cssProcessor: cssnano,
cssProcessorOptions: {
parser: safe,
discardComments: { removeAll: true }
}
})
],
mode: 'production'
})
}
if (ENV === 'development') {
Config = merge(Config, {
devtool: 'source-map',
mode: 'development',
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new StyleLintPlugin(
{
emitErrors: false,
configFile: '.stylelintrc',
context: 'src',
files: '**/*.pcss',
},
),
]
})
}
const WebpackConfig = Config
Option 2. Use different configurations
Two separated files webpack.config.prod.js and webpack.config.dev.js can be created and call them with different npm scripts. The problem with this solution is that there is a duplication of code.
In your postcss.config.js you can do checking for the environment property:
module.exports = ({ env }) => ({
plugins: [
require('postcss-import')(),
require('postcss-url')(),
require('autoprefixer')(),
env === 'production' ? require('cssnano')({preset: 'default' })() : false,
]
})
I can't build a project with webpack because I'm getting a syntax error all the time.
Moreover when my friend runs the same code on Linux (I work on Windows 10) he doesn't get any errors and everything works fine.
Here is my webpack config
const path = require('path');
const autoprefixer = require('autoprefixer');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackMd5Hash = require('webpack-md5-hash');
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const HMRPlugin = require('webpack/lib/HotModuleReplacementPlugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
const NamedModulesPlugin = require('webpack/lib/NamedModulesPlugin');
const OccurrenceOrderPlugin = require('webpack/lib/optimize/OccurrenceOrderPlugin');
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
//=========================================================
// VARS
//---------------------------------------------------------
const NODE_ENV = process.env.NODE_ENV;
const DEVELOPMENT = NODE_ENV === 'development';
const PRODUCTION = NODE_ENV === 'production';
const HOST = process.env.HOST || '127.0.0.1';
const PORT = process.env.PORT || '3000';
//=========================================================
// LOADERS
//---------------------------------------------------------
const rules = {
js: {
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
json: {
test: /\.json$/,
loader: 'json-loader',
},
css: {
test: /\.css$/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'resolve-url-loader', 'postcss-loader'],
}),
},
scss: {
test: /\.scss$/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'resolve-url-loader', 'postcss-loader', 'sass-loader'],
}),
},
fonts: {
test: /\.(eot|svg|ttf|woff|woff2)$/,
loader: 'file-loader',
query: {
name: `[name].[ext]`,
publicPath: '/assets/fonts/',
}
},
images: {
test: /\.(svg|png|jpg|jpeg|gif)$/,
loader: 'file-loader',
query: {
limit: 10000,
name: `[name].[ext]`,
publicPath: '/assets/images/',
}
}
};
//=========================================================
// CONFIG
//---------------------------------------------------------
const config = {};
config.entry = {
polyfills: './src/application/polyfills.js',
main: ['./src/application/index.js'],
};
config.output = {
filename: 'assets/js/[name].js',
path: path.resolve('./dist'),
// publicPath: '/',
};
config.resolve = {
extensions: ['.js', '.json'],
modules: [
path.resolve('./src'),
'node_modules',
]
};
config.module = {
rules: [
rules.js,
rules.css,
rules.json,
rules.scss,
rules.fonts,
rules.images,
]
};
config.plugins = [
new LoaderOptionsPlugin({
debug: !PRODUCTION,
cache: !PRODUCTION,
minimize: PRODUCTION,
options: {
postcss: [
autoprefixer({
browsers: ['last 3 versions'],
})
],
sassLoader: {
outputStyle: PRODUCTION ? 'compressed' : 'expanded',
precision: 10,
sourceComments: false,
sourceMap: PRODUCTION,
}
}
}),
new DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(NODE_ENV),
}),
new OccurrenceOrderPlugin(true),
new NamedModulesPlugin(),
new CommonsChunkPlugin({
name: 'polyfills',
chunks: ['polyfills'],
}),
// This enables tree shaking of the vendors modules
new CommonsChunkPlugin({
name: 'vendor',
chunks: ['main'],
minChunks: module => /node_modules/.test(module.resource),
}),
new CommonsChunkPlugin({
name: ['polyfills', 'vendor'].reverse(),
}),
new CopyWebpackPlugin([
{
from: './src/assets',
to: 'assets',
ignore: ['**/*.scss'],
}
]),
new ExtractTextPlugin({
filename: 'assets/css/[name].css',
disable: !PRODUCTION,
allChunks: true,
}),
new HtmlWebpackPlugin({
filename: 'index.html',
hash: false,
inject: 'body',
chunksSortMode: 'dependency',
template: './src/index.html',
})
];
//=====================================
// DEVELOPMENT
//-------------------------------------
if (DEVELOPMENT) {
config.devtool = 'cheap-module-source-map';
config.entry.main.unshift(
'react-hot-loader/patch',
`webpack-dev-server/client?http://${HOST}:${PORT}`,
'webpack/hot/only-dev-server',
);
config.plugins.push(
new HMRPlugin(),
new ProgressPlugin(),
);
config.devServer = {
contentBase: path.resolve(__dirname, 'dist'),
historyApiFallback: true,
host: HOST,
hot: true,
port: PORT,
stats: {
cached: true,
cachedAssets: true,
children: false,
chunks: false,
chunkModules: false,
colors: true,
modules: false,
hash: false,
reasons: true,
timings: true,
version: false,
}
};
}
//=====================================
// PRODUCTION
//-------------------------------------
if (PRODUCTION) {
config.devtool = 'hidden-source-map';
config.plugins.push(
new WebpackMd5Hash(),
new UglifyJsPlugin({
comments: false,
compress: {
unused: true,
dead_code: true,
screw_ie8: true,
warnings: false,
},
mangle: {
screw_ie8: true,
}
})
);
}
module.exports = config;
And this is my package.json scripts
"scripts": {
"test": "jest",
"server:dev": "set NODE_ENV='development' && webpack-dev-server --color",
"start": "npm run server:dev",
"build": "set NODE_ENV='production' && webpack --color"
},
When I try to run "npm start", I have this error
C:\Users\vellgreen\Desktop\my_webpack_react\webpack.config.js:184
);
^
SyntaxError: Unexpected token )
when I put this into comment everything is working normal.
config.entry.main.unshift(
'react-hot-loader/patch',
`webpack-dev-server/client?http://${HOST}:${PORT}`,
'webpack/hot/only-dev-server',
);
config.plugins.push(
new HMRPlugin(),
new ProgressPlugin(),
);
When I run code for production everything is also fine.
My OS is Windows 10, webpack v3.1.0, npm v5.3.0, node v6.10.3.
Does anyone know what may cause such an error?
Trailing commas in functions are a relatively recent feature and Node started supporting it in version 8. Your friend is simply using a version that supports it (it's unrelated to the OS).
config.entry.main.unshift(
'react-hot-loader/patch',
`webpack-dev-server/client?http://${HOST}:${PORT}`,
'webpack/hot/only-dev-server',
// ^ --- remove this comma
);
config.plugins.push(
new HMRPlugin(),
new ProgressPlugin(),
// ^ --- and this comma
);
I need to do code splitting and load some React component and other script on-demand, I simply do it like:
<Route path="/journal" getComponent={function (nextState, cb) {
require.ensure([], function (require) {
cb(null, require("./components/Journal"));
})
}} />
In development, just run webpack it works just fine.
But for production build, I run webpack -p, then I always get error:
Uncaught TypeError: Cannot read property 'call' of undefined
at e (bootstrap a99e046…:50)
line 50 is:
// Execute the module function
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
What could be the issue ?
My webpack config:
var webpack = require('webpack');
var merge = require('webpack-merge');
var validate = require('webpack-validator');
var parts = require('./webpack.parts');
var common = {
entry: {
vendor: ['react', 'react-dom', 'lodash'],
},
output: {
filename: "index.bundle.js",
path: __dirname + '/public/js/',
publicPath: __dirname + '/public/js/'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
minChunks: 3,
filename: "vendor.bundle.js"
})
]
};
var config;
switch(process.env.npm_lifecycle_event) {
case 'build':
config = merge(common,
{
devtool: 'source-map',
entry: {
app: [ __dirname + '/src/index.js']
},
module: {
loaders: [
{test: /\.js$/, exclude: /node_modules/, loaders: ["babel-loader"]}
]
}
},
parts.productionOptimize()
);
break;
default:
config = merge(
common,
{
devtool: 'eval-source-map',
entry: {
app: ['webpack-hot-middleware/client', __dirname + '/src/index.js']
},
module: {
loaders: [
{test: /\.js$/, exclude: /node_modules/, loaders: ["react-hot","babel-loader"]}
]
}
},
parts.devServer({
host: process.env.HOST,
port: process.env.PORT
})
);
}
module.exports = validate(config);
webpack.parts.js
var webpack = require('webpack');
exports.devServer = function(options) {
return {
devServer: {
historyApiFallback: true,
inline: true,
hot: true,
stats: 'errors-only',
host: options.host,
port: options.port
},
plugins: [
new webpack.HotModuleReplacementPlugin({
multistep: true
})
]
};
}
exports.productionOptimize = function () {
return {
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production')
}
}),
new webpack.optimize.UglifyJsPlugin()
]
}
}
I did it wrong, publicPath should not be absolute:
I change
publicPath: __dirname + '/public/js/'
to
publicPath: '/js/'