webpack/lib/FlagDependencyExportsPlugin.js

105 lines
2.9 KiB
JavaScript
Raw Normal View History

/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
2017-11-08 18:32:05 +08:00
const addToSet = (a, b) => {
let changed = false;
b.forEach((item) => {
if(!a.has(item)) {
a.add(item);
changed = true;
}
});
return changed;
};
class FlagDependencyExportsPlugin {
apply(compiler) {
compiler.plugin("compilation", (compilation) => {
compilation.plugin("finish-modules", (modules) => {
2017-01-26 06:23:20 +08:00
const dependencies = Object.create(null);
2017-11-08 18:32:05 +08:00
// TODO maybe replace with utils/Queue for better performance?
const queue = modules.filter((m) => !m.providedExports);
let module;
let moduleWithExports;
let moduleProvidedExports;
2017-11-08 18:32:05 +08:00
const processDependenciesBlock = depBlock => {
depBlock.dependencies.forEach((dep) => processDependency(dep));
depBlock.variables.forEach((variable) => {
variable.dependencies.forEach((dep) => processDependency(dep));
});
2017-01-26 06:23:20 +08:00
depBlock.blocks.forEach(processDependenciesBlock);
2017-11-08 18:32:05 +08:00
};
2017-11-08 18:32:05 +08:00
const processDependency = dep => {
const exportDesc = dep.getExports && dep.getExports();
if(!exportDesc) return;
moduleWithExports = true;
const exports = exportDesc.exports;
const exportDeps = exportDesc.dependencies;
if(exportDeps) {
exportDeps.forEach((dep) => {
const depIdent = dep.identifier();
// if this was not yet initialized
// initialize it as an array containing the module and stop
2017-02-08 16:01:59 +08:00
const array = dependencies[depIdent];
if(!array) {
dependencies[depIdent] = [module];
return;
}
// check if this module is known
// if not, add it to the dependencies for this identifier
2017-02-08 16:01:59 +08:00
if(array.indexOf(module) < 0)
array.push(module);
});
}
let changed = false;
if(module.providedExports !== true) {
if(exports === true) {
module.providedExports = true;
2016-09-09 20:20:29 +08:00
changed = true;
} else if(Array.isArray(exports)) {
changed = addToSet(moduleProvidedExports, exports);
2016-09-09 20:20:29 +08:00
}
2016-11-21 08:00:25 +08:00
}
if(changed) {
notifyDependencies();
}
2017-11-08 18:32:05 +08:00
};
2016-09-09 20:50:14 +08:00
2017-11-08 18:32:05 +08:00
const notifyDependencies = () => {
2017-01-26 06:23:20 +08:00
const deps = dependencies[module.identifier()];
if(deps) {
deps.forEach((dep) => queue.push(dep));
}
2017-11-08 18:32:05 +08:00
};
for(let i = 0; i < queue.length; i++) {
module = queue[i];
2017-11-08 18:32:05 +08:00
if(module.providedExports !== true) {
moduleWithExports = module.meta && module.meta.harmonyModule;
moduleProvidedExports = Array.isArray(module.providedExports) ? new Set(module.providedExports) : new Set();
processDependenciesBlock(module);
if(!moduleWithExports) {
module.providedExports = true;
notifyDependencies();
} else if(module.providedExports !== true) {
module.providedExports = Array.from(moduleProvidedExports);
}
}
2017-11-08 18:32:05 +08:00
}
});
});
}
}
module.exports = FlagDependencyExportsPlugin;