resolveWcEntry.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. const fs = require('fs')
  2. const path = require('path')
  3. const camelizeRE = /-(\w)/g
  4. const camelize = str => {
  5. return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
  6. }
  7. const hyphenateRE = /\B([A-Z])/g
  8. const hyphenate = str => {
  9. return str.replace(hyphenateRE, '-$1').toLowerCase()
  10. }
  11. /**
  12. * Creates the script to add the component to the custom elements
  13. * @param {string} prefix The prefix for the component library
  14. * @param {string} component The component name for single entry builds, component file for multi-entry builds
  15. * @param {string} file The file for the component
  16. * @param {boolean} async Whether to load component async or not
  17. */
  18. const createElement = (prefix, component, file, async) => {
  19. const { camelName, kebabName } = exports.fileToComponentName(prefix, component)
  20. return async
  21. ? `window.customElements.define('${kebabName}', wrap(Vue, () => import('~root/${file}?shadow')))\n`
  22. : `import ${camelName} from '~root/${file}?shadow'\n` +
  23. `window.customElements.define('${kebabName}', wrap(Vue, ${camelName}))\n`
  24. }
  25. exports.fileToComponentName = (prefix, file) => {
  26. const basename = path.basename(file).replace(/\.(jsx?|vue)$/, '')
  27. const camelName = camelize(basename)
  28. const kebabName = `${prefix ? `${prefix}-` : ``}${hyphenate(basename)}`
  29. return {
  30. basename,
  31. camelName,
  32. kebabName
  33. }
  34. }
  35. exports.resolveEntry = (prefix, libName, files, async) => {
  36. const filePath = path.resolve(__dirname, 'entry-wc.js')
  37. const elements =
  38. prefix === ''
  39. ? [createElement('', libName, files[0])]
  40. : files.map(file => createElement(prefix, file, file, async)).join('\n')
  41. const content = `
  42. import './setPublicPath'
  43. import Vue from 'vue'
  44. import wrap from '@vue/web-component-wrapper'
  45. // runtime shared by every component chunk
  46. import 'css-loader/lib/css-base'
  47. import 'vue-style-loader/lib/addStylesShadow'
  48. import 'vue-loader/lib/runtime/componentNormalizer'
  49. ${elements}`.trim()
  50. fs.writeFileSync(filePath, content)
  51. return filePath
  52. }