Skip to content

[RFC] build-scripts 2.0 版本设计 #82

Open
@maoxiaoke

Description

@maoxiaoke

背景

  • build-scripts 与 webpack 体系解耦,沉淀为底层插件开发服务。

方案

build-scripts 分层设计

image

Service 规范

Service 确定如何实现诸如 startbuild 的命令,可以是由函数或类实现,比如(以 webpack 为例):

import { Service } from 'build-scripts';
import start from './start';
import build from './build';
import WebpackChain from 'webpack-chain';
import webpack from 'webpack';

const webpackService = new Service<WebpackChain, Record<'webpack', typeof webpack>>({
	name: 'webpack',
	command: {
		start,
		build
	},
	bundlers: {
		wepback
	}
})

export default webpackService;

// start.ts 实现 npm run start
// build.ts 实现 npm run build
// 参考实现如下
export default start = (context: Context<WebpackChain>) => {
	const { getConfig, applyHook } = context;
	const configArr = context.getConfig();

	await applyHook(`before.${command}.load`, { xxx })

	try {
		compiler = webpackInstance(webpackConfig);
	} catch (e) {
		await applyHook('error', { err });
	}

	compiler.run((err, stats) => {
		// 
	})

	await applyHook(`after.${command}.compile`, result)
}

Service API

Service 可消费 Context 的所有 public API:

interface Context {
	command: 'build' | 'start' | 'test',
	commandArgs: object;
	rootDir: string;
	pkg: Json;
	applyHook: (key: string, opts?: {}) => Promise<void>;
	logger: Logger;
	...
}

插件 API

插件 API 与现有插件 api 基本保持一致(除部分存在命名上变更)。主要变更有:

  • onGetWebpackConfig → 变更为 onGetConfig,使用方式保持与之前不变
// 入参 config 与 registerTask 配置 对应
interface onGetConfig<T> {
	(name: string, fn: (config: T)): void;
	(fn: (config: T)): void;
}
  • registerTask 入参变更
    • 对于 webpack,注册的是 wepback-chain
    • 对于 vite,注册的是 vite config (目前对于 ice 来说,通过单一插件支持,因此注册的仍是 webpack-chian,通过一层 webpack2vite 进行了磨平)
    • 对于 rollup,注册的是 rollup 配置
  • ctx 不再默认导出 webpack

之前存在从 ctx 下导出 wepback 的场景,目的是保证使用的是统一 webpack 实例。新模式下,需要 Service 注入给 Plugin 消费。

const ctx = createContext({
	command: 'start',
	rootDir: this.options.rootDir,
	bundlers: {
		webpack
	}
})
  • configWebpack 字段修改为 setConfig,入参为 Task Config。

注册 Task

Task 通过插件注册,注册方式如下:

const plugin = ({
	registerTask
}) => {
	// 以 webpack 为例,注册 webpack-chain 配置
	registerTask('taskName', webpackConfig);
}

具体改动

  • Context API 变更

    • 移除 publicAPI registerCommandModules
    • 移除 publicAPI getCommandModule
    • 移除 pulicAPI getWebpackConfig
    • 移除 privateAPI getProjectFile - 移进 utils 文件夹,修改名为 loadPkg
    • 修改 onHook 方法为 privateAPI
  • 依赖包升级

  • Service 可消费的 api

    • command
    • commandArgs
    • rootDir
    • pkg
    • userConfig

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions