SimplifyNamesPlugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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