util.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /* eslint-disable @typescript-eslint/no-var-requires */
  2. const { compileTemplate, TemplateCompiler } = require('@vue/compiler-sfc');
  3. function stripScript(content) {
  4. const result = content.match(/<(script)>([\s\S]+)<\/\1>/);
  5. return result && result[2] ? result[2].trim() : '';
  6. }
  7. function stripStyle(content) {
  8. const result = content.match(/<(style)\s*>([\s\S]+)<\/\1>/);
  9. return result && result[2] ? result[2].trim() : '';
  10. }
  11. // 编写例子时不一定有 template。所以采取的方案是剔除其他的内容
  12. function stripTemplate(content) {
  13. content = content.trim();
  14. if (!content) {
  15. return content;
  16. }
  17. return content.replace(/<(script|style)[\s\S]+<\/\1>/g, '').trim();
  18. }
  19. function pad(source) {
  20. return source
  21. .split(/\r?\n/)
  22. .map(line => ` ${line}`)
  23. .join('\n');
  24. }
  25. const templateReplaceRegex = /<template>([\s\S]+)<\/template>/g;
  26. function genInlineComponentText(template, script) {
  27. // https://github.com/vuejs/vue-loader/blob/423b8341ab368c2117931e909e2da9af74503635/lib/loaders/templateLoader.js#L46
  28. let source = template;
  29. if (templateReplaceRegex.test(source)) {
  30. source = source.replace(templateReplaceRegex, '$1');
  31. }
  32. const finalOptions = {
  33. source: `<div>${source}</div>`,
  34. filename: 'inline-component', // TODO:这里有待调整
  35. compiler: TemplateCompiler,
  36. compilerOptions: {
  37. mode: 'function'
  38. }
  39. };
  40. const compiled = compileTemplate(finalOptions);
  41. // tips
  42. if (compiled.tips && compiled.tips.length) {
  43. compiled.tips.forEach(tip => {
  44. console.warn(tip);
  45. });
  46. }
  47. // errors
  48. if (compiled.errors && compiled.errors.length) {
  49. console.error(`\n Error compiling template:\n${pad(compiled.source)}\n` + compiled.errors.map(e => ` - ${e}`).join('\n') + '\n');
  50. }
  51. let demoComponentContent = `
  52. ${compiled.code.replace('return function render', 'function render')}
  53. `;
  54. // todo: 这里采用了硬编码有待改进
  55. script = script.trim();
  56. if (script) {
  57. script = script.replace(/export\s+default/, 'const democomponentExport =').replace(/import ({.*}) from 'vue'/g, (s, s1) => `const ${s1} = Vue`);
  58. } else {
  59. script = 'const democomponentExport = {}';
  60. }
  61. demoComponentContent = `(function() {
  62. ${demoComponentContent}
  63. ${script}
  64. return {
  65. render,
  66. ...democomponentExport
  67. }
  68. })()`;
  69. return demoComponentContent;
  70. }
  71. module.exports = {
  72. stripScript,
  73. stripStyle,
  74. stripTemplate,
  75. genInlineComponentText
  76. };