You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
7.5 KiB
203 lines
7.5 KiB
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
exports.default = function (_ref) {
|
|
var t = _ref.types;
|
|
|
|
var cache = {};
|
|
var modelPaths = {};
|
|
|
|
function getImportRequirePath(identifierName, scope) {
|
|
if (scope.hasBinding(identifierName)) {
|
|
var binding = scope.bindings[identifierName];
|
|
if (binding) {
|
|
var parent = binding.path.parent;
|
|
|
|
if (t.isImportDeclaration(parent)) {
|
|
return parent.source.value;
|
|
} else if (t.isVariableDeclaration(parent)) {
|
|
var declarator = findDeclarator(parent.declarations, identifierName);
|
|
if (declarator) {
|
|
if (isRequire(declarator.init)) {
|
|
return getArguments0(declarator.init);
|
|
} else if (isRequireDefault(declarator.init)) {
|
|
return getArguments0(declarator.init.object);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function isDvaCallExpression(node, scope) {
|
|
return t.isCallExpression(node) && t.isIdentifier(node.callee) && getImportRequirePath(node.callee.name, scope) === 'dva';
|
|
}
|
|
|
|
function isDvaInstance(identifierName, scope) {
|
|
if (scope.hasBinding(identifierName)) {
|
|
var binding = scope.bindings[identifierName];
|
|
if (binding) {
|
|
var parent = binding.path.parent;
|
|
if (t.isVariableDeclaration(parent)) {
|
|
var declarator = findDeclarator(parent.declarations, identifierName);
|
|
if (declarator && isDvaCallExpression(declarator.init, scope)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function isRouterCall(node, scope) {
|
|
if (!t.isMemberExpression(node)) return false;
|
|
var object = node.object,
|
|
property = node.property;
|
|
|
|
return t.isIdentifier(property) && property.name === 'router' && t.isIdentifier(object) && isDvaInstance(object.name, scope);
|
|
}
|
|
|
|
function isModelCall(node, scope) {
|
|
if (!t.isMemberExpression(node)) return false;
|
|
var object = node.object,
|
|
property = node.property;
|
|
|
|
return t.isIdentifier(property) && property.name === 'model' && t.isIdentifier(object) && isDvaInstance(object.name, scope);
|
|
}
|
|
|
|
function isRequire(node) {
|
|
return t.isCallExpression(node) && t.isIdentifier(node.callee) && node.callee.name === 'require';
|
|
}
|
|
|
|
function isRequireDefault(node) {
|
|
if (!t.isMemberExpression(node)) return false;
|
|
var object = node.object,
|
|
property = node.property;
|
|
|
|
return isRequire(object) && t.isIdentifier(property) && property.name === 'default';
|
|
}
|
|
|
|
function findDeclarator(declarations, identifier) {
|
|
var _iteratorNormalCompletion = true;
|
|
var _didIteratorError = false;
|
|
var _iteratorError = undefined;
|
|
|
|
try {
|
|
for (var _iterator = declarations[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
var d = _step.value;
|
|
|
|
if (t.isIdentifier(d.id) && d.id.name === identifier) {
|
|
return d;
|
|
}
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError = true;
|
|
_iteratorError = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion && _iterator.return) {
|
|
_iterator.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError) {
|
|
throw _iteratorError;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function getArguments0(node) {
|
|
if (t.isLiteral(node.arguments[0])) {
|
|
return node.arguments[0].value;
|
|
}
|
|
}
|
|
|
|
function getRequirePath(node, scope) {
|
|
switch (node.type) {
|
|
case 'CallExpression':
|
|
{
|
|
var path = getArguments0(node);
|
|
if (path) {
|
|
return path;
|
|
}
|
|
break;
|
|
}
|
|
case 'Identifier':
|
|
{
|
|
var _path = getImportRequirePath(node.name, scope);
|
|
if (_path) {
|
|
return _path;
|
|
}
|
|
break;
|
|
}
|
|
case 'MemberExpression':
|
|
{
|
|
if (isRequireDefault(node)) {
|
|
var _path2 = getArguments0(node.object);
|
|
if (_path2) {
|
|
return _path2;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return {
|
|
visitor: {
|
|
Program: {
|
|
enter: function enter(path) {
|
|
var filename = path.hub.file.opts.filename;
|
|
|
|
delete cache[filename];
|
|
}
|
|
},
|
|
CallExpression: function CallExpression(path, state) {
|
|
var opts = state.opts;
|
|
|
|
var _ref2 = path && path.hub && path.hub.file && path.hub.file.opts || state && state.file,
|
|
filename = _ref2.filename;
|
|
|
|
if (cache[filename]) return;
|
|
var _path$node = path.node,
|
|
callee = _path$node.callee,
|
|
args = _path$node.arguments;
|
|
|
|
if (isRouterCall(callee, path.scope)) {
|
|
var routerPath = getRequirePath(args[0], path.scope);
|
|
if (routerPath) {
|
|
cache[filename] = true;
|
|
!opts.quiet && console.info('[babel-plugin-dva-hmr][INFO] got routerPath ' + routerPath);
|
|
path.parentPath.replaceWithSourceString(getHmrString(callee.object.name, routerPath, modelPaths[filename], opts.container, !opts.disableModel));
|
|
} else {
|
|
!opts.quiet && console.warn('[babel-plugin-dva-hmr][WARN] can\'t get router path in ' + filename);
|
|
}
|
|
} else if (isModelCall(callee, path.scope)) {
|
|
modelPaths[filename] = modelPaths[filename] || [];
|
|
modelPaths[filename].push(getRequirePath(args[0], path.scope));
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
var _path3 = require('path');
|
|
|
|
function getHmrString(appName, routerPath) {
|
|
var modelPaths = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
var container = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '#root';
|
|
var enableModel = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
|
|
var modelHot = enableModel ? modelPaths.map(function (modelPath) {
|
|
return '\n if (module.hot) {\n const modelNamespaceMap = {};\n let model = require(\'' + modelPath + '\');\n if (model.default) model = model.default;\n modelNamespaceMap[\'' + modelPath + '\'] = model.namespace;\n module.hot.accept(\'' + modelPath + '\', () => {\n try {\n app.unmodel(modelNamespaceMap[\'' + modelPath + '\']);\n let model = require(\'' + modelPath + '\');\n if (model.default) model = model.default;\n app.model(model);\n } catch(e) { console.error(e); }\n });\n }\n';
|
|
}).join('\n') : '';
|
|
return '\n(function() {\n // Generated by babel-plugin-dva-hmr\n console.log(\'[HMR] inited with babel-plugin-dva-hmr\');\n const router = require(\'' + routerPath + '\');\n ' + appName + '.router(router.default || router);\n ' + appName + '.use({\n onHmr(render) {\n if (module.hot) {\n const renderNormally = render;\n const renderException = (error) => {\n const RedBox = require(\'redbox-react\');\n ReactDOM.render(React.createElement(RedBox, { error: error }), document.querySelector(\'' + container + '\'));\n };\n const newRender = (router) => {\n try {\n renderNormally(router);\n } catch (error) {\n console.error(\'error\', error);\n renderException(error);\n }\n };\n module.hot.accept(\'' + routerPath + '\', () => {\n const router = require(\'' + routerPath + '\');\n newRender(router.default || router);\n });\n }\n },\n });\n ' + modelHot + '\n})()\n ';
|
|
}
|
|
|
|
module.exports = exports['default']; |