@tarojs/service 4.0.0-beta.1 → 4.0.0-beta.10

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.
@@ -1,75 +0,0 @@
1
- import { PLATFORM_TYPE } from '@tarojs/shared'
2
-
3
- import type { Func, IPluginContext, TConfig } from '../utils/types'
4
-
5
- interface IWrapper {
6
- init? (): void
7
- close? (): void
8
- }
9
-
10
- export class Transaction<T = TaroPlatform> {
11
- wrappers: IWrapper[] = []
12
-
13
- async perform (fn: Func, scope: T, ...args: any[]) {
14
- this.initAll(scope)
15
- await fn.call(scope, ...args)
16
- this.closeAll(scope)
17
- }
18
-
19
- initAll (scope: T) {
20
- const wrappers = this.wrappers
21
- wrappers.forEach(wrapper => wrapper.init?.call(scope))
22
- }
23
-
24
- closeAll (scope: T) {
25
- const wrappers = this.wrappers
26
- wrappers.forEach(wrapper => wrapper.close?.call(scope))
27
- }
28
-
29
- addWrapper (wrapper: IWrapper) {
30
- this.wrappers.push(wrapper)
31
- }
32
- }
33
-
34
- export default abstract class TaroPlatform<T extends TConfig = TConfig> {
35
- protected ctx: IPluginContext
36
- protected config: T
37
- protected helper: IPluginContext['helper']
38
- protected compiler: string
39
-
40
- abstract platformType: PLATFORM_TYPE
41
- abstract platform: string
42
- abstract runtimePath: string | string[]
43
-
44
- protected setupTransaction = new Transaction<this>()
45
- protected buildTransaction = new Transaction<this>()
46
-
47
- constructor (ctx: IPluginContext, config: T) {
48
- this.ctx = ctx
49
- this.helper = ctx.helper
50
- this.config = config
51
- this.updateOutputPath(config)
52
- const _compiler = config.compiler
53
- this.compiler = typeof _compiler === 'object' ? _compiler.type : _compiler
54
- }
55
-
56
- protected emptyOutputDir (excludes: Array<string | RegExp> = []) {
57
- const { outputPath } = this.ctx.paths
58
- this.helper.emptyDirectory(outputPath, { excludes })
59
- }
60
-
61
- /**
62
- * 如果分端编译详情 webpack 配置了 output 则需更新 outputPath 位置
63
- */
64
- private updateOutputPath (config: TConfig) {
65
- const platformPath = config.output?.path
66
- if (platformPath) {
67
- this.ctx.paths.outputPath = platformPath
68
- }
69
- }
70
-
71
- /**
72
- * 调用 runner 开启编译
73
- */
74
- abstract start(): Promise<void>
75
- }
@@ -1,136 +0,0 @@
1
- import { isObject, PLATFORM_TYPE } from '@tarojs/shared'
2
- import { get, merge } from 'lodash'
3
- import * as path from 'path'
4
-
5
- import { getPkgVersion } from '../utils/package'
6
- import TaroPlatform from './platform'
7
-
8
- import type { TConfig } from '../utils/types'
9
-
10
- export abstract class TaroPlatformWeb<T extends TConfig = TConfig> extends TaroPlatform<T> {
11
- platformType = PLATFORM_TYPE.WEB
12
-
13
- /**
14
- * 1. 清空 dist 文件夹
15
- * 2. 输出编译提示
16
- */
17
- private async setup () {
18
- await this.setupTransaction.perform(this.setupWebApp, this)
19
- this.ctx.onSetupClose?.(this)
20
- }
21
-
22
- private setupWebApp () {
23
- const { output } = this.config
24
- // webpack5 原生支持 output.clean 选项,但是 webpack4 不支持, 为统一行为,这里做一下兼容
25
- // (在 packages/taro-mini-runner/src/webpack/chain.ts 和 packages/taro-webpack-runner/src/utils/chain.ts 的 makeConfig 中对 clean 选项做了过滤)
26
- // eslint-disable-next-line eqeqeq
27
- if (output == undefined || output.clean == undefined || output.clean === true) {
28
- this.emptyOutputDir()
29
- } else if (isObject(output.clean)) {
30
- this.emptyOutputDir(output.clean.keep || [])
31
- }
32
- this.printDevelopmentTip()
33
- }
34
-
35
- protected printDevelopmentTip () {
36
- const tips: string[] = []
37
- const config = this.config
38
- const { chalk } = this.helper
39
-
40
- if (this.compiler === 'webpack5' && !config.cache?.enable) {
41
- tips.push(chalk.yellowBright('建议开启持久化缓存功能,能有效提升二次编译速度,详情请参考: https://docs.taro.zone/docs/config-detail#cache。'))
42
- }
43
-
44
- if (tips.length) {
45
- console.log(chalk.yellowBright('Tips:'))
46
- tips.forEach((item, index) => console.log(`${chalk.yellowBright(index + 1)}. ${item}`))
47
- console.log('\n')
48
- }
49
- }
50
-
51
- /**
52
- * 返回当前项目内的 runner 包
53
- */
54
- protected async getRunner () {
55
- const { appPath } = this.ctx.paths
56
- const { npm } = this.helper
57
-
58
- let runnerPkg: string
59
- switch (this.compiler) {
60
- case 'webpack5':
61
- runnerPkg = '@tarojs/webpack5-runner'
62
- break
63
- case 'vite':
64
- runnerPkg = '@tarojs/vite-runner'
65
- break
66
- default:
67
- runnerPkg = '@tarojs/webpack-runner'
68
- }
69
-
70
- const runner = await npm.getNpmPkg(runnerPkg, appPath)
71
-
72
- return runner.bind(null, appPath)
73
- }
74
-
75
- /**
76
- * 准备 runner 参数
77
- * @param extraOptions 需要额外合入 Options 的配置项
78
- */
79
- protected getOptions (extraOptions = {}) {
80
- const { sourcePath } = this.ctx.paths
81
- const { initialConfig } = this.ctx
82
- const { port } = this.ctx.runOpts.options
83
- const { recursiveMerge, ENTRY, SOURCE_DIR, OUTPUT_DIR } = this.ctx.helper
84
- const entryFileName = `${ENTRY}.config`
85
- const entryFile = path.basename(entryFileName)
86
- const defaultEntry = {
87
- [ENTRY]: [path.join(sourcePath, entryFile)]
88
- }
89
- const customEntry = get(initialConfig, 'h5.entry')
90
- const config = recursiveMerge(Object.assign({}, this.config), {
91
- entryFileName: ENTRY,
92
- env: {
93
- FRAMEWORK: JSON.stringify(this.config.framework),
94
- TARO_ENV: JSON.stringify(this.platform),
95
- TARO_PLATFORM: JSON.stringify(this.platformType),
96
- TARO_VERSION: JSON.stringify(getPkgVersion())
97
- },
98
- devServer: { port },
99
- sourceRoot: this.config.sourceRoot || SOURCE_DIR,
100
- outputRoot: this.config.outputRoot || OUTPUT_DIR
101
- })
102
- config.entry = merge(defaultEntry, customEntry)
103
-
104
- return {
105
- ...config,
106
- buildAdapter: config.platform,
107
- platformType: this.platformType,
108
- ...extraOptions
109
- }
110
- }
111
-
112
- /**
113
- * 调用 runner 开始编译
114
- * @param extraOptions 需要额外传入 runner 的配置项
115
- */
116
- private async build (extraOptions = {}) {
117
- this.ctx.onBuildInit?.(this)
118
- await this.buildTransaction.perform(this.buildWebApp, this, extraOptions)
119
- }
120
-
121
- private async buildWebApp (extraOptions = {}) {
122
- const runner = await this.getRunner()
123
- const options = this.getOptions(Object.assign({
124
- runtimePath: this.runtimePath,
125
- }, extraOptions))
126
- await runner(options)
127
- }
128
-
129
- /**
130
- * 调用 runner 开启编译
131
- */
132
- public async start () {
133
- await this.setup()
134
- await this.build()
135
- }
136
- }
@@ -1,37 +0,0 @@
1
- export default class TaroMiniHMRPlugin {
2
- apply (compiler) {
3
- compiler.hooks.thisCompilation.tap('TaroMiniHMRPlugin', compilation => {
4
- compilation.hooks.beforeChunkAssets.tap('TaroMiniHMRPlugin', () => {
5
- compilation.chunks.forEach(chunk => {
6
- if (chunk.hasRuntime() && chunk.name === 'runtime') {
7
- const runtimeModules = compilation.chunkGraph.getChunkRuntimeModulesInOrder(chunk)
8
- for (const module of runtimeModules) {
9
- if (module.name === 'jsonp chunk loading') {
10
- const runtimeSource = compilation.codeGenerationResults.getSource(
11
- module,
12
- chunk.runtime,
13
- 'runtime'
14
- )
15
- runtimeSource._value += `
16
- var miniHMRCallback = function(parentChunkLoadingFunction, data) {
17
- var chunkIds = data[0];
18
- var moreModules = data[1];
19
- if(chunkIds.some(function(id) { return installedChunks[id] === 0 })) {
20
- chunkIds.forEach(id => {
21
- delete installedChunks[id]
22
- })
23
- Object.keys(moreModules).forEach(id => {
24
- delete __webpack_module_cache__[id]
25
- })
26
- }
27
- if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
28
- }
29
- chunkLoadingGlobal.push = miniHMRCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));`
30
- }
31
- }
32
- }
33
- })
34
- })
35
- })
36
- }
37
- }
@@ -1,21 +0,0 @@
1
- export const CONFIG_DIR_NAME = 'config'
2
- export const DEFAULT_CONFIG_FILE = 'index'
3
-
4
- export const PRESET_PREFIX = '@tarojs/preset-'
5
- export const PLUGIN_PREFIX = '@tarojs/plugin-'
6
-
7
- export const IS_EVENT_HOOK = /^on/
8
- export const IS_ADD_HOOK = /^add/
9
- export const IS_MODIFY_HOOK = /^modify/
10
-
11
- export const presetOrPluginPrefixReg = new RegExp(`^${PRESET_PREFIX}|${PLUGIN_PREFIX}`)
12
-
13
- export enum PluginType {
14
- Preset = 'Preset',
15
- Plugin = 'Plugin'
16
- }
17
-
18
- export const PluginNamePrefix = {
19
- [PluginType.Preset]: PLUGIN_PREFIX,
20
- [PluginType.Plugin]: PLUGIN_PREFIX
21
- }
@@ -1,118 +0,0 @@
1
- import { chalk, getModuleDefaultExport } from '@tarojs/helper'
2
- import { merge } from 'lodash'
3
- import * as path from 'path'
4
- import * as resolve from 'resolve'
5
-
6
- import { PluginType } from './constants'
7
-
8
- import type { PluginItem } from '@tarojs/taro/types/compile'
9
- import type { IPlugin, IPluginsObject } from './types'
10
-
11
- export const isNpmPkg: (name: string) => boolean = name => !(/^(\.|\/)/.test(name))
12
-
13
- export function getPluginPath (pluginPath: string) {
14
- if (isNpmPkg(pluginPath) || path.isAbsolute(pluginPath)) return pluginPath
15
- throw new Error('plugin 和 preset 配置必须为绝对路径或者包名')
16
- }
17
-
18
- export function convertPluginsToObject (items: PluginItem[]): () => IPluginsObject {
19
- return () => {
20
- const obj: IPluginsObject = {}
21
- if (Array.isArray(items)) {
22
- items.forEach(item => {
23
- if (typeof item === 'string') {
24
- const name = getPluginPath(item)
25
- obj[name] = null
26
- } else if (Array.isArray(item)) {
27
- const name = getPluginPath(item[0])
28
- obj[name] = item[1]
29
- }
30
- })
31
- }
32
- return obj
33
- }
34
- }
35
-
36
- export function mergePlugins (dist: PluginItem[], src: PluginItem[]) {
37
- return () => {
38
- const srcObj = convertPluginsToObject(src)()
39
- const distObj = convertPluginsToObject(dist)()
40
- return merge(distObj, srcObj)
41
- }
42
- }
43
-
44
- // getModuleDefaultExport
45
- export function resolvePresetsOrPlugins (root: string, args: IPluginsObject, type: PluginType, skipError?: boolean): IPlugin[] {
46
- // 全局的插件引入报错,不抛出 Error 影响主流程,而是通过 log 提醒然后把插件 filter 掉,保证主流程不变
47
- const resolvedPresetsOrPlugins: IPlugin[] = []
48
- const presetsOrPluginsNames = Object.keys(args) || []
49
- for ( let i = 0; i < presetsOrPluginsNames.length; i++ ) {
50
- const item = presetsOrPluginsNames[i]
51
- let fPath
52
- try {
53
- fPath = resolve.sync(item, {
54
- basedir: root,
55
- extensions: ['.js', '.ts']
56
- })
57
- } catch (err) {
58
- if (args[item]?.backup) {
59
- // 如果项目中没有,可以使用 CLI 中的插件
60
- fPath = args[item]?.backup
61
- } else if (skipError) {
62
- // 如果跳过报错,那么 log 提醒,并且不使用该插件
63
- console.log(chalk.yellow(`找不到插件依赖 "${item}",请先在项目中安装,项目路径:${root}`))
64
- continue
65
- } else {
66
- console.log(chalk.red(`找不到插件依赖 "${item}",请先在项目中安装,项目路径:${root}`))
67
- process.exit(1)
68
- }
69
- }
70
- const resolvedItem = {
71
- id: fPath,
72
- path: fPath,
73
- type,
74
- opts: args[item] || {},
75
- apply () {
76
- try {
77
- return getModuleDefaultExport(require(fPath))
78
- } catch (error) {
79
- console.error(error)
80
- // 全局的插件运行报错,不抛出 Error 影响主流程,而是通过 log 提醒然后把插件 filter 掉,保证主流程不变
81
- if (skipError) {
82
- console.error(`插件依赖 "${item}" 加载失败,请检查插件配置`)
83
- } else {
84
- throw new Error(`插件依赖 "${item}" 加载失败,请检查插件配置`)
85
- }
86
- }
87
- }
88
- }
89
- resolvedPresetsOrPlugins.push(resolvedItem)
90
- }
91
-
92
- return resolvedPresetsOrPlugins
93
- }
94
-
95
- function supplementBlank (length) {
96
- return Array(length).map(() => '').join(' ')
97
- }
98
-
99
- export function printHelpLog (command, optionsList: Map<string, string>, synopsisList?: Set<string>) {
100
- console.log(`Usage: taro ${command} [options]`)
101
- console.log()
102
- console.log('Options:')
103
- const keys = Array.from(optionsList.keys())
104
- const maxLength = keys.reduce((v1, v2) => {
105
- return v1.length > v2.length ? v1 : v2
106
- }).length + 3
107
- optionsList.forEach((v, k) => {
108
- const supplementBlankLength = maxLength - k.length
109
- console.log(` ${k}${supplementBlank(supplementBlankLength)}${v}`)
110
- })
111
- if (synopsisList && synopsisList.size) {
112
- console.log()
113
- console.log('Synopsis:')
114
- synopsisList.forEach(item => {
115
- console.log(` $ ${item}`)
116
- })
117
- }
118
- }
@@ -1,15 +0,0 @@
1
- /* eslint-disable no-console */
2
- import * as path from 'path'
3
-
4
- export function getRootPath (): string {
5
- return path.resolve(__dirname, '../../')
6
- }
7
-
8
- export function getPkgVersion (): string {
9
- return require(path.join(getRootPath(), 'package.json')).version
10
- }
11
-
12
- export function printPkgVersion () {
13
- console.log(`👽 Taro v${getPkgVersion()}`)
14
- console.log()
15
- }
@@ -1,167 +0,0 @@
1
- import type helper from '@tarojs/helper'
2
- import type runnerUtils from '@tarojs/runner-utils'
3
- import type { IMiniFilesConfig, IProjectConfig } from '@tarojs/taro/types/compile'
4
- import type { IModifyChainData } from '@tarojs/taro/types/compile/hooks'
5
- import type joi from 'joi'
6
- import type Webpack from 'webpack'
7
- import type Chain from 'webpack-chain'
8
- import type { PluginType } from './constants'
9
-
10
- export interface IPaths {
11
- /**
12
- * 当前命令执行的目录,如果是 build 命令则为当前项目路径
13
- */
14
- appPath: string
15
- /**
16
- * 当前项目配置目录,如果 init 命令,则没有此路径
17
- */
18
- configPath: string
19
- /**
20
- * 当前项目源码路径
21
- */
22
- sourcePath: string
23
- /**
24
- * 当前项目输出代码路径
25
- */
26
- outputPath: string
27
- /**
28
- * 当前项目所用的 node_modules 路径
29
- */
30
- nodeModulesPath: string
31
- }
32
-
33
- export type Func = (...args: any[]) => any
34
-
35
- export type IPluginsObject = Record<string, Record<any, any> | null>
36
-
37
- export interface IPlugin {
38
- id: string
39
- path: string
40
- opts: any
41
- type: PluginType
42
- apply: Func
43
- }
44
-
45
- export type IPreset = IPlugin
46
-
47
- export interface IHook {
48
- name: string
49
- plugin?: string
50
- fn: Func
51
- before?: string
52
- stage?: number
53
- }
54
-
55
- export interface ICommand extends IHook {
56
- alias?: string
57
- optionsMap?: {
58
- [key: string]: string
59
- }
60
- synopsisList?: string[]
61
- }
62
-
63
- export interface IFileType {
64
- templ: string
65
- style: string
66
- script: string
67
- config: string
68
- }
69
-
70
- export interface IPlatform extends IHook {
71
- useConfigName?: string
72
- }
73
-
74
- export declare interface IPluginContext {
75
- /**
76
- * 获取当前所有挂载的插件
77
- */
78
- plugins: Map<string, IPlugin>
79
- /**
80
- * 获取当前所有挂载的平台
81
- */
82
- platforms: Map<string, IPlatform>
83
- /**
84
- * 包含当前执行命令的相关路径集合
85
- */
86
- paths: IPaths
87
- /**
88
- * 获取当前执行命令所带的参数
89
- */
90
- runOpts: any
91
- /**
92
- * 为包 @tarojs/helper 的快捷使用方式,包含其所有 API
93
- */
94
- helper: typeof helper
95
- /**
96
- * 为包 @tarojs/runner-utils 的快捷使用方式,包含其所有 API
97
- */
98
- runnerUtils: typeof runnerUtils
99
- /**
100
- * 项目配置
101
- */
102
- initialConfig: IProjectConfig
103
- /**
104
- * 注册一个可供其他插件调用的钩子,接收一个参数,即 Hook 对象
105
- */
106
- register: (hook: IHook) => void
107
- /**
108
- * 向 ctx 上挂载一个方法可供其他插件直接调用
109
- */
110
- registerMethod: (arg: (string | { name: string, fn?: Func }), fn?: Func) => void
111
- /**
112
- * 注册一个自定义命令
113
- */
114
- registerCommand: (command: ICommand) => void
115
- /**
116
- * 注册一个自定义编译平台
117
- */
118
- registerPlatform: (platform: IPlatform) => void
119
- /**
120
- * 触发注册的钩子(使用`ctx.register`方法注册的钩子),传入钩子名和钩子所需参数
121
- */
122
- applyPlugins: (args: string | { name: string, initialVal?: any, opts?: any }) => Promise<any>
123
- /**
124
- * 为插件添加入参校验
125
- */
126
- addPluginOptsSchema: (fn: (joi: joi.Root) => void) => void
127
- /**
128
- * 编译开始
129
- */
130
- onBuildStart: (fn: Func) => void
131
- /**
132
- * 编译结束(保存代码每次编译结束后都会触发)
133
- */
134
- onBuildFinish: (fn: Func) => void
135
- /**
136
- * 编译完成(启动项目后首次编译结束后会触发一次)
137
- */
138
- onBuildComplete: (fn: Func) => void
139
- /**
140
- * 修改编译过程中的页面组件配置
141
- */
142
- onCompilerMake: (fn: (args: { compilation: Webpack.Compilation, compiler: Webpack.Compiler, plugin: any }) => void) => void
143
- /**
144
- * 编译中修改 webpack 配置,在这个钩子中,你可以对 webpackChain 作出想要的调整,等同于配置 [`webpackChain`](./config-detail.md#miniwebpackchain)
145
- */
146
- modifyWebpackChain: (fn: (args: { chain: Chain, webpack: typeof Webpack, data?: IModifyChainData }) => void) => void
147
- /**
148
- * 编译中修改 vite 配置
149
- */
150
- modifyViteConfig: (fn: (args: { viteConfig: any, data?: IModifyChainData }) => void) => void
151
- /**
152
- * 修改编译后的结果
153
- */
154
- modifyBuildAssets: (fn: (args: { assets: any, miniPlugin: any }) => void) => void
155
- /**
156
- * 修改编译过程中的页面组件配置
157
- */
158
- modifyMiniConfigs: (fn: (args: { configMap: IMiniFilesConfig }) => void) => void
159
- /**
160
- * 修改 Taro 编译配置
161
- */
162
- modifyRunnerOpts: (fn: (args: { opts: any }) => void) => void
163
-
164
- [key: string]: any
165
- }
166
-
167
- export declare type TConfig = Record<string, any>