mirror of https://github.com/embarklabs/embark.git
Do not run webpack for file changes that do not need webpack
For file changes that do not require a webpack run, ie HTML, the assets will still be copied to the output directory, but webpack will not run (as it’s too slow).
This commit is contained in:
parent
7e75b1eee7
commit
91e5e9c990
|
@ -108,9 +108,9 @@ class Engine {
|
|||
this.registerModule('pipeline', {
|
||||
webpackConfigName: this.webpackConfigName
|
||||
});
|
||||
this.events.on('code-generator-ready', function () {
|
||||
this.events.on('code-generator-ready', function (modifiedAsset) {
|
||||
self.events.request('code', function (abi, contractsJSON) {
|
||||
self.events.request('pipeline:build', {abi, contractsJSON}, () => {
|
||||
self.events.request('pipeline:build', {abi, contractsJSON, modifiedAsset}, () => {
|
||||
self.events.emit('outputDone');
|
||||
});
|
||||
});
|
||||
|
@ -162,17 +162,17 @@ class Engine {
|
|||
|
||||
this.registerModule('code_generator', {plugins: self.plugins, env: self.env});
|
||||
|
||||
const generateCode = function () {
|
||||
const generateCode = function (modifiedAsset) {
|
||||
self.events.request("code-generator:embarkjs:build", () => {
|
||||
self.events.emit('code-generator-ready');
|
||||
self.events.emit('code-generator-ready', modifiedAsset);
|
||||
});
|
||||
};
|
||||
const cargo = async.cargo((_tasks, callback) => {
|
||||
generateCode();
|
||||
const cargo = async.queue((task, callback) => {
|
||||
generateCode(task.modifiedAsset);
|
||||
self.events.once('outputDone', callback);
|
||||
});
|
||||
const addToCargo = function () {
|
||||
cargo.push({});
|
||||
}, 10);
|
||||
const addToCargo = function (modifiedAsset) {
|
||||
cargo.push({modifiedAsset});
|
||||
};
|
||||
|
||||
this.events.on('contractsDeployed', addToCargo);
|
||||
|
@ -198,7 +198,7 @@ class Engine {
|
|||
this.registerModule('console_listener', {ipc: self.ipc});
|
||||
this.registerModule('deployment', {plugins: this.plugins, onlyCompile: options.onlyCompile});
|
||||
|
||||
this.events.on('file-event', function (fileType) {
|
||||
this.events.on('file-event', function ({fileType, path}) {
|
||||
clearTimeout(self.fileTimeout);
|
||||
self.fileTimeout = setTimeout(() => {
|
||||
// TODO: still need to redeploy contracts because the original contracts
|
||||
|
@ -206,7 +206,7 @@ class Engine {
|
|||
self.config.reloadConfig();
|
||||
if (fileType === 'asset') {
|
||||
// Throttle file changes so we re-write only once for all files
|
||||
self.events.emit('asset-changed', self.contractsManager);
|
||||
self.events.emit('asset-changed', path);
|
||||
}
|
||||
// TODO: for now need to deploy on asset changes as well
|
||||
// because the contractsManager config is corrupted after a deploy
|
||||
|
|
|
@ -3,6 +3,7 @@ const async = require('async');
|
|||
const utils = require('../../utils/utils.js');
|
||||
const ProcessLauncher = require('../../core/processes/processLauncher');
|
||||
const constants = require('../../constants');
|
||||
const WebpackConfigReader = require('../pipeline/webpackConfigReader');
|
||||
|
||||
class Pipeline {
|
||||
constructor(embark, options) {
|
||||
|
@ -18,11 +19,11 @@ class Pipeline {
|
|||
this.pipelineConfig = embark.config.pipelineConfig;
|
||||
this.isFirstBuild = true;
|
||||
|
||||
this.events.setCommandHandler('pipeline:build', (options, callback) => this.build(callback));
|
||||
this.events.setCommandHandler('pipeline:build', (options, callback) => this.build(options, callback));
|
||||
fs.removeSync(this.buildDir);
|
||||
}
|
||||
|
||||
build(callback) {
|
||||
build({modifiedAsset}, callback) {
|
||||
let self = this;
|
||||
const importsList = {};
|
||||
let placeholderPage;
|
||||
|
@ -82,7 +83,26 @@ class Pipeline {
|
|||
});
|
||||
});
|
||||
},
|
||||
function runWebpack(next) {
|
||||
function shouldRunWebpack(next){
|
||||
// assuming we got here because an asset was changed, let's check our webpack config
|
||||
// to see if the changed asset requires webpack to run
|
||||
if(modifiedAsset){
|
||||
const configReader = new WebpackConfigReader({webpackConfigName: self.webpackConfigName});
|
||||
return configReader.readConfig((err, config) => {
|
||||
if(err) return next(err);
|
||||
|
||||
if (typeof config !== 'object' || config === null) {
|
||||
return next(__('bad webpack config, the resolved config was null or not an object'));
|
||||
}
|
||||
|
||||
const shouldRun = config.module.rules.some(rule => rule.test.test(modifiedAsset));
|
||||
return next(null, !shouldRun);
|
||||
});
|
||||
}
|
||||
next(null, false);
|
||||
},
|
||||
function runWebpack(shouldNotRun, next) {
|
||||
if(shouldNotRun) return next();
|
||||
self.logger.info(__(`running webpack with '${self.webpackConfigName}' config...`));
|
||||
const assets = Object.keys(self.assetFiles).filter(key => key.match(/\.js$/));
|
||||
if (!assets || !assets.length) {
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
const {errorMessage} = require('../../utils/utils');
|
||||
const fs = require('../../core/fs');
|
||||
|
||||
class WebpackConfigReader {
|
||||
constructor(options) {
|
||||
this.webpackConfigName = options.webpackConfigName;
|
||||
}
|
||||
|
||||
async readConfig(callback){
|
||||
const dappConfigPath = fs.dappPath('webpack.config.js');
|
||||
const defaultConfigPath = fs.embarkPath('lib/modules/pipeline', 'webpack.config.js');
|
||||
|
||||
let config, configPath;
|
||||
try {
|
||||
if (fs.existsSync(dappConfigPath)) {
|
||||
configPath = dappConfigPath;
|
||||
delete require.cache[configPath];
|
||||
} else {
|
||||
configPath = defaultConfigPath;
|
||||
}
|
||||
config = require(configPath);
|
||||
// valid config types: https://webpack.js.org/configuration/configuration-types/
|
||||
// + function that returns a config object
|
||||
// + function that returns a promise for a config object
|
||||
// + array of named config objects
|
||||
// + config object
|
||||
if (typeof config === 'function') {
|
||||
// if(Promise.resolve(config)){
|
||||
// return config(this.webpackConfigName).then(config => {
|
||||
// callback(null, config);
|
||||
// });
|
||||
// }
|
||||
|
||||
config = await config(this.webpackConfigName);
|
||||
//return callback(null, config);
|
||||
} else if (Array.isArray(config)) {
|
||||
config = config.filter(cfg => cfg.name === this.webpackConfigName);
|
||||
if (!config.length) {
|
||||
return callback(`no webpack config has the name '${this.webpackConfigName}'`);
|
||||
}
|
||||
if (config.length > 1) {
|
||||
console.warn(`detected ${config.length} webpack configs having the name '${this.webpackConfigName}', using the first one`);
|
||||
}
|
||||
config = config[0];
|
||||
//return callback(null, config);
|
||||
}
|
||||
callback(null, config);
|
||||
} catch (e) {
|
||||
console.error(`error while loading webpack config ${configPath}`);
|
||||
callback(errorMessage(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = WebpackConfigReader;
|
|
@ -4,6 +4,7 @@ const ProcessWrapper = require('../../core/processes/processWrapper');
|
|||
const webpack = require('webpack');
|
||||
const writeFile = require('util').promisify(require('fs').writeFile);
|
||||
const {errorMessage} = require('../../utils/utils');
|
||||
const WebpackConfigReader = require('./webpackConfigReader');
|
||||
|
||||
let webpackProcess;
|
||||
|
||||
|
@ -40,70 +41,43 @@ class WebpackProcess extends ProcessWrapper {
|
|||
return callback(errorMessage(e));
|
||||
}
|
||||
|
||||
const dappConfigPath = fs.dappPath('webpack.config.js');
|
||||
const defaultConfigPath = fs.embarkPath('lib/modules/pipeline', 'webpack.config.js');
|
||||
|
||||
let config, configPath;
|
||||
try {
|
||||
if (fs.existsSync(dappConfigPath)) {
|
||||
configPath = dappConfigPath;
|
||||
delete require.cache[configPath];
|
||||
} else {
|
||||
configPath = defaultConfigPath;
|
||||
}
|
||||
config = require(configPath);
|
||||
// valid config types: https://webpack.js.org/configuration/configuration-types/
|
||||
// + function that returns a config object
|
||||
// + function that returns a promise for a config object
|
||||
// + array of named config objects
|
||||
// + config object
|
||||
if (typeof config === 'function') {
|
||||
config = await config(this.webpackConfigName);
|
||||
} else if (Array.isArray(config)) {
|
||||
config = config.filter(cfg => cfg.name === this.webpackConfigName);
|
||||
if (!config.length) {
|
||||
return callback(`no webpack config has the name '${this.webpackConfigName}'`);
|
||||
}
|
||||
if (config.length > 1) {
|
||||
console.warn(`detected ${config.length} webpack configs having the name '${this.webpackConfigName}', using the first one`);
|
||||
}
|
||||
config = config[0];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`error while loading webpack config ${configPath}`);
|
||||
callback(errorMessage(e));
|
||||
}
|
||||
|
||||
if (typeof config !== 'object' || config === null) {
|
||||
return callback('bad webpack config, the resolved config was null or not an object');
|
||||
}
|
||||
|
||||
webpack(config).run(async (err, stats) => {
|
||||
const configReader = new WebpackConfigReader({webpackConfigName: this.webpackConfigName});
|
||||
configReader.readConfig((err, config) => {
|
||||
if (err) {
|
||||
return callback(errorMessage(err));
|
||||
return callback(err);
|
||||
}
|
||||
if (!config.stats || config.stats === 'none') {
|
||||
return callback();
|
||||
|
||||
if (typeof config !== 'object' || config === null) {
|
||||
return callback('bad webpack config, the resolved config was null or not an object');
|
||||
}
|
||||
try {
|
||||
this._log('info', 'writing file '+ ('.embark/stats.report').bold.dim);
|
||||
await writeFile(
|
||||
fs.dappPath('.embark/stats.report'),
|
||||
stats.toString(config.stats)
|
||||
);
|
||||
this._log('info', 'writing file ' + ('.embark/stats.json').bold.dim);
|
||||
await writeFile(
|
||||
fs.dappPath('.embark/stats.json'),
|
||||
JSON.stringify(stats.toJson(config.stats))
|
||||
);
|
||||
if (stats.hasErrors()) {
|
||||
const errors = stats.toJson(config.stats).errors.join('\n');
|
||||
return callback(errors);
|
||||
|
||||
webpack(config).run(async (err, stats) => {
|
||||
if (err) {
|
||||
return callback(errorMessage(err));
|
||||
}
|
||||
callback();
|
||||
} catch (e) {
|
||||
return callback(errorMessage(e));
|
||||
}
|
||||
if (!config.stats || config.stats === 'none') {
|
||||
return callback();
|
||||
}
|
||||
try {
|
||||
this._log('info', 'writing file ' + ('.embark/stats.report').bold.dim);
|
||||
await writeFile(
|
||||
fs.dappPath('.embark/stats.report'),
|
||||
stats.toString(config.stats)
|
||||
);
|
||||
this._log('info', 'writing file ' + ('.embark/stats.json').bold.dim);
|
||||
await writeFile(
|
||||
fs.dappPath('.embark/stats.json'),
|
||||
JSON.stringify(stats.toJson(config.stats))
|
||||
);
|
||||
if (stats.hasErrors()) {
|
||||
const errors = stats.toJson(config.stats).errors.join('\n');
|
||||
return callback(errors);
|
||||
}
|
||||
callback();
|
||||
} catch (e) {
|
||||
return callback(errorMessage(e));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ class Watcher {
|
|||
function (eventName, path) {
|
||||
self.logger.info(`${eventName}: ${path}`);
|
||||
self.events.emit('file-' + eventName, 'asset', path);
|
||||
self.events.emit('file-event', 'asset', path);
|
||||
self.events.emit('file-event', {fileType: 'asset', path});
|
||||
},
|
||||
function () {
|
||||
callback();
|
||||
|
@ -104,7 +104,7 @@ class Watcher {
|
|||
function (eventName, path) {
|
||||
self.logger.info(`${eventName}: ${path}`);
|
||||
self.events.emit('file-' + eventName, 'contract', path);
|
||||
self.events.emit('file-event', 'contract', path);
|
||||
self.events.emit('file-event', {fileType: 'contract', path});
|
||||
},
|
||||
function () {
|
||||
callback();
|
||||
|
@ -154,7 +154,7 @@ class Watcher {
|
|||
function (eventName, path) {
|
||||
self.logger.info(`${eventName}: ${path}`);
|
||||
self.events.emit('file-' + eventName, 'config', path);
|
||||
self.events.emit('file-event', 'config', path);
|
||||
self.events.emit('file-event', {fileType: 'config', path});
|
||||
},
|
||||
function () {
|
||||
callback();
|
||||
|
@ -177,7 +177,7 @@ class Watcher {
|
|||
this.watchFiles(filesToWatch, (eventName, path) => {
|
||||
this.logger.info(`${eventName}: ${path}`);
|
||||
this.events.emit('file-' + eventName, 'config', path);
|
||||
this.events.emit('file-event', 'config', path);
|
||||
this.events.emit('file-event', {fileType: 'config', path});
|
||||
}, callback);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue