resolveWcEntry.js 2.1 KB

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