parse.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. exports.parseWxsCode = exports.parseWxsNodes = exports.parseBlockCode = exports.parseVueCode = void 0;
  7. const magic_string_1 = __importDefault(require("magic-string"));
  8. const ast_1 = require("../vite/utils/ast");
  9. const BLOCK_RE = /<\/block>/;
  10. const WXS_LANG_RE = /lang=["|'](renderjs|wxs|sjs)["|']/;
  11. const WXS_ATTRS = ['wxs', 'renderjs', 'sjs'];
  12. function parseVueCode(code, isNVue = false) {
  13. const hasBlock = BLOCK_RE.test(code);
  14. const hasWxs = WXS_LANG_RE.test(code);
  15. if (!hasBlock && !hasWxs) {
  16. return { code };
  17. }
  18. const errors = [];
  19. const files = [];
  20. let ast = (0, ast_1.parseVue)(code, errors);
  21. if (hasBlock) {
  22. code = parseBlockCode(ast, code);
  23. // 重新解析新的 code
  24. ast = (0, ast_1.parseVue)(code, errors);
  25. }
  26. if (!isNVue && hasWxs) {
  27. const wxsNodes = parseWxsNodes(ast);
  28. code = parseWxsCode(wxsNodes, code);
  29. // add watch
  30. for (const wxsNode of wxsNodes) {
  31. const srcProp = wxsNode.props.find((prop) => prop.type === 6 /* NodeTypes.ATTRIBUTE */ && prop.name === 'src');
  32. if (srcProp && srcProp.value) {
  33. files.push(srcProp.value.content);
  34. }
  35. }
  36. }
  37. return { code, files, errors };
  38. }
  39. exports.parseVueCode = parseVueCode;
  40. function traverseChildren({ children }, blockNodes) {
  41. children.forEach((node) => traverseNode(node, blockNodes));
  42. }
  43. function traverseNode(node, blockNodes) {
  44. if ((0, ast_1.isElementNode)(node) && node.tag === 'block') {
  45. blockNodes.push(node);
  46. }
  47. if (node.type === 10 /* NodeTypes.IF_BRANCH */ ||
  48. node.type === 11 /* NodeTypes.FOR */ ||
  49. node.type === 1 /* NodeTypes.ELEMENT */ ||
  50. node.type === 0 /* NodeTypes.ROOT */) {
  51. traverseChildren(node, blockNodes);
  52. }
  53. }
  54. function parseBlockCode(ast, code) {
  55. const blockNodes = [];
  56. traverseNode(ast, blockNodes);
  57. if (blockNodes.length) {
  58. return parseBlockNode(code, blockNodes);
  59. }
  60. return code;
  61. }
  62. exports.parseBlockCode = parseBlockCode;
  63. const BLOCK_END_LEN = '</block>'.length;
  64. const BLOCK_START_LEN = '<block'.length;
  65. function parseBlockNode(code, blocks) {
  66. const magicString = new magic_string_1.default(code);
  67. blocks.forEach(({ loc }) => {
  68. const startOffset = loc.start.offset;
  69. const endOffset = loc.end.offset;
  70. magicString.overwrite(startOffset, startOffset + BLOCK_START_LEN, '<template');
  71. magicString.overwrite(endOffset - BLOCK_END_LEN, endOffset, '</template>');
  72. });
  73. return magicString.toString();
  74. }
  75. function parseWxsNodes(ast) {
  76. return ast.children.filter((node) => node.type === 1 /* NodeTypes.ELEMENT */ &&
  77. node.tag === 'script' &&
  78. node.props.find((prop) => prop.name === 'lang' &&
  79. prop.type === 6 /* NodeTypes.ATTRIBUTE */ &&
  80. prop.value &&
  81. WXS_ATTRS.includes(prop.value.content)));
  82. }
  83. exports.parseWxsNodes = parseWxsNodes;
  84. function parseWxsCode(wxsNodes, code) {
  85. if (wxsNodes.length) {
  86. code = parseWxsNode(code, wxsNodes);
  87. }
  88. return code;
  89. }
  90. exports.parseWxsCode = parseWxsCode;
  91. const SCRIPT_END_LEN = '</script>'.length;
  92. const SCRIPT_START_LEN = '<script'.length;
  93. function parseWxsNode(code, nodes) {
  94. const magicString = new magic_string_1.default(code);
  95. nodes.forEach(({ loc, props }) => {
  96. const langAttr = props.find((prop) => prop.name === 'lang');
  97. const moduleAttr = props.find((prop) => prop.name === 'module');
  98. const startOffset = loc.start.offset;
  99. const endOffset = loc.end.offset;
  100. const lang = langAttr.value.content;
  101. const langStartOffset = langAttr.loc.start.offset;
  102. magicString.overwrite(startOffset, startOffset + SCRIPT_START_LEN, '<' + lang); // <renderjs or <wxs
  103. magicString.overwrite(langStartOffset, langStartOffset + ('lang="' + lang + '"').length, ''); // remove lang="renderjs" or lang="wxs"
  104. magicString.overwrite(endOffset - SCRIPT_END_LEN, endOffset, '</' + lang + '>'); //</renderjs> or </wxs>
  105. if (moduleAttr) {
  106. const moduleStartOffset = moduleAttr.loc.start.offset;
  107. magicString.overwrite(moduleStartOffset, moduleStartOffset + 'module'.length, 'name'); // module="echarts" => name="echarts"
  108. }
  109. });
  110. return magicString.toString();
  111. }