@tdb/web
Version:
Common condiguration for serving a web-site and testing web-based UI components.
218 lines (154 loc) • 8.52 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _webpack = require('webpack');
var _webpack2 = _interopRequireDefault(_webpack);
var _flatMap = require('lodash/flatMap');
var _flatMap2 = _interopRequireDefault(_flatMap);
var _isEmpty = require('lodash/isEmpty');
var _isEmpty2 = _interopRequireDefault(_isEmpty);
var _once = require('lodash/once');
var _once2 = _interopRequireDefault(_once);
var _tapable = require('tapable');
var _webpackSources = require('webpack-sources');
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _paths = require('./paths');
var _createCompileIfNeeded = require('./createCompileIfNeeded');
var _createCompileIfNeeded2 = _interopRequireDefault(_createCompileIfNeeded);
var _createConfig = require('./createConfig');
var _createConfig2 = _interopRequireDefault(_createConfig);
var _createMemory = require('./createMemory');
var _createMemory2 = _interopRequireDefault(_createMemory);
var _createSettings = require('./createSettings');
var _createSettings2 = _interopRequireDefault(_createSettings);
var _getInstanceIndex = require('./getInstanceIndex');
var _getInstanceIndex2 = _interopRequireDefault(_getInstanceIndex);
var _createHandleStats = require('./createHandleStats');
var _createHandleStats2 = _interopRequireDefault(_createHandleStats);
var _createLogger = require('./createLogger');
var _createLogger2 = _interopRequireDefault(_createLogger);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var AutoDLLPlugin = function () {
function AutoDLLPlugin(settings) {
_classCallCheck(this, AutoDLLPlugin);
// first, we store a reference to the settings passed by the user as is.
this._originalSettings = settings;
}
// apply is called once when compiler initialized.
// note that even if the it called using webpack-dev-server
// it still called only once and not on every re-run.
// keep in mind that some user wanted to use multiple instances of the plugin in one config,
// in that case, each instance calls its own apply.
_createClass(AutoDLLPlugin, [{
key: 'apply',
value: function apply(compiler) {
// createSettings responsibe for extending the defaults values with the user's settings.
// It also adds a uniqe hash which in the form of:
// [env]_instance_[index]_[settingsHash]
// [env] - settings.env provided by the user. defaults to NODE_ENV
// [index] - the index of the instance in the user's plugins array.
// [settingsHash] - a hash made of JSON.stringify(settings) with some values omitted.
// hash example: development_instance_0_3289102229a87e84441ca34609c27500
// both [env] & [index] aims to solve the challenge of having muliple instances.
// in the plugin itself its not a problem,
// but since the cache is stored in file system we need to came up with a uniqe path for each instance
// to prevent collision. related to: https://github.com/asfktz/autodll-webpack-plugin/issues/30
var settings = (0, _createSettings2.default)({
originalSettings: this._originalSettings,
index: (0, _getInstanceIndex2.default)(compiler.options.plugins, this),
parentConfig: compiler.options
});
var log = (0, _createLogger2.default)(settings.debug);
var dllConfig = (0, _createConfig2.default)(settings, compiler.options);
var compileIfNeeded = (0, _createCompileIfNeeded2.default)(log, settings);
var memory = (0, _createMemory2.default)();
var handleStats = (0, _createHandleStats2.default)(log, settings.hash, memory);
compiler.hooks.autodllStatsRetrieved = new _tapable.SyncHook(['stats', 'source']);
if ((0, _isEmpty2.default)(dllConfig.entry)) {
// there's nothing to do.
return;
}
var context = settings.context,
inject = settings.inject;
var attachDllReferencePlugin = (0, _once2.default)(function (compiler) {
Object.keys(dllConfig.entry).map((0, _paths.getManifestPath)(settings.hash)).forEach(function (manifestPath) {
new _webpack.DllReferencePlugin({
context: context,
manifest: manifestPath
}).apply(compiler);
});
});
var beforeCompile = function beforeCompile(params, callback) {
var dependencies = new Set(params.compilationDependencies);
[].concat(_toConsumableArray(dependencies)).filter(function (path) {
return !path.startsWith(_paths.cacheDir);
});
callback();
};
var watchRun = function watchRun(compiler, callback) {
compileIfNeeded(function () {
return (0, _webpack2.default)(dllConfig);
}).then(function (stats) {
return handleStats(stats);
}).then(function (_ref) {
var source = _ref.source,
stats = _ref.stats;
compiler.hooks.autodllStatsRetrieved.call(stats, source);
if (source === 'memory') return;
memory.sync(settings.hash, stats);
}).then(function () {
attachDllReferencePlugin(compiler);
callback();
}).catch(console.error);
};
var emit = function emit(compilation, callback) {
var dllAssets = memory.getAssets().reduce(function (assets, _ref2) {
var filename = _ref2.filename,
buffer = _ref2.buffer;
var assetPath = _path2.default.join(settings.path, filename);
return _extends({}, assets, {
[assetPath]: new _webpackSources.RawSource(buffer)
});
}, {});
compilation.assets = _extends({}, compilation.assets, dllAssets);
callback();
};
compiler.hooks.beforeCompile.tapAsync('AutoDllPlugin', beforeCompile);
compiler.hooks.run.tapAsync('AutoDllPlugin', watchRun);
compiler.hooks.watchRun.tapAsync('AutoDllPlugin', watchRun);
compiler.hooks.emit.tapAsync('AutoDllPlugin', emit);
if (inject) {
var getDllEntriesPaths = function getDllEntriesPaths(extension) {
return (0, _flatMap2.default)(memory.getStats().entrypoints, 'assets').filter(function (filename) {
return filename.endsWith(extension);
}).map(function (filename) {
return (0, _paths.getInjectPath)({
publicPath: settings.publicPath,
pluginPath: settings.path,
filename
});
});
};
var doCompilation = function doCompilation(htmlPluginData, callback) {
htmlPluginData.assets.js = [].concat(_toConsumableArray(getDllEntriesPaths('.js')), _toConsumableArray(htmlPluginData.assets.js));
htmlPluginData.assets.css = [].concat(_toConsumableArray(getDllEntriesPaths('.css')), _toConsumableArray(htmlPluginData.assets.css));
callback(null, htmlPluginData);
};
compiler.hooks.compilation.tap('AutoDllPlugin', function (compilation) {
if (!compilation.hooks.htmlWebpackPluginBeforeHtmlGeneration) {
return;
}
compilation.hooks.htmlWebpackPluginBeforeHtmlGeneration.tapAsync('AutoDllPlugin', doCompilation);
});
}
}
}]);
return AutoDLLPlugin;
}();
exports.default = AutoDLLPlugin;