build-scripts
build-scripts copied to clipboard
[RFC] build-scripts 2.0 版本设计
背景
- build-scripts 与 webpack 体系解耦,沉淀为底层插件开发服务。
方案
build-scripts 分层设计
Service 规范
Service 确定如何实现诸如 start
、build
的命令,可以是由函数或类实现,比如(以 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 变更
- [x] 移除 publicAPI
registerCommandModules
- [x] 移除 publicAPI
getCommandModule
- [x] 移除 pulicAPI
getWebpackConfig
- [x] 移除 privateAPI
getProjectFile
- 移进 utils 文件夹,修改名为 loadPkg - [x] 修改 onHook 方法为 privateAPI
- [x] 移除 publicAPI
-
依赖包升级
- [x] chalk 升级为 picocolors
-
Service 可消费的 api
- command
- commandArgs
- rootDir
- pkg
- userConfig
建议补充下 现有 webpack 体系在新架构下涉及到哪些 API 需要定制,已经定制逻辑中的伪代码
对于 getConfig,最好增加标识看下当前是 webpack 还是 rollup,避免webpack4 => 5的恶心的兼容
对于 getConfig,最好增加标识看下当前是 webpack 还是 rollup,避免webpack4 => 5的恶心的兼容
指的是在配置层面能够感知 具体是 webpack 还是 rollup? getConfig 上的 config 具体包含哪些配置主要由上层工具决定,比如 ice/pkg 和 icejs