Skip to content

Commit

Permalink
feat: vue build --target multi-wc [pattern]
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Feb 1, 2018
1 parent 1c4943b commit 0f59c03
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 36 deletions.
1 change: 1 addition & 0 deletions packages/@vue/cli-service/lib/commands/build/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
entry-multi-wc.js
8 changes: 8 additions & 0 deletions packages/@vue/cli-service/lib/commands/build/entry-wc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Vue from 'vue'
import wrap from '@vue/web-component-wrapper'
import Component from '~entry'

window.customElements.define(
process.env.CUSTOM_ELEMENT_NAME,
wrap(Vue, Component)
)

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const fs = require('fs')
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()
}

module.exports = function generateMultiWebComponentEntry (prefix, files) {
const filePath = path.resolve(__dirname, 'entry-multi-wc.js')
const content = `
import Vue from 'vue'
import wrap from '@vue/web-component-wrapper'
${files.map(file => {
const basename = path.basename(file).replace(/\.(jsx?|vue)$/, '')
const camelName = camelize(basename)
const kebabName = hyphenate(basename)
return (
`import ${camelName} from '~root/${file}'\n` +
`window.customElements.define('${prefix}-${kebabName}', wrap(Vue, ${camelName}))\n`
)
}).join('\n')}`.trim()
fs.writeFileSync(filePath, content)
return filePath
}
15 changes: 10 additions & 5 deletions packages/@vue/cli-service/lib/commands/build/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,22 @@ const defaults = {
module.exports = (api, options) => {
api.registerCommand('build', {
description: 'build for production',
usage: 'vue-cli-service build [options]',
usage: 'vue-cli-service build [options] [entry|pattern]',
options: {
'--mode': `specify env mode (default: ${defaults.mode})`,
'--dest': `specify output directory (default: ${options.outputDir})`,
'--target': `app | lib | web-component (default: ${defaults.target})`,
'--entry': `entry for lib or web-component (default: ${defaults.entry})`,
'--name': `name for lib or web-component (default: "name" in package.json or entry filename)`
'--target': `app | lib | wc | multi-wc (default: ${defaults.target})`,
'--name': `name for lib or (multi-)web-component mode (default: "name" in package.json or entry filename)`
}
}, args => {
args.entry = args._[0]
for (const key in defaults) {
if (args[key] == null) args[key] = defaults[key]
}
if (args.dest == null) {
args.dest = options.outputDir
}

api.setMode(args.mode)

const chalk = require('chalk')
Expand Down Expand Up @@ -51,7 +52,11 @@ module.exports = (api, options) => {
let webpackConfig
if (args.target === 'lib') {
webpackConfig = require('./resolveLibConfig')(api, args, options)
} else if (args.target === 'web-component' || args.target === 'wc') {
} else if (
args.target === 'web-component' ||
args.target === 'wc' ||
args.target === 'multi-wc'
) {
webpackConfig = require('./resolveWebComponentConfig')(api, args, options)
} else {
webpackConfig = api.resolveWebpackConfig()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
const path = require('path')

module.exports = (api, { entry, name, dest }) => {
const libName = name || api.service.pkg.name || entry.replace(/\.(js|vue)$/, '')
if (libName.indexOf('-') < 0) {
const { log, error } = require('@vue/cli-shared-utils')
module.exports = (api, { target, entry, name, dest, prefix }) => {
const { log, error } = require('@vue/cli-shared-utils')
const abort = msg => {
log()
error(`--name must contain a hyphen when building as web-component. (got "${libName}")`)
error(msg)
process.exit(1)
}

const libName = name || api.service.pkg.name || entry.replace(/\.(js|vue)$/, '')
if (libName.indexOf('-') < 0 && target !== 'multi-wc') {
abort(`--name must contain a hyphen with --target web-component. (got "${libName}")`)
}

let dynamicEntry
if (target === 'multi-wc') {
if (!entry) {
abort(`a glob pattern is required with --target multi-web-component.`)
}
// generate dynamic entry based on glob files
const files = require('globby').sync([entry], { cwd: api.resolve('.') })
if (!files.length) {
abort(`glob pattern "${entry}" did not match any files.`)
}
dynamicEntry = require('./generateMultiWcEntry')(libName, files)
}

// setting this disables app-only configs
process.env.VUE_CLI_TARGET = 'web-component'
// inline all static asset files since there is no publicPath handling
Expand All @@ -20,18 +37,22 @@ module.exports = (api, { entry, name, dest }) => {
const config = api.resolveChainableWebpackConfig()

config.entryPoints.clear()

// set proxy entry for *.vue files
if (/\.vue$/.test(entry)) {
if (target === 'multi-wc') {
config
.entry(`${libName}${minify ? `.min` : ``}`)
.add(require.resolve('./entry-web-component.js'))
.entry(`${libName}${minify ? `.min` : ``}`)
.add(dynamicEntry)
config.resolve
.alias
.set('~entry', api.resolve(entry))
.alias
.set('~root', api.resolve('.'))
} else {
config
.entry(`${libName}${minify ? `.min` : ``}`)
.add(api.resolve(entry))
.entry(`${libName}${minify ? `.min` : ``}`)
.add(require.resolve('./entry-wc.js'))
config.resolve
.alias
.set('~entry', api.resolve(entry))
}

// only minify min entry
Expand Down Expand Up @@ -70,7 +91,7 @@ module.exports = (api, { entry, name, dest }) => {
config
.plugin('demo-html')
.use(require('html-webpack-plugin'), [{
template: path.resolve(__dirname, './demo-web-component.html'),
template: path.resolve(__dirname, './demo-wc.html'),
inject: false,
filename: 'demo.html',
libName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const TYPE = 'cant-resolve-loader'
const errorRE = /Can't resolve '(.*loader)'/

exports.transformer = error => {
if (error.webpackError) {
if (error.webpackError && error.webpackError.message) {
const match = error.webpackError.message.match(errorRE)
if (match) {
return Object.assign({}, error, {
Expand Down
3 changes: 2 additions & 1 deletion packages/@vue/cli-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"file-loader": "^1.1.6",
"friendly-errors-webpack-plugin": "^1.6.1",
"get-value": "^2.0.6",
"globby": "^7.1.1",
"html-webpack-plugin": "^2.30.1",
"javascript-stringify": "^1.6.0",
"launch-editor-middleware": "^2.2.0",
Expand All @@ -55,7 +56,7 @@
"thread-loader": "^1.1.2",
"uglifyjs-webpack-plugin": "^1.1.6",
"url-loader": "^0.6.2",
"vue-loader": "^14.0.3",
"vue-loader": "^14.1.0",
"vue-template-compiler": "^2.5.13",
"webpack": "^3.10.0",
"webpack-chain": "^4.5.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/@vue/cli/bin/vue.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ program

program
.command('build [entry]')
.option('-t, --target <target>', 'Build target (app | lib | web-component, default: app)')
.option('-t, --target <target>', 'Build target (app | lib | wc, default: app)')
.option('-n, --name <name>', 'name for lib or web-component (default: entry filename)')
.option('-d, --dest <dir>', 'output directory (default: dist)')
.description('build a .js or .vue file in production mode with zero config')
Expand Down
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10077,9 +10077,9 @@ vue-jest@^2.0.0:
tsconfig "^7.0.0"
vue-template-es2015-compiler "^1.5.3"

vue-loader@^14.0.3:
version "14.0.3"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-14.0.3.tgz#26df42fb2a40e21e9799eb1adc15fff763b99bd2"
vue-loader@^14.1.0:
version "14.1.0"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-14.1.0.tgz#ae31d62a11421061fca8bac30cbc15875df886d3"
dependencies:
consolidate "^0.14.0"
hash-sum "^1.0.2"
Expand Down

0 comments on commit 0f59c03

Please sign in to comment.