CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tarojs--service

Core service layer for the Taro cross-platform framework providing plugin management, configuration handling, and platform abstraction capabilities

Pending
Overview
Eval results
Files

plugin-context.mddocs/

Plugin Context API

Complete plugin development API providing access to the service layer's capabilities including comprehensive lifecycle hooks, method registration, build customization, and validation support.

Capabilities

Plugin Context Interface

The primary API interface available to all plugins providing access to the kernel's capabilities and state.

/**
 * Plugin context interface defining the complete API available to plugins
 */
interface IPluginContext {
  /** Map of all registered plugins */
  plugins: Map<string, IPlugin>;
  /** Map of all registered platforms */
  platforms: Map<string, IPlatform>;
  /** Path configuration object */
  paths: IPaths;
  /** Runtime options from command execution */
  runOpts: any;
  /** Helper utilities from @tarojs/helper package */
  helper: typeof helper;
  /** Runner utilities from @tarojs/runner-utils package */
  runnerUtils: typeof runnerUtils;
  /** Initial project configuration */
  initialConfig: IProjectConfig;
  
  // Registration methods
  register(hook: IHook): void;
  registerMethod(arg: string | { name: string; fn?: Func }, fn?: Func): void;
  registerCommand(command: ICommand): void;
  registerPlatform(platform: IPlatform): void;
  
  // Hook execution
  applyPlugins(args: string | { name: string; initialVal?: any; opts?: any }): Promise<any>;
  
  // Validation
  addPluginOptsSchema(fn: (joi: joi.Root) => void): void;
}

Hook Registration

Register hooks to participate in the build process and customize behavior at specific lifecycle points.

/**
 * Register a hook to be called during the build process
 * @param hook - Hook configuration object
 */
register(hook: IHook): void;

interface IHook {
  /** Hook name (e.g., 'onBuildStart', 'modifyWebpackChain') */
  name: string;
  /** Plugin ID that registered this hook (automatically set) */
  plugin?: string;
  /** Hook implementation function */
  fn: Func;
  /** Execute this hook before another hook */
  before?: string;
  /** Execution stage (lower numbers execute first) */
  stage?: number;
}

Usage Examples:

// Build lifecycle hook
ctx.register({
  name: 'onBuildStart',
  fn: async (opts) => {
    console.log('Build starting for platform:', opts.platform);
  }
});

// Configuration modification hook
ctx.register({
  name: 'modifyWebpackChain',
  fn: (opts, { chain }) => {
    chain.plugin('MyPlugin').use(MyWebpackPlugin, [options]);
    return { chain };
  }
});

// Hook with execution order control
ctx.register({
  name: 'modifyWebpackChain',
  stage: 100, // Execute later
  fn: (opts, { chain }) => {
    // This runs after hooks with lower stage numbers
  }
});

Build Lifecycle Hooks

Pre-defined lifecycle hooks available for build process customization.

/**
 * Hook called when build process starts
 */
onBuildStart(fn: Func): void;

/**
 * Hook called when build process finishes (after each save in watch mode)
 */
onBuildFinish(fn: Func): void;

/**
 * Hook called when build process completes (once after initial build)
 */
onBuildComplete(fn: Func): void;

/**
 * Hook called during compiler.make phase
 */
onCompilerMake(fn: (args: { compilation: Webpack.Compilation; compiler: Webpack.Compiler; plugin: any }) => void): void;

Usage Examples:

// Build start hook
ctx.onBuildStart(async (opts) => {
  console.log('Starting build...');
  // Initialize build resources
});

// Build finish hook (called on each rebuild)
ctx.onBuildFinish(async (opts) => {
  console.log('Build finished');
  // Cleanup or post-processing
});

// Build complete hook (called once)
ctx.onBuildComplete(async (opts) => {
  console.log('Initial build complete, ready for development');
  // Open browser, start additional services, etc.
});

Configuration Modification Hooks

Hooks for modifying various aspects of the build configuration.

/**
 * Modify App configuration before compilation
 */
modifyAppConfig(fn: (args: { appConfig: AppConfig }) => void): void;

/**
 * Modify webpack configuration using webpack-chain
 */
modifyWebpackChain(fn: (args: { chain: Chain; webpack: typeof Webpack; data?: IModifyChainData }) => void): void;

/**
 * Modify Vite configuration
 */
modifyViteConfig(fn: (args: { viteConfig: any; data?: IModifyChainData; viteCompilerContext: any }) => void): void;

/**
 * Modify build assets after compilation
 */
modifyBuildAssets(fn: (args: { assets: any; miniPlugin: any }) => void): void;

/**
 * Modify mini-program configuration files
 */
modifyMiniConfigs(fn: (args: { configMap: IMiniFilesConfig }) => void): void;

/**
 * Modify runner options before execution
 */
modifyRunnerOpts(fn: (args: { opts: any }) => void): void;

Usage Examples:

// Modify webpack configuration
ctx.modifyWebpackChain(({ chain, webpack }) => {
  // Add custom plugin
  chain.plugin('MyCustomPlugin')
    .use(MyCustomPlugin, [{ option: 'value' }]);
    
  // Modify loader
  chain.module
    .rule('custom-rule')
    .test(/\.custom$/)
    .use('custom-loader')
    .loader('custom-loader');
});

// Modify app configuration
ctx.modifyAppConfig(({ appConfig }) => {
  appConfig.pages.push('pages/custom/index');
  appConfig.window.navigationBarTitleText = 'Custom Title';
});

// Modify build assets
ctx.modifyBuildAssets(({ assets, miniPlugin }) => {
  // Add or modify generated files
  assets['custom-file.json'] = JSON.stringify({ custom: 'data' });
});

Command Registration

Register custom commands that can be executed via the CLI or programmatically.

/**
 * Register a custom command
 * @param command - Command configuration object
 */
registerCommand(command: ICommand): void;

interface ICommand extends IHook {
  /** Command alias for CLI */
  alias?: string;
  /** CLI options mapping for help display */
  optionsMap?: Record<string, string>;
  /** Usage examples for help display */
  synopsisList?: string[];
}

Usage Examples:

// Basic command
ctx.registerCommand({
  name: 'analyze',
  fn: async (opts) => {
    console.log('Analyzing project...');
    // Analysis logic
  }
});

// Command with CLI options and help
ctx.registerCommand({
  name: 'deploy',
  alias: 'd',
  optionsMap: {
    '--env [env]': 'deployment environment',
    '--dry-run': 'preview deployment without executing'
  },
  synopsisList: [
    'taro deploy --env production',
    'taro deploy --dry-run'
  ],
  fn: async (opts) => {
    const { env, dryRun } = opts.options;
    // Deployment logic
  }
});

Platform Registration

Register custom platforms that can be targeted for builds.

/**
 * Register a custom platform
 * @param platform - Platform configuration object
 */
registerPlatform(platform: IPlatform): void;

interface IPlatform extends IHook {
  /** Configuration section name to use for this platform */
  useConfigName?: string;
}

Usage Examples:

// Register custom platform
ctx.registerPlatform({
  name: 'my-platform',
  useConfigName: 'mini', // Use mini-program config section
  fn: (opts) => {
    const platform = new MyCustomPlatform(ctx, opts.config);
    return platform.start();
  }
});

// Register platform with custom config
ctx.registerPlatform({
  name: 'electron',
  useConfigName: 'electron',
  fn: (opts) => {
    // Electron platform build logic
  }
});

Method Registration

Register methods that can be called by other plugins.

/**
 * Register a method that can be called by other plugins
 * @param arg - Method name or configuration object
 * @param fn - Method implementation (if first arg is string)
 */
registerMethod(arg: string | { name: string; fn?: Func }, fn?: Func): void;

Usage Examples:

// Register utility method
ctx.registerMethod('getProjectInfo', () => {
  return {
    name: ctx.initialConfig.projectName,
    framework: ctx.initialConfig.framework
  };
});

// Register method with object syntax
ctx.registerMethod({
  name: 'customTransform',
  fn: (data) => {
    // Custom transformation logic
    return transformedData;
  }
});

// Use registered method in another plugin
const projectInfo = ctx.getProjectInfo();

Plugin Options Validation

Add validation schema for plugin options using Joi.

/**
 * Add validation schema for plugin options
 * @param fn - Function that receives Joi instance and returns schema
 */
addPluginOptsSchema(fn: (joi: joi.Root) => void): void;

Usage Examples:

// Add options validation
ctx.addPluginOptsSchema((joi) => {
  return joi.object({
    outputDir: joi.string().required(),
    minify: joi.boolean().default(true),
    target: joi.string().valid('es5', 'es6').default('es5'),
    plugins: joi.array().items(joi.string())
  });
});

// Plugin with validated options
export default (ctx, opts) => {
  // opts is now validated and has defaults applied
  console.log(opts.outputDir); // Required string
  console.log(opts.minify);    // Boolean, defaults to true
};

Hook Execution

Execute registered hooks programmatically within plugins.

/**
 * Execute registered hooks with optional initial value and options
 * @param args - Hook name or configuration object
 * @returns Promise resolving to final transformed value
 */
applyPlugins(args: string | { name: string; initialVal?: any; opts?: any }): Promise<any>;

Usage Examples:

// Execute simple hook
await ctx.applyPlugins('customHook');

// Execute hook with initial value (modify pattern)
const modifiedConfig = await ctx.applyPlugins({
  name: 'modifyCustomConfig',
  initialVal: baseConfig,
  opts: { context: 'build' }
});

// Execute hook and collect results (add pattern)
const additionalItems = await ctx.applyPlugins({
  name: 'addCustomItems',
  initialVal: [],
  opts: { filter: 'active' }
});

Context Properties

interface IPaths {
  /** Current command execution directory */
  appPath: string;
  /** Project configuration directory */
  configPath: string;
  /** Project source code directory */
  sourcePath: string;
  /** Build output directory */
  outputPath: string;
  /** Node modules directory */
  nodeModulesPath: string;
}

interface IPlugin {
  /** Unique plugin identifier */
  id: string;
  /** Plugin file path */
  path: string;
  /** Plugin configuration options */
  opts: any;
  /** Plugin type (Plugin or Preset) */
  type: PluginType;
  /** Plugin apply function */
  apply: Func;
}

Plugin Development Best Practices

Plugin Structure Template

export default (ctx, opts = {}) => {
  // Add options validation
  ctx.addPluginOptsSchema((joi) => {
    return joi.object({
      // Define your options schema
    });
  });

  // Register hooks
  ctx.onBuildStart(async () => {
    // Build start logic
  });

  ctx.modifyWebpackChain(({ chain }) => {
    // Webpack modifications
  });

  // Register custom methods
  ctx.registerMethod('myUtility', () => {
    // Utility logic
  });
};

Error Handling in Hooks

ctx.register({
  name: 'onBuildStart',
  fn: async (opts) => {
    try {
      // Build logic that might fail
      await riskyOperation();
    } catch (error) {
      ctx.helper.printLog('ERROR', 'Build failed', error.message);
      throw error; // Re-throw to stop build
    }
  }
});

Install with Tessl CLI

npx tessl i tessl/npm-tarojs--service

docs

configuration.md

index.md

platform-abstraction.md

plugin-context.md

plugin-system.md

tile.json