如何解决Webpack无法调试`import ... from ...`变量;如何使webpack保持`import from`变量名
例如,我的代码是
import React from "react"
var node = <div></div>
当我在var node = <div></div>
行的chrome devtools中设置断点时,它会引发错误:
VM183:1 Uncaught ReferenceError: React is not defined
我知道原因是因为webpack从“ react”编译`import React,{createRef};遵循以下代码
var react_1 = __importStar(__webpack_require__(/*! react */ "./node_modules/react/index.js"));
但是我不知道如何预防
如何解决?
解决方法
更新:
我发现以下问题:
https://github.com/webpack/webpack/issues/3957
最后,它提供了一个自定义的webpack插件,应该修复
https://gist.github.com/staeke/f197ff144e379aa884f91b95003f4ee1
完整代码在这里:
import {App} from "../src/App";
in webpack output become
var App_1 = __webpack_require__(/*! ../src/App */ "./src/App.tsx");
update:
the solution is make webpack plugin to hack webpack compiler(make webpack don't rename import from variable name)
https://gist.github.com/staeke/f197ff144e379aa884f91b95003f4ee1
the full webpack plugin code:
// 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;
};
}
}
};
旧:
我的tmp解决方案是,在使用打字稿时,使用const varName = require("path/to/lib")
而不是import varName from "path/to/lib"
它将起作用
但是我仍然想从import from
中找到一种支持debug var的方法(因为大多数代码样式是import from
而不是const require
)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。