Skip to content

Commit

Permalink
fix(webpack): Invalidate build when new module has been added and -r …
Browse files Browse the repository at this point in the history
…flag is enabled

Fixes #121
  • Loading branch information
d4rkr00t committed Feb 6, 2017
1 parent 55a92e8 commit 93eac9a
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 11 deletions.
3 changes: 3 additions & 0 deletions flow-typed/npm-custom/resolve.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module 'resolve' {
declare module.exports: any
}
12 changes: 12 additions & 0 deletions lib/utils/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ exports.devServerCompiledSuccessfullyMsg = devServerCompiledSuccessfullyMsg;
exports.devServerFailedToCompileMsg = devServerFailedToCompileMsg;
exports.devServerCompiledWithWarningsMsg = devServerCompiledWithWarningsMsg;
exports.devServerFileDoesNotExistMsg = devServerFileDoesNotExistMsg;
exports.devServerRestartMsg = devServerRestartMsg;
exports.devServerModuleDoesntExists = devServerModuleDoesntExists;
exports.builderBanner = builderBanner;
exports.builderRemovingDistMsg = builderRemovingDistMsg;
exports.builderRunningBuildMsg = builderRunningBuildMsg;
Expand Down Expand Up @@ -148,6 +150,16 @@ function devServerFileDoesNotExistMsg(filename) {
return print([warningBadge() + ` File "${_chalk2.default.yellow(filename)}" doesn\'t exist.`, '']);
}

function devServerRestartMsg(module) {
clearConsole(true);
return print([warningBadge() + ' ' + _chalk2.default.yellow(`New npm module was added (${module}).`), '', 'Restarting webpack-dev-server is requried.', '', 'Please be patient and wait until restart completes, otherwise some changes might not be tracked.', '']);
}

function devServerModuleDoesntExists(module, filename) {
clearConsole(true);
return print([errorBadge() + ' ' + _chalk2.default.red(`Module '${module}' doesn't exists.`), '', `Error in ${filename}`, '', `Webpack tried to resolve module ${_chalk2.default.bgYellow.black(' ' + module + ' ')} which doesn't exist.`, '', `It's likely caused by ${_chalk2.default.yellow('typo')} in the module name.`, '']);
}

/**
*
* Build Messages
Expand Down
47 changes: 42 additions & 5 deletions lib/webpack-dev-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ var _connectHistoryApiFallback = require('connect-history-api-fallback');

var _connectHistoryApiFallback2 = _interopRequireDefault(_connectHistoryApiFallback);

var _resolve = require('resolve');

var _resolve2 = _interopRequireDefault(_resolve);

var _webpack = require('webpack');

var _webpack2 = _interopRequireDefault(_webpack);
Expand All @@ -40,7 +44,8 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
/**
* On done handler for webpack compiler.
*/
function onDone(filename, flags, params, stats) {
function onDone(filename, flags, params, compiler, invalidate, stats) {
// eslint-disable-line
const hasErrors = stats.hasErrors();
const hasWarnings = stats.hasWarnings();
const buildDuration = stats.endTime - stats.startTime;
Expand All @@ -58,6 +63,12 @@ function onDone(filename, flags, params, stats) {
let formattedErrors = json.errors.map(message => 'Error in ' + (0, _errorHelpers.formatMessage)(message));

if (hasErrors) {
if (formattedErrors.filter(err => err.match('Cannot resolve module')).length) {
invalidate(formattedErrors);
(0, _testUtils2.default)();
return;
}

(0, _messages.devServerFailedToCompileMsg)();

// If there are any syntax errors, show just them.
Expand Down Expand Up @@ -85,10 +96,13 @@ function onDone(filename, flags, params, stats) {
/**
* Creates webpack compiler.
*/
function createWebpackCompiler(filename, flags, params, config) {


function createWebpackCompiler(filename, flags, params, config, invalidate) {
// eslint-disable-line
const compiler = (0, _webpack2.default)(config);
compiler.plugin('invalid', _messages.devServerInvalidBuildMsg);
compiler.plugin('done', onDone.bind(null, filename, flags, params));
compiler.plugin('done', onDone.bind(null, filename, flags, params, compiler, invalidate));
return compiler;
}

Expand All @@ -102,9 +116,32 @@ function createWebpackDevServer(filename, flags, params) {
flags.port = port;
}

let server; // eslint-disable-line
const invalidate = errors => {
if (!server) return;

const error = errors[0] || '';
const fileWithError = (error.match(/Error in (.+)\n/) || [])[1];
let moduleName = (error.match(/Module not found: Error: Cannot resolve module '(.+)'/) || [])[1];

if (!moduleName) return;

moduleName = moduleName.replace(/'/gmi, '');

try {
_resolve2.default.sync(moduleName, { basedir: process.cwd() });
(0, _messages.devServerRestartMsg)(moduleName);
server.close();
createWebpackDevServer(filename, flags, params);
} catch (e) {
// eslint-disable-line
(0, _messages.devServerModuleDoesntExists)(moduleName, fileWithError);
}
};
const config = (0, _configBuilder2.default)(filename, flags, params);
const compiler = createWebpackCompiler(filename, flags, params, config);
const server = new _webpackDevServer2.default(compiler, {
const compiler = createWebpackCompiler(filename, flags, params, config, invalidate);

server = new _webpackDevServer2.default(compiler, {
// Enable gzip compression of generated files.
compress: true,

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
"postcss-partial-import": "3.1.0",
"precss": "1.4.0",
"react-hot-loader": "1.3.1",
"resolve": "^1.2.0",
"style-loader": "0.13.1",
"webpack": "1.14.0",
"webpack-dev-server": "1.16.3"
Expand Down
26 changes: 26 additions & 0 deletions src/utils/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,32 @@ export function devServerFileDoesNotExistMsg(filename: string) {
]);
}

export function devServerRestartMsg(module: string) {
clearConsole(true);
return print([
warningBadge() + ' ' + chalk.yellow(`New npm module was added (${module}).`),
'',
'Restarting webpack-dev-server is requried.',
'',
'Please be patient and wait until restart completes, otherwise some changes might not be tracked.',
''
]);
}

export function devServerModuleDoesntExists(module: string, filename: string) {
clearConsole(true);
return print([
errorBadge() + ' ' + chalk.red(`Module '${module}' doesn't exists.`),
'',
`Error in ${filename}`,
'',
`Webpack tried to resolve module ${chalk.bgYellow.black(' ' + module + ' ')} which doesn't exist.`,
'',
`It's likely caused by ${chalk.yellow('typo')} in the module name.`,
''
]);
}

/**
*
* Build Messages
Expand Down
43 changes: 37 additions & 6 deletions src/webpack-dev-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import detectPort from 'detect-port';
import historyApiFallback from 'connect-history-api-fallback';
import resolveModule from 'resolve';
import webpack from 'webpack';
import WebpackDevServer from 'webpack-dev-server';
import webpackConfigBuilder from './webpack/config-builder';
Expand All @@ -13,13 +14,15 @@ import {
devServerInvalidBuildMsg,
devServerCompiledSuccessfullyMsg,
devServerFailedToCompileMsg,
devServerCompiledWithWarningsMsg
devServerCompiledWithWarningsMsg,
devServerRestartMsg,
devServerModuleDoesntExists
} from './utils/messages';

/**
* On done handler for webpack compiler.
*/
export function onDone(filename: string, flags: CLIFlags, params: AikParams, stats: Object) {
export function onDone(filename: string, flags: CLIFlags, params: AikParams, compiler: any, invalidate: Function, stats: Object) { // eslint-disable-line
const hasErrors = stats.hasErrors();
const hasWarnings = stats.hasWarnings();
const buildDuration: number = stats.endTime - stats.startTime;
Expand All @@ -37,6 +40,12 @@ export function onDone(filename: string, flags: CLIFlags, params: AikParams, sta
let formattedErrors = json.errors.map(message => 'Error in ' + formatMessage(message));

if (hasErrors) {
if (formattedErrors.filter(err => err.match('Cannot resolve module')).length) {
invalidate(formattedErrors);
testUtils();
return;
}

devServerFailedToCompileMsg();

// If there are any syntax errors, show just them.
Expand Down Expand Up @@ -65,10 +74,10 @@ export function onDone(filename: string, flags: CLIFlags, params: AikParams, sta
/**
* Creates webpack compiler.
*/
export function createWebpackCompiler(filename: string, flags: CLIFlags, params: AikParams, config: Object) {
export function createWebpackCompiler(filename: string, flags: CLIFlags, params: AikParams, config: Object, invalidate: Function) { // eslint-disable-line
const compiler = webpack(config);
compiler.plugin('invalid', devServerInvalidBuildMsg);
compiler.plugin('done', onDone.bind(null, filename, flags, params));
compiler.plugin('done', onDone.bind(null, filename, flags, params, compiler, invalidate));
return compiler;
}

Expand All @@ -82,9 +91,31 @@ export default function createWebpackDevServer(filename: string, flags: CLIFlags
flags.port = port;
}

let server: WebpackDevServer; // eslint-disable-line
const invalidate = (errors: string[]) => {
if (!server) return;

const error = errors[0] || '';
const fileWithError = (error.match(/Error in (.+)\n/) || [])[1];
let moduleName = (error.match(/Module not found: Error: Cannot resolve module '(.+)'/) || [])[1];

if (!moduleName) return;

moduleName = moduleName.replace(/'/gmi, '');

try {
resolveModule.sync(moduleName, { basedir: process.cwd() });
devServerRestartMsg(moduleName);
server.close();
createWebpackDevServer(filename, flags, params);
} catch (e) { // eslint-disable-line
devServerModuleDoesntExists(moduleName, fileWithError);
}
};
const config = webpackConfigBuilder(filename, flags, params);
const compiler = createWebpackCompiler(filename, flags, params, config);
const server = new WebpackDevServer(compiler, {
const compiler = createWebpackCompiler(filename, flags, params, config, invalidate);

server = new WebpackDevServer(compiler, {
// Enable gzip compression of generated files.
compress: true,

Expand Down

0 comments on commit 93eac9a

Please sign in to comment.