webpack-contrib / webpack-hot-middleware

Webpack hot reloading you can attach to your own server
MIT License
2.34k stars 297 forks source link

Unexpected Token error when trying to hot load #84

Closed VasilyShelkov closed 8 years ago

VasilyShelkov commented 8 years ago

I have checked out the ultimate-hot-reloading-examples and played about with the configurations but nothing has been working. Appreciate anyone who can put some time to try and figure out the issue :) I feel like it's some stupid issue and I've just been looking at this all for too long.

Could really do with someone with some fresh eyes and suggestions to look over this. Have been banging my head getting hot loading working despite having it working in pure front-end application over with this error:

ERROR in ./src/client/index.js
Module parse failed: /home/vasily/Programming/solid-octo-disco/src/client/index.js Line 1: Unexpected token
You may need an appropriate loader to handle this file type.
| import ReactDOM from 'react-dom';
| import React from 'react';
| import App from './App';
 @ multi main

The applications workflow is gulp run which uses nodeman and build-watches the project files:

gulp.task('build', function(done) {
  webpack(webpackConfig).run(onBuild(done));
});

gulp.task('build-watch', ['build'], function() {
  webpack(webpackConfig).watch(100, function(err, stats) {
    onBuild()(err, stats);
    nodemon.restart();
  });
});

gulp.task('run', ['build-watch'], function() {
  nodemon({
    execMap: {
      js: 'node',
    },
    script: path.join(__dirname, 'build/server'),
    ignore: ['*'],
    ext: 'js',
  }).on('restart', function() {
    console.log('Reloading Nodemon');
  });
});

The webpack config has hotloading if NODE_ENV !== 'production' ie 'development is:

const path = require('path');
var fs = require('fs');
const webpack = require('webpack');
const extend = require('extend');

const production = process.env.NODE_ENV === 'production' ? true : false;

//
// Common configuration chunk to be used for both
// client-side (client.js) and server-side (server.js) bundles
// -----------------------------------------------------------------------------
const config = {
  module: {
    loaders: [
      {
        test: /\.js$/,
        loaders: ['babel'],
        include: path.join(__dirname, 'src'),
      }
    ]
  },
  debug: !production,
  resolve: {
    extensions: ['', '.js', '.jsx']
  },
}

// Calculate external dependencies for Webpack. Webpack searches for these
// packages in the node_modules instead of packing them into the bundle.
var nodeModules = {};
fs.readdirSync('node_modules')
  .forEach(function(mod) {
    if (mod !== '.bin') {
      nodeModules[mod] = 'commonjs ' + mod;
    }
  });

//
// Configuration for the server-side bundle (server.js)
// -----------------------------------------------------------------------------
const serverConfig = extend(true, {}, config, {
  entry: './src/server/server.js',
  target: 'node',
  output: {
    path: path.join(__dirname, 'build'),
    filename: 'server.js',
  },
  node: {
    __dirname: true,
    __filename: true,
  },
  externals: nodeModules,
  plugins: [],
});

//
// Configuration for the client-side bundle (client.js)
// -----------------------------------------------------------------------------
const clientConfig = extend(true, {}, config, {
  entry: production ? './src/client/index.js' : 
  [
    'eventsource-polyfill', //necessary evil for hot loading with IE
    'webpack-hot-middleware/client',
    './src/client/index.js'
  ],
  output: {
    path: path.join(__dirname, 'public'),
    filename: 'bundle.js',
    publicPath: '/public/',
  },
  plugins: production ? [
      new webpack.optimize.DedupePlugin(),
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
          screw_ie8: true,

          // jscs:enable requireCamelCaseOrUpperCaseIdentifiers
          warnings: false,
        },
      }),
      new webpack.optimize.AggressiveMergingPlugin(),
    ] : [
      new webpack.optimize.OccurenceOrderPlugin(),
      new webpack.HotModuleReplacementPlugin(),
      new webpack.NoErrorsPlugin()
    ]
});

module.exports = [ serverConfig, clientConfig ];

and have a .babelrc file for transpiling from es6->es5.

{
  "presets": ["react", "es2015", "stage-2"],
  "env": {
    "development": {
      "presets": ["react-hmre"]
    }
  }
}

When I change the index.js file and App.js to es5 syntax I get this error instead:

ERROR in ./src/client/index.js
Module parse failed: /home/vasily/Programming/solid-octo-disco/src/client/index.js Line 5: Unexpected token <
You may need an appropriate loader to handle this file type.
| var App = require('./App');
| 
| ReactDOM.render(<App />, document.getElementById('app'));
| 
 @ multi main

My server uses the webpack-dev-middleware/webpack-hot-middleware only when not in production:

import express from 'express';
import path from 'path';
import webpack from 'webpack';
import clientConfig from '../../webpack.config.js';
import 'babel-register';

const app = express();
const port = process.env.PORT || 3000;

console.log(clientConfig[1]);
//In development hotload React using webpack-hot-middleware
if (!(process.env.NODE_ENV === 'production')){
    const compiler = webpack(clientConfig[1]);

    app.use(require('webpack-dev-middleware')(compiler, {
      noInfo: true,
      publicPath: clientConfig[1].output.publicPath
    }));

    app.use(require('webpack-hot-middleware')(compiler, {
        log: console.log
    }));
}
//--------------------------------------------------------------------------

app.use('/public', express.static('public'));

app.get('*', (req, res) => {
  res.sendFile('index.html', { root: 'public' });
});

// Listen on port 3000, IP defaults to 127.0.0.1 (localhost)
app.listen(port, (err) => {
  if (err) {
    console.log(err);
    return;
  }

  console.log('Server running at http://localhost: ' + port);
});

and lastly my installed packages and in package.json:

"dependencies": {
    "express": "^4.13.4",
    "extend": "^3.0.0",
    "react": "^0.14.7",
    "react-dom": "^0.14.7"
  },
  "devDependencies": {
    "babel-cli": "^6.6.4",
    "babel-core": "^6.5.2",
    "babel-eslint": "^5.0.0",
    "babel-loader": "^6.2.4",
    "babel-preset-es2015": "^6.5.0",
    "babel-preset-react": "^6.5.0",
    "babel-preset-react-hmre": "^1.1.0",
    "babel-preset-stage-2": "^6.5.0",
    "babel-register": "^6.6.0",
    "babel-runtime": "^6.6.1",
    "chai": "^3.5.0",
    "codacy-coverage": "^1.1.3",
    "coveralls": "^2.11.8",
    "eslint": "^2.2.0",
    "eslint-config-airbnb": "^6.0.2",
    "eslint-plugin-babel": "^3.1.0",
    "eslint-plugin-react": "^4.1.0",
    "eventsource-polyfill": "^0.9.6",
    "gulp": "^3.9.1",
    "istanbul": "^0.4.2",
    "jscs": "^2.11.0",
    "mocha": "^2.4.5",
    "mocha-lcov-reporter": "^1.2.0",
    "nodemon": "^1.9.1",
    "webpack": "^1.12.14",
    "webpack-dev-middleware": "^1.5.1",
    "webpack-hot-middleware": "^2.9.1"
  }
glenjamin commented 8 years ago

The problem is almost certainly with the loaders section of the webpack config.

Do you get the same error if you use the webpack CLI with that config?

Maybe try dumping out the merged config to see if it looks as you'd expect. Other than that, study the webpack docs on loader config carefully - the main difference I can see is that you have "loaders" instead of "loader"

On 4 Mar 2016, at 22:42, Vasily Shelkov notifications@github.com wrote:

I have checked out the ultimate-hot-reloading-examples and played about with the configurations but nothing has been working. Appreciate anyone who can put some time to try and figure out the issue :) I feel like it's some stupid issue and I've just been looking at this all for too long.

Could really do with someone with some fresh eyes and suggestions to look over this. Have been banging my head getting hot loading working despite having it working in pure front-end application over with this error:

ERROR in ./src/client/index.js Module parse failed: /home/vasily/Programming/solid-octo-disco/src/client/index.js Line 1: Unexpected token You may need an appropriate loader to handle this file type. | import ReactDOM from 'react-dom'; | import React from 'react'; | import App from './App'; @ multi main The applications workflow is gulp run which uses nodeman and build-watches the project files:

gulp.task('build', function(done) { webpack(webpackConfig).run(onBuild(done)); });

gulp.task('build-watch', ['build'], function() { webpack(webpackConfig).watch(100, function(err, stats) { onBuild()(err, stats); nodemon.restart(); }); });

gulp.task('run', ['build-watch'], function() { nodemon({ execMap: { js: 'node', }, script: path.join(__dirname, 'build/server'), ignore: ['*'], ext: 'js', }).on('restart', function() { console.log('Reloading Nodemon'); }); }); The webpack config has hotloading if NODE_ENV !== 'production' ie 'development is:

const path = require('path'); var fs = require('fs'); const webpack = require('webpack'); const extend = require('extend');

const production = process.env.NODE_ENV === 'production' ? true : false;

// // Common configuration chunk to be used for both // client-side (client.js) and server-side (server.js) bundles // ----------------------------------------------------------------------------- const config = { module: { loaders: [ { test: /.js$/, loaders: ['babel'], include: path.join(__dirname, 'src'), } ] }, debug: !production, resolve: { extensions: ['', '.js', '.jsx'] }, }

// Calculate external dependencies for Webpack. Webpack searches for these // packages in the node_modules instead of packing them into the bundle. var nodeModules = {}; fs.readdirSync('node_modules') .forEach(function(mod) { if (mod !== '.bin') { nodeModules[mod] = 'commonjs ' + mod; } });

// // Configuration for the server-side bundle (server.js) // ----------------------------------------------------------------------------- const serverConfig = extend(true, {}, config, { entry: './src/server/server.js', target: 'node', output: { path: path.join(dirname, 'build'), filename: 'server.js', }, node: { dirname: true, __filename: true, }, externals: nodeModules, plugins: [], });

// // Configuration for the client-side bundle (client.js) // ----------------------------------------------------------------------------- const clientConfig = extend(true, {}, config, { entry: production ? './src/client/index.js' : [ 'eventsource-polyfill', //necessary evil for hot loading with IE 'webpack-hot-middleware/client', './src/client/index.js' ], output: { path: path.join(__dirname, 'public'), filename: 'bundle.js', publicPath: '/public/', }, plugins: production ? [ new webpack.optimize.DedupePlugin(), new webpack.optimize.UglifyJsPlugin({ compress: { // jscs:disable requireCamelCaseOrUpperCaseIdentifiers screw_ie8: true,

      // jscs:enable requireCamelCaseOrUpperCaseIdentifiers
      warnings: false,
    },
  }),
  new webpack.optimize.AggressiveMergingPlugin(),
] : [
  new webpack.optimize.OccurenceOrderPlugin(),
  new webpack.HotModuleReplacementPlugin(),
  new webpack.NoErrorsPlugin()
]

});

module.exports = [ serverConfig, clientConfig ]; and have a .babelrc file for transpiling from es6->es5.

{ "presets": ["react", "es2015", "stage-2"], "env": { "development": { "presets": ["react-hmre"] } } } When I change the index.js file and App.js to es5 syntax I get this error instead:

ERROR in ./src/client/index.js Module parse failed: /home/vasily/Programming/solid-octo-disco/src/client/index.js Line 5: Unexpected token < You may need an appropriate loader to handle this file type. var App = require('./App');
ReactDOM.render(, document.getElementById('app'));

@ multi main My server uses the webpack-dev-middleware/webpack-hot-middleware only when not in production:

import express from 'express'; import path from 'path'; import webpack from 'webpack'; import clientConfig from '../../webpack.config.js'; import 'babel-register';

const app = express(); const port = process.env.PORT || 3000;

console.log(clientConfig[1]); //In development hotload React using webpack-hot-middleware if (!(process.env.NODE_ENV === 'production')){ const compiler = webpack(clientConfig[1]);

app.use(require('webpack-dev-middleware')(compiler, {
  noInfo: true,
  publicPath: clientConfig[1].output.publicPath
}));

app.use(require('webpack-hot-middleware')(compiler, {
    log: console.log
}));

} //--------------------------------------------------------------------------

app.use('/public', express.static('public'));

app.get('*', (req, res) => { res.sendFile('index.html', { root: 'public' }); });

// Listen on port 3000, IP defaults to 127.0.0.1 (localhost) app.listen(port, (err) => { if (err) { console.log(err); return; }

console.log('Server running at http://localhost: ' + port); }); and lastly my installed packages and in package.json:

"dependencies": { "express": "^4.13.4", "extend": "^3.0.0", "react": "^0.14.7", "react-dom": "^0.14.7" }, "devDependencies": { "babel-cli": "^6.6.4", "babel-core": "^6.5.2", "babel-eslint": "^5.0.0", "babel-loader": "^6.2.4", "babel-preset-es2015": "^6.5.0", "babel-preset-react": "^6.5.0", "babel-preset-react-hmre": "^1.1.0", "babel-preset-stage-2": "^6.5.0", "babel-register": "^6.6.0", "babel-runtime": "^6.6.1", "chai": "^3.5.0", "codacy-coverage": "^1.1.3", "coveralls": "^2.11.8", "eslint": "^2.2.0", "eslint-config-airbnb": "^6.0.2", "eslint-plugin-babel": "^3.1.0", "eslint-plugin-react": "^4.1.0", "eventsource-polyfill": "^0.9.6", "gulp": "^3.9.1", "istanbul": "^0.4.2", "jscs": "^2.11.0", "mocha": "^2.4.5", "mocha-lcov-reporter": "^1.2.0", "nodemon": "^1.9.1", "webpack": "^1.12.14", "webpack-dev-middleware": "^1.5.1", "webpack-hot-middleware": "^2.9.1" } — Reply to this email directly or view it on GitHub.

VasilyShelkov commented 8 years ago

It does suggest that it's a problem with the loaders, however, when I run just npm start (so not using middleware or anything) and using the same config, it builds both the server and the React client app correctly and I know this because I can access the correctly rendered React component in the browser as well as consoling no errors and the files appearing in the correct places...

This leads me to think that it's something to do with the hot/dev middleware.

I will try using the webpack CLI and re-reading the webpack docks on loader config unless knowing the above suggests anything else to you.

VasilyShelkov commented 8 years ago

So to side on the er of caution, I have changed the webpack config to:

 module: {
    loaders: [
      {
        test: /\.js$/,
        loader: 'babel',
        include: path.join(__dirname, 'src')
      }
    ]
  },

I have also checked that the compiled webpack config contains the loader by console.log(compiler.options.module);, it gets compiled to this:

{ loaders: [ { test: /\.js$/, loader: 'babel', include: 'src' } ],
  unknownContextRequest: '.',
  unknownContextRecursive: true,
  unknownContextRegExp: /^\.\/.*$/,
  unknownContextCritical: true,
  exprContextRequest: '.',
  exprContextRegExp: /^\.\/.*$/,
  exprContextRecursive: true,
  exprContextCritical: true,
  wrappedContextRegExp: /.*/,
  wrappedContextRecursive: true,
  wrappedContextCritical: false }

All seems to be there and yet I'm still getting the

ERROR in ./src/client/index.js
Module parse failed: /home/vasily/Programming/solid-octo-disco/src/client/index.js Line 1: Unexpected token
You may need an appropriate loader to handle this file type.
| import ReactDOM from 'react-dom';
| import React from 'react';
| import App from './App';
 @ multi main

only when trying to use the webpack-dev-middleware and the webpack-hot-middleware.

I know this because when I just run webpack with the config, it builds the server and client correctly into their respective output files.

I don't know what else I could try ? node version 5.6.0 and npm version 3.6.0 not that I think that could be the issue.

Any Suggestions ?

glenjamin commented 8 years ago

Hrm, can you show the sample of how you're building it via CLI?

I wonder if it's the array of configs that isn't working. Does it work with webpack-dev-server on its own? I think you can do multiple bundles via an object instead of an array - that might help

VasilyShelkov commented 8 years ago

It does not work with webpack-dev-server on its own:

const compiler = webpack(config[1]);
app.use(require('webpack-dev-middleware')(compiler, {
    noInfo: true,
    publicPath: config[1].output.publicPath
}));

I did try removing the dev server though and the webpack-hot-middleware didn't complain. ie:

rather than this in the server:

const compiler = webpack(config[1]);
app.use(require('webpack-dev-middleware')(compiler, {
    noInfo: true,
    publicPath: config[1].output.publicPath
}));

app.use(require('webpack-hot-middleware')(compiler, {
    log: console.log
}));

just

const compiler = webpack(config[1]);

app.use(require('webpack-hot-middleware')(compiler, {
    log: console.log
}));

but obviously that doesn't really help since without the dev middleware it doesn't seem to create the bundle.js in memory.

I literally just ran webpack with no options from the terminal, or were you suggesting something more ? it correctly built:

webpack
Hash: c4a7f36bc8b3cc5e9db3e8fcfb1c954492ed6a12
Version: webpack 1.12.14
Child
    Hash: c4a7f36bc8b3cc5e9db3
    Version: webpack 1.12.14
    Time: 800ms
        Asset   Size  Chunks             Chunk Names
    server.js  15 kB       0  [emitted]  main
       [3] ./webpack.config.js 2.52 kB {0} [built]
        + 15 hidden modules
Child
    Hash: e8fcfb1c954492ed6a12
    Version: webpack 1.12.14
    Time: 1318ms
        Asset    Size  Chunks             Chunk Names
    bundle.js  828 kB       0  [emitted]  main
       [0] multi main 52 bytes {0} [built]
        + 173 hidden modules

and the files were there as expected, working properly in the browser when I ran the server in 'production' mode, ie not using the middleware.

I've also tried it on multiple computers to make sure it wasn't some weird cache thing, but the same error occurs consistently and using the webpack cli also works consistently.

VasilyShelkov commented 8 years ago

Again the above points to something being a problem in webpack-dev-middleware :S

I'm not sure if this helps, but the config[1] that I'm compiling is this:

Compiler {
  _plugins: 
   { compilation: 
      [ [Function],
        [Function],
        [Function],
        [Function: bound ],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function],
        [Function: bound ],
        [Function] ],
     'should-emit': [ [Function] ],
     'this-compilation': [ [Function] ],
     'after-resolvers': [ [Function] ],
     'entry-option': [ [Function] ],
     make: [ [Function: bound ] ],
     'context-module-factory': [ [Function] ],
     run: [ [Function], [Function] ],
     'after-compile': [ [Function] ] },
  outputPath: 'public',
  outputFileSystem: NodeOutputFileSystem {},
  inputFileSystem: 
   CachedInputFileSystem {
     fileSystem: NodeJsInputFileSystem {},
     _statStorage: 
      Storage {
        duration: 60000,
        running: {},
        data: {},
        levels: [Object],
        count: 0,
        interval: null,
        needTickCheck: false,
        nextTick: null,
        passive: true },
     _readdirStorage: 
      Storage {
        duration: 60000,
        running: {},
        data: {},
        levels: [Object],
        count: 0,
        interval: null,
        needTickCheck: false,
        nextTick: null,
        passive: true },
     _readFileStorage: 
      Storage {
        duration: 60000,
        running: {},
        data: {},
        levels: [Object],
        count: 0,
        interval: null,
        needTickCheck: false,
        nextTick: null,
        passive: true },
     _readlinkStorage: 
      Storage {
        duration: 60000,
        running: {},
        data: {},
        levels: [Object],
        count: 0,
        interval: null,
        needTickCheck: false,
        nextTick: null,
        passive: true } },
  recordsInputPath: undefined,
  recordsOutputPath: undefined,
  records: {},
  fileTimestamps: {},
  contextTimestamps: {},
  resolvers: 
   { normal: 
      Tapable {
        _plugins: [Object],
        fileSystem: [Object],
        resolve: [Function: resolve] },
     loader: 
      Tapable {
        _plugins: [Object],
        fileSystem: [Object],
        resolve: [Function: resolve] },
     context: 
      Tapable {
        _plugins: [Object],
        fileSystem: [Object],
        resolve: [Function: resolve] } },
  parser: 
   Parser {
     _plugins: 
      { 'evaluate Literal': [Object],
        'evaluate LogicalExpression': [Object],
        'evaluate BinaryExpression': [Object],
        'evaluate UnaryExpression': [Object],
        'evaluate typeof undefined': [Object],
        'evaluate Identifier': [Object],
        'evaluate MemberExpression': [Object],
        'evaluate CallExpression': [Object],
        'evaluate CallExpression .replace': [Object],
        'evaluate CallExpression .substr': [Object],
        'evaluate CallExpression .substring': [Object],
        'evaluate CallExpression .split': [Object],
        'evaluate ConditionalExpression': [Object],
        'evaluate ArrayExpression': [Object],
        'expression __webpack_hash__': [Object],
        'evaluate typeof __webpack_hash__': [Object],
        'evaluate Identifier module.hot': [Object],
        'call module.hot.accept': [Object],
        'call module.hot.decline': [Object],
        'expression module.hot': [Object],
        'expression process': [Object],
        'expression global': [Object],
        'expression Buffer': [Object],
        'expression setImmediate': [Object],
        'expression clearImmediate': [Object],
        'call require': [Object],
        'expression __filename': [Object],
        'evaluate Identifier __filename': [Object],
        'expression __dirname': [Object],
        'evaluate Identifier __dirname': [Object],
        'expression require.main': [Object],
        'expression require.extensions': [Object],
        'expression module.exports': [Object],
        'expression module.loaded': [Object],
        'expression module.id': [Object],
        'expression module': [Object],
        'call require.config': [Object],
        'call requirejs.config': [Object],
        'expression require.version': [Object],
        'expression requirejs.onError': [Object],
        'expression __webpack_require__': [Object],
        'evaluate typeof __webpack_require__': [Object],
        'expression __webpack_public_path__': [Object],
        'evaluate typeof __webpack_public_path__': [Object],
        'expression __webpack_modules__': [Object],
        'evaluate typeof __webpack_modules__': [Object],
        'expression __webpack_chunk_load__': [Object],
        'evaluate typeof __webpack_chunk_load__': [Object],
        'expression __non_webpack_require__': [Object],
        'evaluate typeof __non_webpack_require__': [Object],
        'expression require.onError': [Object],
        'evaluate typeof require.onError': [Object],
        'statement if': [Object],
        'expression ?:': [Object],
        'evaluate Identifier __resourceQuery': [Object],
        'expression __resourceQuery': [Object],
        'call require.include': [Object],
        'evaluate typeof require.include': [Object],
        'typeof require.include': [Object],
        'call require.ensure': [Object],
        'evaluate typeof require.ensure': [Object],
        'typeof require.ensure': [Object],
        'call require.context': [Object],
        'call require:amd:array': [Object],
        'call require:amd:item': [Object],
        'call require:amd:context': [Object],
        'call define': [Object],
        'call define:amd:array': [Object],
        'call define:amd:item': [Object],
        'call define:amd:context': [Object],
        'expression require.amd': [Object],
        'expression define.amd': [Object],
        'expression define': [Object],
        'expression __webpack_amd_options__': [Object],
        'evaluate typeof define.amd': [Object],
        'evaluate typeof require.amd': [Object],
        'evaluate Identifier define.amd': [Object],
        'evaluate Identifier require.amd': [Object],
        'evaluate typeof define': [Object],
        'typeof define': [Object],
        'can-rename define': [Object],
        'rename define': [Object],
        'evaluate typeof require': [Object],
        'typeof require': [Object],
        'evaluate typeof require.resolve': [Object],
        'typeof require.resolve': [Object],
        'evaluate typeof require.resolveWeak': [Object],
        'typeof require.resolveWeak': [Object],
        'evaluate typeof module': [Object],
        'assign require': [Object],
        'can-rename require': [Object],
        'rename require': [Object],
        'typeof module': [Object],
        'evaluate typeof exports': [Object],
        'expression require.cache': [Object],
        'expression require': [Object],
        'call require:commonjs:item': [Object],
        'call require:commonjs:context': [Object],
        'call require.resolve': [Object],
        'call require.resolveWeak': [Object],
        'call require.resolve(Weak)': [Object],
        'call require.resolve(Weak):item': [Object],
        'call require.resolve(Weak):context': [Object],
        'can-rename DEBUG': [Object],
        'evaluate Identifier DEBUG': [Object],
        'expression DEBUG': [Object],
        'evaluate typeof DEBUG': [Object],
        'typeof DEBUG': [Object] },
     options: undefined },
  options: 
   { module: 
      { loaders: [Object],
        unknownContextRequest: '.',
        unknownContextRecursive: true,
        unknownContextRegExp: /^\.\/.*$/,
        unknownContextCritical: true,
        exprContextRequest: '.',
        exprContextRegExp: /^\.\/.*$/,
        exprContextRecursive: true,
        exprContextCritical: true,
        wrappedContextRegExp: /.*/,
        wrappedContextRecursive: true,
        wrappedContextCritical: false },
     debug: true,
     devtool: 'eval',
     entry: 
      [ 'eventsource-polyfill',
        'webpack-hot-middleware/client',
        './src/client/index.js' ],
     output: 
      { path: 'public',
        filename: 'bundle.js',
        publicPath: '/public/',
        libraryTarget: 'var',
        sourceMapFilename: '[file].map[query]',
        hotUpdateChunkFilename: '[id].[hash].hot-update.js',
        hotUpdateMainFilename: '[hash].hot-update.json',
        crossOriginLoading: false,
        hashFunction: 'md5',
        hashDigest: 'hex',
        hashDigestLength: 20,
        sourcePrefix: '\t',
        devtoolLineToLine: false },
     plugins: [ [Object], HotModuleReplacementPlugin {}, NoErrorsPlugin {} ],
     cache: true,
     context: '/home/vasily/Programming/solid-octo-disco',
     target: 'web',
     node: 
      { console: false,
        process: true,
        global: true,
        setImmediate: true,
        __filename: 'mock',
        __dirname: 'mock' },
     resolve: 
      { fastUnsafe: [],
        alias: {},
        packageAlias: 'browser',
        modulesDirectories: [Object],
        packageMains: [Object],
        extensions: [Object] },
     resolveLoader: 
      { fastUnsafe: [],
        alias: {},
        modulesDirectories: [Object],
        packageMains: [Object],
        extensions: [Object],
        moduleTemplates: [Object] },
     optimize: { occurenceOrderPreferEntry: true } },
  context: '/home/vasily/Programming/solid-octo-disco',
  name: undefined,
  _currentPluginApply: undefined,
  watchFileSystem: 
   NodeWatchFileSystem {
     inputFileSystem: 
      CachedInputFileSystem {
        fileSystem: NodeJsInputFileSystem {},
        _statStorage: [Object],
        _readdirStorage: [Object],
        _readFileStorage: [Object],
        _readlinkStorage: [Object] },
     watcherOptions: { aggregateTimeout: 200 },
     watcher: 
      EventEmitter {
        domain: null,
        _events: {},
        _eventsCount: 0,
        _maxListeners: undefined,
        options: [Object],
        watcherOptions: [Object],
        fileWatchers: [],
        dirWatchers: [],
        mtimes: {},
        paused: false,
        aggregatedChanges: [],
        aggregateTimeout: 0,
        _onTimeout: [Function: bound _onTimeout] } } }

where config[1].options.module:

{ loaders: [ { test: /\.js$/, loader: 'babel', include: 'src' } ],
  unknownContextRequest: '.',
  unknownContextRecursive: true,
  unknownContextRegExp: /^\.\/.*$/,
  unknownContextCritical: true,
  exprContextRequest: '.',
  exprContextRegExp: /^\.\/.*$/,
  exprContextRecursive: true,
  exprContextCritical: true,
  wrappedContextRegExp: /.*/,
  wrappedContextRecursive: true,
  wrappedContextCritical: false }

in case you were wondering if the loader was there since you were suggesting that could be the issue.

Had a though, could the issue be caused by the server.js file not being in the root of the project in some way ?

but like I said it works with the webpack cli perfectly, just not through dev-middleware

glenjamin commented 8 years ago

Assuming that the webpack on your path is the same version as the one in your project, I suspect the problem is that dev-middleware doesn't work with an array of bundles

VasilyShelkov commented 8 years ago

but it's not gettting an array of bundles, it's getting only 1 element which is the same as passing it just as an object (config[1])from that array (just the client) surely no ? or am I misunderstanding what I'm doing ?

VasilyShelkov commented 8 years ago

and yes the webpack version is the same on my path as in my project: v1.12.14

glenjamin commented 8 years ago

Ah, I've just re-read the code you posted, that array thing was my mistake.

I'm checking your code out now to take a look, this is pretty odd.

VasilyShelkov commented 8 years ago

ok appreciate you taking any time to look into it :) but I've completely run out of ideas and exhausted my search through other github repos and the documentations... I'm definitely missing something to do with the webpack-dev-server.

So I'm running nodeman (btw I'm now ignoring the client files so nodeman doesn't restart when client files are changed in case that was somehow affecting it) to this:

gulp.task('build', function(done) {
  webpack(webpackConfig).run(onBuild(done));
});

gulp.task('build-watch', function() {
  webpack(webpackConfig[0]).watch(100, function(err, stats) {
    onBuild()(err, stats);
    nodemon.restart();
  });
});

gulp.task('run', ['build-watch'], function() {
  nodemon({
    execMap: {
      js: 'node',
    },
    script: path.join(__dirname, 'build/server'),
    ignore: ['/src/client/**/*'],
    ext: 'js'
  }).on('restart', function() {
    console.log('Reloading Nodemon');
  });
});

so build-watch task only builds the server webpack config webpackConfig[0] and also in run task, nodemon is ignoring the client code ('/src/client/**/*') in case nodemon was somehow affecting it.

VasilyShelkov commented 8 years ago

It's really strange because I haven't had issues running the webpack-dev-server and hotloading before and really love it X)

lf you are looking and have the time, feel free to have a look at the public repository in case any of my first posts code is slightly out of date here https://github.com/Winwardo/solid-octo-disco/tree/react-hotloading but think there aren't any major differences other than the ones I've posted

glenjamin commented 8 years ago

Ok, that was pretty fiddly - but I figured it out.

The problem is that the webpack server build includes the webpack config, even when setting __dirname: true in the webpack node section, you only get relative paths - not absolute. This means that the include section gets reduced to src, which won't work from build/server.js.

You can see this here:

where config[1].options.module:

{ loaders: [ { test: /.js$/, loader: 'babel', include: 'src' } ], unknownContextRequest: '.', unknownContextRecursive: true, unknownContextRegExp: /^.\/.$/, unknownContextCritical: true, exprContextRequest: '.', exprContextRegExp: /^.\/.$/, exprContextRecursive: true, exprContextCritical: true, wrappedContextRegExp: /.*/, wrappedContextRecursive: true, wrappedContextCritical: false }

The simplest fix I could find was to exclude the webpack config from the bundle, like so:

@@ -46,7 +46,9 @@ const serverConfig = extend(true, {}, config, {
     __dirname: true,
     __filename: true,
   },
-  externals: nodeModules,
+  externals: [nodeModules, {
+    '../../webpack.config.js': 'commonjs ' + require.resolve(__filename)
+  }],
   plugins: [],
 });

After doing this, the webpack-built server bundle works.

VasilyShelkov commented 8 years ago

wow you are an absolute beast, I should have known to look into that since that function and externals is the only difference between the projects that had it working and didn't. I just dismissed it because I didn't think it be in the scope of the webpack-dev-server due to it being server side building, how wrong I was...

Sheffield developer too strong ! (coincidently I'm in my final year nCS at University of Sheffield :) )

glenjamin commented 8 years ago

You should come along to one of the local programmer meetups then - http://sheffieldgeeks.org.uk/

VasilyShelkov commented 8 years ago

ooh I didn't even realise that existed ! will check it out :)

hutber commented 8 years ago

My god!! They actually teach tech in uni's now? For the life of me couldn't find a web dev court for uni :/