Skip to content

Instantly share code, notes, and snippets.

@staeke
Created June 19, 2020 18:59
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save staeke/f197ff144e379aa884f91b95003f4ee1 to your computer and use it in GitHub Desktop.
Save staeke/f197ff144e379aa884f91b95003f4ee1 to your computer and use it in GitHub Desktop.
SimplifyNamesPlugin
// This is a hack to just simplify variable namings, because they're ugly, for easier debugging
const HarmonyImportDependency = require('webpack/lib/dependencies/HarmonyImportDependency');
const HarmonyImportSpecifierDependency = require('webpack/lib/dependencies/HarmonyImportSpecifierDependency');
const HarmonyImportSpecifierDependencyTemplate = HarmonyImportSpecifierDependency.Template;
const path = require('path');
const HIDproto = HarmonyImportDependency.prototype;
const HISDTproto = HarmonyImportSpecifierDependencyTemplate.prototype;
const originalGetImportVar = HIDproto.getImportVar;
const originalGetImportStatement = HIDproto.getImportStatement;
const originalGetContent = HISDTproto.getContent;
const DEFAULT_MODULE_VAR_NAME_FN = str => {
return '__' + path.basename(str).replace(/[^a-zA-Z0-9$]+/g, '_');
}
module.exports = class SimplifyNamesPlugin {
constructor(options) {
this.options = options || {};
}
toIdentifier(str, scope) {
if (!str || typeof str !== 'string') return str;
let out = (this.options.moduleVarNameFn || DEFAULT_MODULE_VAR_NAME_FN)(str)
const taken = scope.importVarMapVals || (scope.importVarMapVals = new Set());
if (taken.has(out)) {
let extra = '';
while (taken.has(out + extra)) {
const num = parseInt(extra.substr(1) || '0') + 1;
extra = '_' + num;
}
out = out + extra;
}
taken.add(out);
return out;
}
apply(compiler) {
compiler.hooks.compilation.tap('HarmonyModulesPlugin', (compilation, {normalModuleFactory}) => {
normalModuleFactory.hooks.parser
.for('javascript/auto')
.tap('HarmonyModulesPlugin', (parser, parserOptions) => {
parser.hooks.importSpecifier.tap('HarmonyImportDependencyParserPlugin', (statement, source) => {
const deps = parser.state.module.dependencies;
deps[deps.length - 1].statement = statement;
});
});
});
if (HIDproto.getImportVar === originalGetImportVar) {
const self = this;
HIDproto.getImportVar = function() {
let importVarMap = this.parserScope.importVarMap;
if (!importVarMap) this.parserScope.importVarMap = importVarMap = new Map();
let importVar = importVarMap.get(this.module);
if (importVar) return importVar;
importVar = self.toIdentifier(this.userRequest, this.parserScope);
importVarMap.set(this.module, importVar);
return importVar;
}
HIDproto.getImportStatement = function() {
const orig = originalGetImportStatement.apply(this, arguments).replace('/* harmony import */ ', '');
const specifiers = this.statement && this.statement.specifiers;
if (specifiers) {
const importSpecifiers = specifiers.filter(s => s.type === 'ImportSpecifier');
const importVars = importSpecifiers.map(s => {
if (!s.imported)
return null
if (!s.local || s.local.name === s.imported.name)
return s.imported.name;
return s.imported.name + ':' + s.local.name
}).filter(x => !!x)
const defaultSpecifier = specifiers.find(s => s.type === 'ImportDefaultSpecifier');
let last = ''
const vals = [...this.parserScope.importVarMap.values()]
const moduleName = [...vals][vals.length - 1]
if (defaultSpecifier) {
const name = defaultSpecifier.local.name
importVars.push('default:' + name);
last = `;if(typeof ${name}==="undefined")${name}=${moduleName}`
}
return `${orig.substr(0, orig.length - 1)}let {${importVars.join(',')}} = ${moduleName}${last};\n`;
}
return orig;
};
HISDTproto.getContent = function() {
const orig = originalGetContent.apply(this, arguments);
let out = orig;
if (orig.startsWith('Object('))
out = orig.substr(7, orig.length - 8);
const match = out.match(/^(.+)\["([^\]]+)"]$/);
if (match) {
const legalId = match[2].match(/^[a-zA-Z][a-zA-Z0-9$]*$/);
if (legalId) {
out = match[1] + '.' + match[2];
}
}
return out;
};
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment