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.
		
		
		
		
			
				
					129 lines
				
				3.7 KiB
			
		
		
			
		
	
	
					129 lines
				
				3.7 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								const path = require('path')
							 | 
						||
| 
								 | 
							
								const { resolveEntry, fileToComponentName } = require('./resolveWcEntry')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = (api, { target, entry, name, 'inline-vue': inlineVue }) => {
							 | 
						||
| 
								 | 
							
								  // Disable CSS extraction and turn on CSS shadow mode for vue-style-loader
							 | 
						||
| 
								 | 
							
								  process.env.VUE_CLI_CSS_SHADOW_MODE = true
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const { log, error } = require('@vue/cli-shared-utils')
							 | 
						||
| 
								 | 
							
								  const abort = msg => {
							 | 
						||
| 
								 | 
							
								    log()
							 | 
						||
| 
								 | 
							
								    error(msg)
							 | 
						||
| 
								 | 
							
								    process.exit(1)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const isAsync = /async/.test(target)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // generate dynamic entry based on glob files
							 | 
						||
| 
								 | 
							
								  const resolvedFiles = require('globby').sync(entry.split(','), { cwd: api.resolve('.') })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!resolvedFiles.length) {
							 | 
						||
| 
								 | 
							
								    abort(`entry pattern "${entry}" did not match any files.`)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  let libName
							 | 
						||
| 
								 | 
							
								  let prefix
							 | 
						||
| 
								 | 
							
								  if (resolvedFiles.length === 1) {
							 | 
						||
| 
								 | 
							
								    // in single mode, determine the lib name from filename
							 | 
						||
| 
								 | 
							
								    libName = name || fileToComponentName('', resolvedFiles[0]).kebabName
							 | 
						||
| 
								 | 
							
								    prefix = ''
							 | 
						||
| 
								 | 
							
								    if (libName.indexOf('-') < 0) {
							 | 
						||
| 
								 | 
							
								      abort(`--name must contain a hyphen when building a single web component.`)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    // multi mode
							 | 
						||
| 
								 | 
							
								    libName = prefix = (name || api.service.pkg.name)
							 | 
						||
| 
								 | 
							
								    if (!libName) {
							 | 
						||
| 
								 | 
							
								      abort(`--name is required when building multiple web components.`)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const dynamicEntry = resolveEntry(prefix, libName, resolvedFiles, isAsync)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function genConfig (minify, genHTML) {
							 | 
						||
| 
								 | 
							
								    const config = api.resolveChainableWebpackConfig()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // make sure not to transpile wc-wrapper
							 | 
						||
| 
								 | 
							
								    config.module
							 | 
						||
| 
								 | 
							
								      .rule('js')
							 | 
						||
| 
								 | 
							
								        .exclude
							 | 
						||
| 
								 | 
							
								          .add(/vue-wc-wrapper/)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // only minify min entry
							 | 
						||
| 
								 | 
							
								    if (!minify) {
							 | 
						||
| 
								 | 
							
								      config.optimization.minimize(false)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    config
							 | 
						||
| 
								 | 
							
								      .plugin('web-component-options')
							 | 
						||
| 
								 | 
							
								        .use(require('webpack').DefinePlugin, [{
							 | 
						||
| 
								 | 
							
								          'process.env.CUSTOM_ELEMENT_NAME': JSON.stringify(libName)
							 | 
						||
| 
								 | 
							
								        }])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // enable shadow mode in vue-loader
							 | 
						||
| 
								 | 
							
								    config.module
							 | 
						||
| 
								 | 
							
								      .rule('vue')
							 | 
						||
| 
								 | 
							
								        .use('vue-loader')
							 | 
						||
| 
								 | 
							
								          .tap(options => {
							 | 
						||
| 
								 | 
							
								            options.shadowMode = true
							 | 
						||
| 
								 | 
							
								            return options
							 | 
						||
| 
								 | 
							
								          })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (genHTML) {
							 | 
						||
| 
								 | 
							
								      config
							 | 
						||
| 
								 | 
							
								        .plugin('demo-html')
							 | 
						||
| 
								 | 
							
								          .use(require('html-webpack-plugin'), [{
							 | 
						||
| 
								 | 
							
								            template: path.resolve(__dirname, `./demo-wc.html`),
							 | 
						||
| 
								 | 
							
								            inject: false,
							 | 
						||
| 
								 | 
							
								            filename: 'demo.html',
							 | 
						||
| 
								 | 
							
								            libName,
							 | 
						||
| 
								 | 
							
								            components:
							 | 
						||
| 
								 | 
							
								              prefix === ''
							 | 
						||
| 
								 | 
							
								                ? [libName]
							 | 
						||
| 
								 | 
							
								                : resolvedFiles.map(file => {
							 | 
						||
| 
								 | 
							
								                  return fileToComponentName(prefix, file).kebabName
							 | 
						||
| 
								 | 
							
								                })
							 | 
						||
| 
								 | 
							
								          }])
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // set entry/output last so it takes higher priority than user
							 | 
						||
| 
								 | 
							
								    // configureWebpack hooks
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // set proxy entry for *.vue files
							 | 
						||
| 
								 | 
							
								    config.resolve
							 | 
						||
| 
								 | 
							
								      .alias
							 | 
						||
| 
								 | 
							
								        .set('~root', api.resolve('.'))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const rawConfig = api.resolveWebpackConfig(config)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // externalize Vue in case user imports it
							 | 
						||
| 
								 | 
							
								    rawConfig.externals = [
							 | 
						||
| 
								 | 
							
								      ...(Array.isArray(rawConfig.externals) ? rawConfig.externals : [rawConfig.externals]),
							 | 
						||
| 
								 | 
							
								      { ...(inlineVue || { vue: 'Vue' }) }
							 | 
						||
| 
								 | 
							
								    ].filter(Boolean)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const entryName = `${libName}${minify ? `.min` : ``}`
							 | 
						||
| 
								 | 
							
								    rawConfig.entry = {
							 | 
						||
| 
								 | 
							
								      [entryName]: dynamicEntry
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Object.assign(rawConfig.output, {
							 | 
						||
| 
								 | 
							
								      // to ensure that multiple copies of async wc bundles can co-exist
							 | 
						||
| 
								 | 
							
								      // on the same page.
							 | 
						||
| 
								 | 
							
								      jsonpFunction: libName.replace(/-\w/g, c => c.charAt(1).toUpperCase()) + '_jsonp',
							 | 
						||
| 
								 | 
							
								      filename: `${entryName}.js`,
							 | 
						||
| 
								 | 
							
								      chunkFilename: `${libName}.[name]${minify ? `.min` : ``}.js`,
							 | 
						||
| 
								 | 
							
								      // use dynamic publicPath so this can be deployed anywhere
							 | 
						||
| 
								 | 
							
								      // the actual path will be determined at runtime by checking
							 | 
						||
| 
								 | 
							
								      // document.currentScript.src.
							 | 
						||
| 
								 | 
							
								      publicPath: ''
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return rawConfig
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return [
							 | 
						||
| 
								 | 
							
								    genConfig(false, true),
							 | 
						||
| 
								 | 
							
								    genConfig(true, false)
							 | 
						||
| 
								 | 
							
								  ]
							 | 
						||
| 
								 | 
							
								}
							 |