@tarojs/service 4.0.0-beta.0 → 4.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +14 -0
- package/dist/Config.js +2 -2
- package/dist/Config.js.map +1 -1
- package/dist/Kernel.js.map +1 -1
- package/dist/Plugin.js.map +1 -1
- package/dist/platform-plugin-base/platform.js.map +1 -1
- package/package.json +12 -9
- package/types/Config.d.ts +1 -2
- package/types/Kernel.d.ts +2 -2
- package/types/Plugin.d.ts +2 -1
- package/types/platform-plugin-base/platform.d.ts +2 -1
- package/types/utils/types.d.ts +1 -2
- package/src/Config.ts +0 -125
- package/src/Kernel.ts +0 -394
- package/src/Plugin.ts +0 -80
- package/src/index.ts +0 -9
- package/src/platform-plugin-base/index.ts +0 -3
- package/src/platform-plugin-base/mini.ts +0 -215
- package/src/platform-plugin-base/platform.ts +0 -75
- package/src/platform-plugin-base/web.ts +0 -136
- package/src/platform-plugin-base/webpack/hmr-plugin.ts +0 -37
- package/src/utils/constants.ts +0 -21
- package/src/utils/index.ts +0 -118
- package/src/utils/package.ts +0 -15
- package/src/utils/types.ts +0 -167
package/src/Kernel.ts
DELETED
|
@@ -1,394 +0,0 @@
|
|
|
1
|
-
import * as helper from '@tarojs/helper'
|
|
2
|
-
import * as runnerUtils from '@tarojs/runner-utils'
|
|
3
|
-
import { getPlatformType } from '@tarojs/shared'
|
|
4
|
-
import { EventEmitter } from 'events'
|
|
5
|
-
import { merge } from 'lodash'
|
|
6
|
-
import * as path from 'path'
|
|
7
|
-
import { AsyncSeriesWaterfallHook } from 'tapable'
|
|
8
|
-
|
|
9
|
-
import Plugin from './Plugin'
|
|
10
|
-
import { convertPluginsToObject, mergePlugins, printHelpLog, resolvePresetsOrPlugins } from './utils'
|
|
11
|
-
import {
|
|
12
|
-
IS_ADD_HOOK,
|
|
13
|
-
IS_EVENT_HOOK,
|
|
14
|
-
IS_MODIFY_HOOK,
|
|
15
|
-
PluginType
|
|
16
|
-
} from './utils/constants'
|
|
17
|
-
|
|
18
|
-
import type { IProjectConfig, PluginItem } from '@tarojs/taro/types/compile'
|
|
19
|
-
import type Config from './Config'
|
|
20
|
-
import type {
|
|
21
|
-
Func,
|
|
22
|
-
ICommand,
|
|
23
|
-
IHook,
|
|
24
|
-
IPaths,
|
|
25
|
-
IPlatform,
|
|
26
|
-
IPlugin,
|
|
27
|
-
IPluginsObject,
|
|
28
|
-
IPreset
|
|
29
|
-
} from './utils/types'
|
|
30
|
-
|
|
31
|
-
interface IKernelOptions {
|
|
32
|
-
appPath: string
|
|
33
|
-
config: Config
|
|
34
|
-
presets?: PluginItem[]
|
|
35
|
-
plugins?: PluginItem[]
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export default class Kernel extends EventEmitter {
|
|
39
|
-
appPath: string
|
|
40
|
-
isWatch: boolean
|
|
41
|
-
isProduction: boolean
|
|
42
|
-
optsPresets: PluginItem[] | void
|
|
43
|
-
optsPlugins: PluginItem[] | void
|
|
44
|
-
plugins: Map<string, IPlugin>
|
|
45
|
-
paths: IPaths
|
|
46
|
-
extraPlugins: IPluginsObject
|
|
47
|
-
globalExtraPlugins: IPluginsObject
|
|
48
|
-
config: Config
|
|
49
|
-
initialConfig: IProjectConfig
|
|
50
|
-
initialGlobalConfig: IProjectConfig
|
|
51
|
-
hooks: Map<string, IHook[]>
|
|
52
|
-
methods: Map<string, Func[]>
|
|
53
|
-
cliCommands: string []
|
|
54
|
-
cliCommandsPath: string
|
|
55
|
-
commands: Map<string, ICommand>
|
|
56
|
-
platforms: Map<string, IPlatform>
|
|
57
|
-
helper: any
|
|
58
|
-
runnerUtils: any
|
|
59
|
-
runOpts: any
|
|
60
|
-
debugger: any
|
|
61
|
-
|
|
62
|
-
constructor (options: IKernelOptions) {
|
|
63
|
-
super()
|
|
64
|
-
this.debugger = process.env.DEBUG === 'Taro:Kernel' ? helper.createDebug('Taro:Kernel') : function () {}
|
|
65
|
-
this.appPath = options.appPath || process.cwd()
|
|
66
|
-
this.optsPresets = options.presets
|
|
67
|
-
this.optsPlugins = options.plugins
|
|
68
|
-
this.config = options.config
|
|
69
|
-
this.hooks = new Map()
|
|
70
|
-
this.methods = new Map()
|
|
71
|
-
this.commands = new Map()
|
|
72
|
-
this.platforms = new Map()
|
|
73
|
-
this.initHelper()
|
|
74
|
-
this.initConfig()
|
|
75
|
-
this.initPaths()
|
|
76
|
-
this.initRunnerUtils()
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
initConfig () {
|
|
80
|
-
this.initialConfig = this.config.initialConfig
|
|
81
|
-
this.initialGlobalConfig = this.config.initialGlobalConfig
|
|
82
|
-
this.debugger('initConfig', this.initialConfig)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
initPaths () {
|
|
86
|
-
this.paths = {
|
|
87
|
-
appPath: this.appPath,
|
|
88
|
-
nodeModulesPath: helper.recursiveFindNodeModules(path.join(this.appPath, helper.NODE_MODULES))
|
|
89
|
-
} as IPaths
|
|
90
|
-
if (this.config.isInitSuccess) {
|
|
91
|
-
Object.assign(this.paths, {
|
|
92
|
-
configPath: this.config.configPath,
|
|
93
|
-
sourcePath: path.join(this.appPath, this.initialConfig.sourceRoot as string),
|
|
94
|
-
outputPath: path.resolve(this.appPath, this.initialConfig.outputRoot as string)
|
|
95
|
-
})
|
|
96
|
-
}
|
|
97
|
-
this.debugger(`initPaths:${JSON.stringify(this.paths, null, 2)}`)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
initHelper () {
|
|
101
|
-
this.helper = helper
|
|
102
|
-
this.debugger('initHelper')
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
initRunnerUtils () {
|
|
106
|
-
this.runnerUtils = runnerUtils
|
|
107
|
-
this.debugger('initRunnerUtils')
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
initPresetsAndPlugins () {
|
|
111
|
-
const initialConfig = this.initialConfig
|
|
112
|
-
const initialGlobalConfig = this.initialGlobalConfig
|
|
113
|
-
const cliAndProjectConfigPresets = mergePlugins(this.optsPresets || [], initialConfig.presets || [])()
|
|
114
|
-
const cliAndProjectPlugins = mergePlugins(this.optsPlugins || [], initialConfig.plugins || [])()
|
|
115
|
-
const globalPlugins = convertPluginsToObject(initialGlobalConfig.plugins || [])()
|
|
116
|
-
const globalPresets = convertPluginsToObject(initialGlobalConfig.presets || [])()
|
|
117
|
-
this.debugger('initPresetsAndPlugins', cliAndProjectConfigPresets, cliAndProjectPlugins)
|
|
118
|
-
this.debugger('globalPresetsAndPlugins', globalPlugins, globalPresets)
|
|
119
|
-
process.env.NODE_ENV !== 'test' &&
|
|
120
|
-
helper.createSwcRegister({
|
|
121
|
-
only: [
|
|
122
|
-
...Object.keys(cliAndProjectConfigPresets),
|
|
123
|
-
...Object.keys(cliAndProjectPlugins),
|
|
124
|
-
...Object.keys(globalPresets),
|
|
125
|
-
...Object.keys(globalPlugins)
|
|
126
|
-
]
|
|
127
|
-
})
|
|
128
|
-
this.plugins = new Map()
|
|
129
|
-
this.extraPlugins = {}
|
|
130
|
-
this.globalExtraPlugins = {}
|
|
131
|
-
this.resolvePresets(cliAndProjectConfigPresets, globalPresets)
|
|
132
|
-
this.resolvePlugins(cliAndProjectPlugins, globalPlugins)
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
resolvePresets (cliAndProjectPresets: IPluginsObject, globalPresets: IPluginsObject) {
|
|
136
|
-
const resolvedCliAndProjectPresets = resolvePresetsOrPlugins(this.appPath, cliAndProjectPresets, PluginType.Preset)
|
|
137
|
-
while (resolvedCliAndProjectPresets.length) {
|
|
138
|
-
this.initPreset(resolvedCliAndProjectPresets.shift()!)
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const globalConfigRootPath = path.join(helper.getUserHomeDir(), helper.TARO_GLOBAL_CONFIG_DIR)
|
|
142
|
-
const resolvedGlobalPresets = resolvePresetsOrPlugins(globalConfigRootPath, globalPresets, PluginType.Plugin, true)
|
|
143
|
-
while (resolvedGlobalPresets.length) {
|
|
144
|
-
this.initPreset(resolvedGlobalPresets.shift()!, true)
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
resolvePlugins (cliAndProjectPlugins: IPluginsObject, globalPlugins: IPluginsObject) {
|
|
149
|
-
cliAndProjectPlugins = merge(this.extraPlugins, cliAndProjectPlugins)
|
|
150
|
-
const resolvedCliAndProjectPlugins = resolvePresetsOrPlugins(this.appPath, cliAndProjectPlugins, PluginType.Plugin)
|
|
151
|
-
|
|
152
|
-
globalPlugins = merge(this.globalExtraPlugins, globalPlugins)
|
|
153
|
-
const globalConfigRootPath = path.join(helper.getUserHomeDir(), helper.TARO_GLOBAL_CONFIG_DIR)
|
|
154
|
-
const resolvedGlobalPlugins = resolvePresetsOrPlugins(globalConfigRootPath, globalPlugins, PluginType.Plugin, true)
|
|
155
|
-
|
|
156
|
-
const resolvedPlugins = resolvedCliAndProjectPlugins.concat(resolvedGlobalPlugins)
|
|
157
|
-
|
|
158
|
-
while (resolvedPlugins.length) {
|
|
159
|
-
this.initPlugin(resolvedPlugins.shift()!)
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
this.extraPlugins = {}
|
|
163
|
-
this.globalExtraPlugins = {}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
initPreset (preset: IPreset, isGlobalConfigPreset?: boolean) {
|
|
167
|
-
this.debugger('initPreset', preset)
|
|
168
|
-
const { id, path, opts, apply } = preset
|
|
169
|
-
const pluginCtx = this.initPluginCtx({ id, path, ctx: this })
|
|
170
|
-
const { presets, plugins } = apply()(pluginCtx, opts) || {}
|
|
171
|
-
this.registerPlugin(preset)
|
|
172
|
-
if (Array.isArray(presets)) {
|
|
173
|
-
const _presets = resolvePresetsOrPlugins(this.appPath, convertPluginsToObject(presets)(), PluginType.Preset, isGlobalConfigPreset)
|
|
174
|
-
while (_presets.length) {
|
|
175
|
-
this.initPreset(_presets.shift()!, isGlobalConfigPreset)
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
if (Array.isArray(plugins)) {
|
|
179
|
-
isGlobalConfigPreset
|
|
180
|
-
? (this.globalExtraPlugins = merge(this.globalExtraPlugins, convertPluginsToObject(plugins)()))
|
|
181
|
-
: (this.extraPlugins = merge(this.extraPlugins, convertPluginsToObject(plugins)()))
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
initPlugin (plugin: IPlugin) {
|
|
186
|
-
const { id, path, opts, apply } = plugin
|
|
187
|
-
const pluginCtx = this.initPluginCtx({ id, path, ctx: this })
|
|
188
|
-
this.debugger('initPlugin', plugin)
|
|
189
|
-
this.registerPlugin(plugin)
|
|
190
|
-
apply()(pluginCtx, opts)
|
|
191
|
-
this.checkPluginOpts(pluginCtx, opts)
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
applyCliCommandPlugin (commandNames: string[] = []) {
|
|
195
|
-
const existsCliCommand: string[] = []
|
|
196
|
-
for ( let i = 0; i < commandNames.length; i++ ) {
|
|
197
|
-
const commandName = commandNames[i]
|
|
198
|
-
const commandFilePath = path.resolve(this.cliCommandsPath, `${commandName}.js`)
|
|
199
|
-
if (this.cliCommands.includes(commandName)) existsCliCommand.push(commandFilePath)
|
|
200
|
-
}
|
|
201
|
-
const commandPlugins = convertPluginsToObject(existsCliCommand || [])()
|
|
202
|
-
helper.createSwcRegister({ only: [ ...Object.keys(commandPlugins) ] })
|
|
203
|
-
const resolvedCommandPlugins = resolvePresetsOrPlugins(this.appPath, commandPlugins, PluginType.Plugin)
|
|
204
|
-
while (resolvedCommandPlugins.length) {
|
|
205
|
-
this.initPlugin(resolvedCommandPlugins.shift()!)
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
checkPluginOpts (pluginCtx, opts) {
|
|
210
|
-
if (typeof pluginCtx.optsSchema !== 'function') {
|
|
211
|
-
return
|
|
212
|
-
}
|
|
213
|
-
this.debugger('checkPluginOpts', pluginCtx)
|
|
214
|
-
const joi = require('joi')
|
|
215
|
-
const schema = pluginCtx.optsSchema(joi)
|
|
216
|
-
if (!joi.isSchema(schema)) {
|
|
217
|
-
throw new Error(`插件${pluginCtx.id}中设置参数检查 schema 有误,请检查!`)
|
|
218
|
-
}
|
|
219
|
-
const { error } = schema.validate(opts)
|
|
220
|
-
if (error) {
|
|
221
|
-
error.message = `插件${pluginCtx.id}获得的参数不符合要求,请检查!`
|
|
222
|
-
throw error
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
registerPlugin (plugin: IPlugin) {
|
|
227
|
-
this.debugger('registerPlugin', plugin)
|
|
228
|
-
if (this.plugins.has(plugin.id)) {
|
|
229
|
-
throw new Error(`插件 ${plugin.id} 已被注册`)
|
|
230
|
-
}
|
|
231
|
-
this.plugins.set(plugin.id, plugin)
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
initPluginCtx ({ id, path, ctx }: { id: string, path: string, ctx: Kernel }) {
|
|
235
|
-
const pluginCtx = new Plugin({ id, path, ctx })
|
|
236
|
-
const internalMethods = ['onReady', 'onStart']
|
|
237
|
-
const kernelApis = [
|
|
238
|
-
'appPath',
|
|
239
|
-
'plugins',
|
|
240
|
-
'platforms',
|
|
241
|
-
'paths',
|
|
242
|
-
'helper',
|
|
243
|
-
'runOpts',
|
|
244
|
-
'runnerUtils',
|
|
245
|
-
'initialConfig',
|
|
246
|
-
'applyPlugins',
|
|
247
|
-
'applyCliCommandPlugin'
|
|
248
|
-
]
|
|
249
|
-
internalMethods.forEach(name => {
|
|
250
|
-
if (!this.methods.has(name)) {
|
|
251
|
-
pluginCtx.registerMethod(name)
|
|
252
|
-
}
|
|
253
|
-
})
|
|
254
|
-
return new Proxy(pluginCtx, {
|
|
255
|
-
get: (target, name: string) => {
|
|
256
|
-
if (this.methods.has(name)) {
|
|
257
|
-
const method = this.methods.get(name)
|
|
258
|
-
if (Array.isArray(method)) {
|
|
259
|
-
return (...arg) => {
|
|
260
|
-
method.forEach(item => {
|
|
261
|
-
item.apply(this, arg)
|
|
262
|
-
})
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
return method
|
|
266
|
-
}
|
|
267
|
-
if (kernelApis.includes(name)) {
|
|
268
|
-
return typeof this[name] === 'function' ? this[name].bind(this) : this[name]
|
|
269
|
-
}
|
|
270
|
-
return target[name]
|
|
271
|
-
}
|
|
272
|
-
})
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
async applyPlugins (args: string | { name: string, initialVal?: any, opts?: any }) {
|
|
276
|
-
let name
|
|
277
|
-
let initialVal
|
|
278
|
-
let opts
|
|
279
|
-
if (typeof args === 'string') {
|
|
280
|
-
name = args
|
|
281
|
-
} else {
|
|
282
|
-
name = args.name
|
|
283
|
-
initialVal = args.initialVal
|
|
284
|
-
opts = args.opts
|
|
285
|
-
}
|
|
286
|
-
this.debugger('applyPlugins')
|
|
287
|
-
this.debugger(`applyPlugins:name:${name}`)
|
|
288
|
-
this.debugger(`applyPlugins:initialVal:${initialVal}`)
|
|
289
|
-
this.debugger(`applyPlugins:opts:${opts}`)
|
|
290
|
-
if (typeof name !== 'string') {
|
|
291
|
-
throw new Error('调用失败,未传入正确的名称!')
|
|
292
|
-
}
|
|
293
|
-
const hooks = this.hooks.get(name) || []
|
|
294
|
-
if (!hooks.length) {
|
|
295
|
-
return await initialVal
|
|
296
|
-
}
|
|
297
|
-
const waterfall = new AsyncSeriesWaterfallHook(['arg'])
|
|
298
|
-
if (hooks.length) {
|
|
299
|
-
const resArr: any[] = []
|
|
300
|
-
for (const hook of hooks) {
|
|
301
|
-
waterfall.tapPromise({
|
|
302
|
-
name: hook.plugin!,
|
|
303
|
-
stage: hook.stage || 0,
|
|
304
|
-
// @ts-ignore
|
|
305
|
-
before: hook.before
|
|
306
|
-
}, async arg => {
|
|
307
|
-
const res = await hook.fn(opts, arg)
|
|
308
|
-
if (IS_MODIFY_HOOK.test(name) && IS_EVENT_HOOK.test(name)) {
|
|
309
|
-
return res
|
|
310
|
-
}
|
|
311
|
-
if (IS_ADD_HOOK.test(name)) {
|
|
312
|
-
resArr.push(res)
|
|
313
|
-
return resArr
|
|
314
|
-
}
|
|
315
|
-
return null
|
|
316
|
-
})
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
return await waterfall.promise(initialVal)
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
runWithPlatform (platform) {
|
|
323
|
-
if (!this.platforms.has(platform)) {
|
|
324
|
-
throw new Error(`不存在编译平台 ${platform}`)
|
|
325
|
-
}
|
|
326
|
-
const config = this.platforms.get(platform)!
|
|
327
|
-
const withNameConfig = this.config.getConfigWithNamed(config.name, config.useConfigName)
|
|
328
|
-
process.env.TARO_PLATFORM = getPlatformType(config.name, config.useConfigName)
|
|
329
|
-
return withNameConfig
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
setRunOpts (opts) {
|
|
333
|
-
this.runOpts = opts
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
runHelp (name: string) {
|
|
337
|
-
const command = this.commands.get(name)
|
|
338
|
-
const defaultOptionsMap = new Map()
|
|
339
|
-
defaultOptionsMap.set('-h, --help', 'output usage information')
|
|
340
|
-
let customOptionsMap = new Map()
|
|
341
|
-
if (command?.optionsMap) {
|
|
342
|
-
customOptionsMap = new Map(Object.entries(command?.optionsMap))
|
|
343
|
-
}
|
|
344
|
-
const optionsMap = new Map([...customOptionsMap, ...defaultOptionsMap])
|
|
345
|
-
printHelpLog(name, optionsMap, command?.synopsisList ? new Set(command?.synopsisList) : new Set())
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
async run (args: string | { name: string, opts?: any }) {
|
|
349
|
-
let name
|
|
350
|
-
let opts
|
|
351
|
-
if (typeof args === 'string') {
|
|
352
|
-
name = args
|
|
353
|
-
} else {
|
|
354
|
-
name = args.name
|
|
355
|
-
opts = args.opts
|
|
356
|
-
}
|
|
357
|
-
this.debugger('command:run')
|
|
358
|
-
this.debugger(`command:run:name:${name}`)
|
|
359
|
-
this.debugger('command:runOpts')
|
|
360
|
-
this.debugger(`command:runOpts:${JSON.stringify(opts, null, 2)}`)
|
|
361
|
-
this.setRunOpts(opts)
|
|
362
|
-
|
|
363
|
-
this.debugger('initPresetsAndPlugins')
|
|
364
|
-
this.initPresetsAndPlugins()
|
|
365
|
-
|
|
366
|
-
await this.applyPlugins('onReady')
|
|
367
|
-
|
|
368
|
-
this.debugger('command:onStart')
|
|
369
|
-
await this.applyPlugins('onStart')
|
|
370
|
-
|
|
371
|
-
if (!this.commands.has(name)) {
|
|
372
|
-
throw new Error(`${name} 命令不存在`)
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
if (opts?.isHelp) {
|
|
376
|
-
return this.runHelp(name)
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
if (opts?.options?.platform) {
|
|
380
|
-
opts.config = this.runWithPlatform(opts.options.platform)
|
|
381
|
-
await this.applyPlugins({
|
|
382
|
-
name: 'modifyRunnerOpts',
|
|
383
|
-
opts: {
|
|
384
|
-
opts: opts?.config
|
|
385
|
-
}
|
|
386
|
-
})
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
await this.applyPlugins({
|
|
390
|
-
name,
|
|
391
|
-
opts
|
|
392
|
-
})
|
|
393
|
-
}
|
|
394
|
-
}
|
package/src/Plugin.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { addPlatforms } from '@tarojs/helper'
|
|
2
|
-
|
|
3
|
-
import type Kernel from './Kernel'
|
|
4
|
-
import type { Func, ICommand, IHook, IPlatform } from './utils/types'
|
|
5
|
-
|
|
6
|
-
export default class Plugin {
|
|
7
|
-
id: string
|
|
8
|
-
path: string
|
|
9
|
-
ctx: Kernel
|
|
10
|
-
optsSchema: Func
|
|
11
|
-
|
|
12
|
-
constructor (opts) {
|
|
13
|
-
this.id = opts.id
|
|
14
|
-
this.path = opts.path
|
|
15
|
-
this.ctx = opts.ctx
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
register (hook: IHook) {
|
|
19
|
-
if (typeof hook.name !== 'string') {
|
|
20
|
-
throw new Error(`插件 ${this.id} 中注册 hook 失败, hook.name 必须是 string 类型`)
|
|
21
|
-
}
|
|
22
|
-
if (typeof hook.fn !== 'function') {
|
|
23
|
-
throw new Error(`插件 ${this.id} 中注册 hook 失败, hook.fn 必须是 function 类型`)
|
|
24
|
-
}
|
|
25
|
-
const hooks = this.ctx.hooks.get(hook.name) || []
|
|
26
|
-
hook.plugin = this.id
|
|
27
|
-
this.ctx.hooks.set(hook.name, hooks.concat(hook))
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
registerCommand (command: ICommand) {
|
|
31
|
-
if (this.ctx.commands.has(command.name)) {
|
|
32
|
-
throw new Error(`命令 ${command.name} 已存在`)
|
|
33
|
-
}
|
|
34
|
-
this.ctx.commands.set(command.name, command)
|
|
35
|
-
this.register(command)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
registerPlatform (platform: IPlatform) {
|
|
39
|
-
if (this.ctx.platforms.has(platform.name)) {
|
|
40
|
-
throw new Error(`适配平台 ${platform.name} 已存在`)
|
|
41
|
-
}
|
|
42
|
-
addPlatforms(platform.name)
|
|
43
|
-
this.ctx.platforms.set(platform.name, platform)
|
|
44
|
-
this.register(platform)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
registerMethod (...args) {
|
|
48
|
-
const { name, fn } = processArgs(args)
|
|
49
|
-
const methods = this.ctx.methods.get(name) || []
|
|
50
|
-
methods.push(fn || function (fn: Func) {
|
|
51
|
-
this.register({
|
|
52
|
-
name,
|
|
53
|
-
fn
|
|
54
|
-
})
|
|
55
|
-
}.bind(this))
|
|
56
|
-
this.ctx.methods.set(name, methods)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
addPluginOptsSchema (schema) {
|
|
60
|
-
this.optsSchema = schema
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function processArgs (args) {
|
|
65
|
-
let name, fn
|
|
66
|
-
if (!args.length) {
|
|
67
|
-
throw new Error('参数为空')
|
|
68
|
-
} else if (args.length === 1) {
|
|
69
|
-
if (typeof args[0] === 'string') {
|
|
70
|
-
name = args[0]
|
|
71
|
-
} else {
|
|
72
|
-
name = args[0].name
|
|
73
|
-
fn = args[0].fn
|
|
74
|
-
}
|
|
75
|
-
} else {
|
|
76
|
-
name = args[0]
|
|
77
|
-
fn = args[1]
|
|
78
|
-
}
|
|
79
|
-
return { name, fn }
|
|
80
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import Config from './Config'
|
|
2
|
-
import Kernel from './Kernel'
|
|
3
|
-
import { TaroPlatform, TaroPlatformBase, TaroPlatformWeb } from './platform-plugin-base'
|
|
4
|
-
|
|
5
|
-
export * from './utils/types'
|
|
6
|
-
export { Config, Kernel, TaroPlatform, TaroPlatformBase, TaroPlatformWeb }
|
|
7
|
-
export default { Config, Kernel, TaroPlatform, TaroPlatformBase, TaroPlatformWeb }
|
|
8
|
-
|
|
9
|
-
export type { IPluginContext } from './utils/types'
|
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
import { recursiveMerge } from '@tarojs/helper'
|
|
2
|
-
import { isObject, PLATFORM_TYPE } from '@tarojs/shared'
|
|
3
|
-
import * as path from 'path'
|
|
4
|
-
|
|
5
|
-
import { getPkgVersion } from '../utils/package'
|
|
6
|
-
import TaroPlatform from './platform'
|
|
7
|
-
|
|
8
|
-
import type { RecursiveTemplate, UnRecursiveTemplate } from '@tarojs/shared/dist/template'
|
|
9
|
-
import type { TConfig } from '../utils/types'
|
|
10
|
-
|
|
11
|
-
interface IFileType {
|
|
12
|
-
templ: string
|
|
13
|
-
style: string
|
|
14
|
-
config: string
|
|
15
|
-
script: string
|
|
16
|
-
xs?: string
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export abstract class TaroPlatformBase<T extends TConfig = TConfig> extends TaroPlatform<T> {
|
|
20
|
-
platformType = PLATFORM_TYPE.MINI
|
|
21
|
-
|
|
22
|
-
abstract globalObject: string
|
|
23
|
-
abstract fileType: IFileType
|
|
24
|
-
abstract template: RecursiveTemplate | UnRecursiveTemplate
|
|
25
|
-
projectConfigJson?: string
|
|
26
|
-
taroComponentsPath?: string
|
|
27
|
-
|
|
28
|
-
private projectConfigJsonOutputPath: string
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* 1. 清空 dist 文件夹
|
|
32
|
-
* 2. 输出编译提示
|
|
33
|
-
* 3. 生成 project.config.json
|
|
34
|
-
*/
|
|
35
|
-
private async setup () {
|
|
36
|
-
await this.setupTransaction.perform(this.setupImpl, this)
|
|
37
|
-
this.ctx.onSetupClose?.(this)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
private setupImpl () {
|
|
41
|
-
const { output } = this.config
|
|
42
|
-
// webpack5 原生支持 output.clean 选项,但是 webpack4 不支持, 为统一行为,这里做一下兼容
|
|
43
|
-
// (在 packages/taro-mini-runner/src/webpack/chain.ts 和 packages/taro-webpack-runner/src/utils/chain.ts 的 makeConfig 中对 clean 选项做了过滤)
|
|
44
|
-
// 仅 output.clean 为 false 时不清空输出目录
|
|
45
|
-
// eslint-disable-next-line eqeqeq
|
|
46
|
-
if (output == undefined || output.clean == undefined || output.clean === true) {
|
|
47
|
-
this.emptyOutputDir()
|
|
48
|
-
} else if (isObject(output.clean)) {
|
|
49
|
-
this.emptyOutputDir(output.clean.keep || [])
|
|
50
|
-
}
|
|
51
|
-
this.printDevelopmentTip(this.platform)
|
|
52
|
-
if (this.projectConfigJson) {
|
|
53
|
-
this.generateProjectConfig(this.projectConfigJson)
|
|
54
|
-
}
|
|
55
|
-
if (this.ctx.initialConfig.logger?.quiet === false) {
|
|
56
|
-
const { printLog, processTypeEnum } = this.ctx.helper
|
|
57
|
-
printLog(processTypeEnum.START, '开发者工具-项目目录', `${this.ctx.paths.outputPath}`)
|
|
58
|
-
}
|
|
59
|
-
// Webpack5 代码自动热重载
|
|
60
|
-
if (this.compiler === 'webpack5' && this.config.isWatch && this.projectConfigJsonOutputPath) {
|
|
61
|
-
try {
|
|
62
|
-
const projectConfig = require(this.projectConfigJsonOutputPath)
|
|
63
|
-
if (projectConfig.setting?.compileHotReLoad === true) {
|
|
64
|
-
this.ctx.modifyWebpackChain(({ chain }) => {
|
|
65
|
-
chain.plugin('TaroMiniHMRPlugin')
|
|
66
|
-
.use(require(path.join(__dirname, './webpack/hmr-plugin.js')).default)
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
-
} catch (e) {} // eslint-disable-line no-empty
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
protected printDevelopmentTip (platform: string) {
|
|
74
|
-
const tips: string[] = []
|
|
75
|
-
const config = this.config
|
|
76
|
-
const { chalk } = this.helper
|
|
77
|
-
|
|
78
|
-
if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test') {
|
|
79
|
-
const { isWindows } = this.helper
|
|
80
|
-
const exampleCommand = isWindows
|
|
81
|
-
? `$ set NODE_ENV=production && taro build --type ${platform} --watch`
|
|
82
|
-
: `$ NODE_ENV=production taro build --type ${platform} --watch`
|
|
83
|
-
|
|
84
|
-
tips.push(chalk.yellowBright(`预览模式生成的文件较大,设置 NODE_ENV 为 production 可以开启压缩。
|
|
85
|
-
Example:
|
|
86
|
-
${exampleCommand}`))
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (this.compiler === 'webpack5' && !config.cache?.enable) {
|
|
90
|
-
tips.push(chalk.yellowBright('建议开启持久化缓存功能,能有效提升二次编译速度,详情请参考: https://docs.taro.zone/docs/config-detail#cache。'))
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (tips.length) {
|
|
94
|
-
console.log(chalk.yellowBright('Tips:'))
|
|
95
|
-
tips.forEach((item, index) => console.log(`${chalk.yellowBright(index + 1)}. ${item}`))
|
|
96
|
-
console.log('\n')
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* 返回当前项目内的 @tarojs/mini-runner 包
|
|
102
|
-
*/
|
|
103
|
-
protected async getRunner () {
|
|
104
|
-
const { appPath } = this.ctx.paths
|
|
105
|
-
const { npm } = this.helper
|
|
106
|
-
|
|
107
|
-
let runnerPkg: string
|
|
108
|
-
switch (this.compiler) {
|
|
109
|
-
case 'webpack5':
|
|
110
|
-
runnerPkg = '@tarojs/webpack5-runner'
|
|
111
|
-
break
|
|
112
|
-
case 'vite':
|
|
113
|
-
runnerPkg = '@tarojs/vite-runner'
|
|
114
|
-
break
|
|
115
|
-
default:
|
|
116
|
-
runnerPkg = '@tarojs/mini-runner'
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const runner = await npm.getNpmPkg(runnerPkg, appPath)
|
|
120
|
-
|
|
121
|
-
return runner.bind(null, appPath)
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* 准备 mini-runner 参数
|
|
126
|
-
* @param extraOptions 需要额外合入 Options 的配置项
|
|
127
|
-
*/
|
|
128
|
-
protected getOptions (extraOptions = {}) {
|
|
129
|
-
const { ctx, globalObject, fileType, template } = this
|
|
130
|
-
|
|
131
|
-
const config = recursiveMerge(Object.assign({}, this.config), {
|
|
132
|
-
env: {
|
|
133
|
-
FRAMEWORK: JSON.stringify(this.config.framework),
|
|
134
|
-
TARO_ENV: JSON.stringify(this.platform),
|
|
135
|
-
TARO_PLATFORM: JSON.stringify(this.platformType),
|
|
136
|
-
TARO_VERSION: JSON.stringify(getPkgVersion())
|
|
137
|
-
}
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
return {
|
|
141
|
-
...config,
|
|
142
|
-
nodeModulesPath: ctx.paths.nodeModulesPath,
|
|
143
|
-
buildAdapter: config.platform,
|
|
144
|
-
platformType: this.platformType,
|
|
145
|
-
globalObject,
|
|
146
|
-
fileType,
|
|
147
|
-
template,
|
|
148
|
-
...extraOptions
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* 调用 mini-runner 开始编译
|
|
154
|
-
* @param extraOptions 需要额外传入 @tarojs/mini-runner 的配置项
|
|
155
|
-
*/
|
|
156
|
-
private async build (extraOptions = {}) {
|
|
157
|
-
this.ctx.onBuildInit?.(this)
|
|
158
|
-
await this.buildTransaction.perform(this.buildImpl, this, extraOptions)
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
private async buildImpl (extraOptions = {}) {
|
|
162
|
-
const runner = await this.getRunner()
|
|
163
|
-
const options = this.getOptions(
|
|
164
|
-
Object.assign(
|
|
165
|
-
{
|
|
166
|
-
runtimePath: this.runtimePath,
|
|
167
|
-
taroComponentsPath: this.taroComponentsPath
|
|
168
|
-
},
|
|
169
|
-
extraOptions
|
|
170
|
-
)
|
|
171
|
-
)
|
|
172
|
-
await runner(options)
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* 生成 project.config.json
|
|
177
|
-
* @param src 项目源码中配置文件的名称
|
|
178
|
-
* @param dist 编译后配置文件的名称,默认为 'project.config.json'
|
|
179
|
-
*/
|
|
180
|
-
protected generateProjectConfig (src: string, dist = 'project.config.json') {
|
|
181
|
-
if (this.config.isBuildNativeComp) return
|
|
182
|
-
this.ctx.generateProjectConfig({
|
|
183
|
-
srcConfigName: src,
|
|
184
|
-
distConfigName: dist
|
|
185
|
-
})
|
|
186
|
-
this.projectConfigJsonOutputPath = `${this.ctx.paths.outputPath}/${dist}`
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* 递归替换对象的 key 值
|
|
191
|
-
*/
|
|
192
|
-
protected recursiveReplaceObjectKeys (obj, keyMap) {
|
|
193
|
-
Object.keys(obj).forEach((key) => {
|
|
194
|
-
if (keyMap[key]) {
|
|
195
|
-
obj[keyMap[key]] = obj[key]
|
|
196
|
-
if (typeof obj[key] === 'object') {
|
|
197
|
-
this.recursiveReplaceObjectKeys(obj[keyMap[key]], keyMap)
|
|
198
|
-
}
|
|
199
|
-
delete obj[key]
|
|
200
|
-
} else if (keyMap[key] === false) {
|
|
201
|
-
delete obj[key]
|
|
202
|
-
} else if (typeof obj[key] === 'object') {
|
|
203
|
-
this.recursiveReplaceObjectKeys(obj[key], keyMap)
|
|
204
|
-
}
|
|
205
|
-
})
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* 调用 mini-runner 开启编译
|
|
210
|
-
*/
|
|
211
|
-
public async start () {
|
|
212
|
-
await this.setup()
|
|
213
|
-
await this.build()
|
|
214
|
-
}
|
|
215
|
-
}
|