You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
2.1 KiB
67 lines
2.1 KiB
const path = require('path') |
|
|
|
const camelizeRE = /-(\w)/g |
|
const camelize = str => { |
|
return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '') |
|
} |
|
|
|
const hyphenateRE = /\B([A-Z])/g |
|
const hyphenate = str => { |
|
return str.replace(hyphenateRE, '-$1').toLowerCase() |
|
} |
|
|
|
/** |
|
* Creates the script to add the component to the custom elements |
|
* @param {string} prefix The prefix for the component library |
|
* @param {string} component The component name for single entry builds, component file for multi-entry builds |
|
* @param {string} file The file for the component |
|
* @param {boolean} isAsync Whether to load component async or not |
|
*/ |
|
const createElement = (prefix, component, file, isAsync) => { |
|
const { camelName, kebabName } = exports.fileToComponentName(prefix, component) |
|
|
|
return isAsync |
|
? `window.customElements.define('${kebabName}', wrap(Vue, () => import('~root/${file}?shadow')))\n` |
|
: `import ${camelName} from '~root/${file}?shadow'\n` + |
|
`window.customElements.define('${kebabName}', wrap(Vue, ${camelName}))\n` |
|
} |
|
|
|
exports.fileToComponentName = (prefix, file) => { |
|
const basename = path.basename(file).replace(/\.(jsx?|vue)$/, '') |
|
const camelName = camelize(basename) |
|
const kebabName = `${prefix ? `${prefix}-` : ``}${hyphenate(basename)}` |
|
return { |
|
basename, |
|
camelName, |
|
kebabName |
|
} |
|
} |
|
|
|
exports.resolveEntry = (prefix, libName, files, isAsync) => { |
|
const filePath = path.resolve(__dirname, 'entry-wc.js') |
|
const elements = |
|
prefix === '' |
|
? [createElement('', libName, files[0])] |
|
: files.map(file => createElement(prefix, file, file, isAsync)).join('\n') |
|
|
|
function resolveImportPath (mod) { |
|
return require.resolve(mod).replace(/\\/g, '\\\\') |
|
} |
|
|
|
const content = ` |
|
import './setPublicPath' |
|
import Vue from 'vue' |
|
import wrap from '@vue/web-component-wrapper' |
|
|
|
// runtime shared by every component chunk |
|
import '${resolveImportPath('css-loader/dist/runtime/api.js')}' |
|
import '${resolveImportPath('vue-style-loader/lib/addStylesShadow')}' |
|
import '${resolveImportPath('@vue/vue-loader-v15/lib/runtime/componentNormalizer')}' |
|
|
|
${elements}`.trim() |
|
|
|
return { |
|
filePath: filePath, |
|
content: content |
|
} |
|
}
|
|
|