plugin.ts 3.2 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1
import path from 'path'
fxy060608's avatar
fxy060608 已提交
2 3
import type { Plugin } from 'vite'
import { extend, isArray, isString, isFunction } from '@vue/shared'
fxy060608's avatar
fxy060608 已提交
4
import { isCustomElement, isNativeTag } from '@dcloudio/uni-shared'
fxy060608's avatar
fxy060608 已提交
5 6 7 8 9
import type {
  CopyOptions,
  UniViteCopyPluginTarget,
  UniVitePlugin,
} from '@dcloudio/uni-cli-shared'
fxy060608's avatar
fxy060608 已提交
10
import { TemplateCompiler } from '@vue/compiler-sfc'
fxy060608's avatar
fxy060608 已提交
11 12 13 14 15 16 17 18 19 20 21

interface PluginConfig {
  id: string
  name: string
  apply?: UniApp.PLATFORM | UniApp.PLATFORM[]
  config: {
    name: string
    main?: string
  }
}

fxy060608's avatar
fxy060608 已提交
22
export function initPluginUniOptions(UniVitePlugins: UniVitePlugin[]) {
fxy060608's avatar
fxy060608 已提交
23
  const assets: string[] = []
fxy060608's avatar
fxy060608 已提交
24
  const targets: UniViteCopyPluginTarget[] = []
fxy060608's avatar
fxy060608 已提交
25
  const transformEvent: Record<string, string> = Object.create(null)
fxy060608's avatar
fxy060608 已提交
26
  const compilerOptions: Required<UniVitePlugin>['uni']['compilerOptions'] = {
fxy060608's avatar
fxy060608 已提交
27 28 29
    isNativeTag,
    isCustomElement,
  }
fxy060608's avatar
fxy060608 已提交
30
  let compiler: TemplateCompiler | undefined
fxy060608's avatar
fxy060608 已提交
31 32
  UniVitePlugins.forEach((plugin) => {
    const {
fxy060608's avatar
fxy060608 已提交
33
      compiler: pluginTemplateCompiler,
fxy060608's avatar
fxy060608 已提交
34
      copyOptions: pluginCopyOptions,
fxy060608's avatar
fxy060608 已提交
35 36 37
      compilerOptions: pluginCompilerOptions,
      transformEvent: pluginTransformEvent,
    } = plugin.uni || {}
fxy060608's avatar
fxy060608 已提交
38 39 40
    if (pluginTemplateCompiler) {
      compiler = pluginTemplateCompiler
    }
fxy060608's avatar
fxy060608 已提交
41
    if (pluginCompilerOptions) {
fxy060608's avatar
fxy060608 已提交
42
      extend(compilerOptions, pluginCompilerOptions)
fxy060608's avatar
fxy060608 已提交
43 44 45 46
    }
    if (pluginTransformEvent) {
      extend(transformEvent, pluginTransformEvent)
    }
fxy060608's avatar
fxy060608 已提交
47 48 49 50 51 52 53 54 55 56 57 58
    if (pluginCopyOptions) {
      let copyOptions = pluginCopyOptions as CopyOptions
      if (isFunction(pluginCopyOptions)) {
        copyOptions = pluginCopyOptions()
      }
      if (copyOptions.assets) {
        assets.push(...copyOptions.assets)
      }
      if (copyOptions.targets) {
        targets.push(...copyOptions.targets)
      }
    }
fxy060608's avatar
fxy060608 已提交
59 60
  })
  return {
fxy060608's avatar
fxy060608 已提交
61
    compiler,
fxy060608's avatar
fxy060608 已提交
62 63 64 65
    copyOptions: {
      assets,
      targets,
    },
fxy060608's avatar
fxy060608 已提交
66 67 68 69 70
    transformEvent,
    compilerOptions,
  }
}

fxy060608's avatar
fxy060608 已提交
71 72 73 74
export function initExtraPlugins(cliRoot: string, platform: UniApp.PLATFORM) {
  return initPlugins(resolvePlugins(cliRoot, platform))
}

fxy060608's avatar
fxy060608 已提交
75 76 77
function initPlugin({ id, config: { main } }: PluginConfig): Plugin | void {
  const plugin = require(path.join(id, main || '/lib/uni.plugin.js'))
  return plugin.default || plugin
fxy060608's avatar
fxy060608 已提交
78 79 80 81 82
}

function initPlugins(plugins: PluginConfig[]): Plugin[] {
  return plugins
    .map((plugin) => initPlugin(plugin))
fxy060608's avatar
fxy060608 已提交
83
    .flat()
fxy060608's avatar
fxy060608 已提交
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
    .filter<Plugin>(Boolean as any)
}

function resolvePlugins(cliRoot: string, platform: UniApp.PLATFORM) {
  const pkg = require(path.join(cliRoot, 'package.json'))
  return Object.keys(pkg.devDependencies || {})
    .concat(Object.keys(pkg.dependencies || {}))
    .map<PluginConfig | void>((id) => {
      try {
        const pluginPkg = require(id + '/package.json')
        const config = pluginPkg['uni-app'] as PluginConfig
        if (!config || !config.name) {
          return
        }
        const { apply } = config
        if (isArray(apply)) {
          if (!apply.includes(platform)) {
            return
          }
        } else if (isString(apply)) {
fxy060608's avatar
fxy060608 已提交
104
          if (!new RegExp(apply).test(platform)) {
fxy060608's avatar
fxy060608 已提交
105 106 107 108 109 110 111 112 113 114 115 116
            return
          }
        }
        return {
          id,
          name: config.name,
          config,
        }
      } catch (e) {}
    })
    .filter<PluginConfig>(Boolean as any)
}