util.js 2.6 KB

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