plugin.js 3.3 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1 2 3 4 5 6 7 8
const path = require('path')

const initPreprocessContext = require('./preprocess')

const Plugin = {
  options: {},
  // 初步校验相关配置是否正确
  validate: [], // (platformOptions, manifestJson) {},
fxy060608's avatar
fxy060608 已提交
9
  configureEnv: [], // (){},
fxy060608's avatar
fxy060608 已提交
10 11
  // 以 H5 为基准的平台特殊配置
  configureH5: [], // (h5Options) {},
fxy060608's avatar
fxy060608 已提交
12
  configurePages: [], // (pagesJson,manifestJson,loader) {},
fxy060608's avatar
fxy060608 已提交
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
  // 链式修改 webpack config
  chainWebpack: [], // (config, vueOptions, api) {},
  // 修改 webpack config
  configureWebpack: [], // (config, vueOptions, api) {},
  // 配置额外的资源拷贝
  copyWebpackOptions: [] // (platformOptions, vueOptions) {}
}

const PLUGIN_KEYS = Object.keys(Plugin)

function initPlugin (plugin) {
  let pluginApi
  try {
    pluginApi = require(path.join(plugin.id, (plugin.config.main || '/lib/uni.config.js')))
  } catch (e) {
fxy060608's avatar
fxy060608 已提交
28
    console.warn(`${plugin.id} 缺少 uni.config.js `)
fxy060608's avatar
fxy060608 已提交
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
  }

  pluginApi && PLUGIN_KEYS.forEach(name => {
    if (pluginApi[name]) {
      if (Array.isArray(Plugin[name])) { // hooks
        Plugin[name].push(pluginApi[name])
      } else { // options
        Object.assign(Plugin[name], pluginApi[name])
      }
    }
  })
}

const pluginRE = /^(uni-|@[\w-]+(\.)?[\w-]+\/uni-)/

function resolvePlugins () {
  const pkg = require(path.resolve(process.env.UNI_CLI_CONTEXT, 'package.json'))
  return Object.keys(pkg.devDependencies || {})
    .concat(Object.keys(pkg.dependencies || {}))
    .map(id => {
49
      if (!pluginRE.test(id)) {
fxy060608's avatar
fxy060608 已提交
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
        return
      }
      try {
        const pluginPkg = require(id + '/package.json')
        const config = pluginPkg['uni-app']
        if (!config) {
          return
        }
        if (!config.name) {
          return console.warn(`${id}/package.json->uni-app 缺少 name 属性`)
        }
        return {
          id,
          name: config.name,
          config
        }
      } catch (e) {}
    }).filter(Boolean)
}

function initExtends (name, plugin, plugins) {
fxy060608's avatar
fxy060608 已提交
71
  const extendsPlatform = plugin.config.extends
fxy060608's avatar
fxy060608 已提交
72 73
  if (extendsPlatform) {
    if (extendsPlatform !== 'h5') {
fxy060608's avatar
fxy060608 已提交
74
      console.error('目前仅支持基于 h5 平台做扩展')
fxy060608's avatar
fxy060608 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
      process.exit(0)
    }
    const extendsPlugin = plugins.find(plugin => plugin.name === extendsPlatform)
    if (!plugin) {
      console.error(`缺少平台 ${extendsPlatform} 插件`)
      process.exit(0)
    }
    process.env.UNI_SUB_PLATFORM = name
    process.env.UNI_PLATFORM = extendsPlatform
    initPlugin(extendsPlugin)
  }
}

module.exports = {
  init () {
90 91
    // compatible with vue-cli-service lint
    process.env.UNI_PLATFORM = process.env.UNI_PLATFORM || 'h5'
fxy060608's avatar
fxy060608 已提交
92 93 94 95 96 97 98 99 100 101 102
    const plugins = resolvePlugins()
    const plugin = plugins.find(plugin => plugin.name === process.env.UNI_PLATFORM)
    if (!plugin) {
      console.error(`缺少平台 ${process.env.UNI_PLATFORM} 插件`)
      process.exit(0)
    }
    const name = plugin.name

    initExtends(name, plugin, plugins)

    initPlugin(plugin)
103 104

    Plugin.name = name
fxy060608's avatar
fxy060608 已提交
105
    Plugin.id = plugin.id
fxy060608's avatar
fxy060608 已提交
106 107 108 109 110 111 112
    Plugin.config = plugin.config
    Plugin.platforms = plugins.map(plugin => plugin.name)
    Plugin.preprocess = initPreprocessContext(name, Plugin.platforms, process.UNI_SCRIPT_DEFINE)

    return Plugin
  }
}