{"id":27316960,"url":"https://github.com/ice-lab/build-scripts","last_synced_at":"2025-05-16T12:04:21.005Z","repository":{"id":41156698,"uuid":"287015993","full_name":"ice-lab/build-scripts","owner":"ice-lab","description":":octopus: 基于 Webpack 的插件化工程构建工具，支持快速建设一套开箱即用的工程方案。","archived":false,"fork":false,"pushed_at":"2024-04-02T03:45:50.000Z","size":645,"stargazers_count":402,"open_issues_count":34,"forks_count":77,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-03-20T14:49:49.598Z","etag":null,"topics":["babel","react","webpack","webpack-plugin"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ice-lab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-08-12T13:06:00.000Z","updated_at":"2025-03-17T16:05:57.000Z","dependencies_parsed_at":"2024-04-02T04:49:01.383Z","dependency_job_id":null,"html_url":"https://github.com/ice-lab/build-scripts","commit_stats":{"total_commits":92,"total_committers":9,"mean_commits":"10.222222222222221","dds":"0.44565217391304346","last_synced_commit":"c64540e863855f12a9437eb4cf34315cad836bc9"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ice-lab%2Fbuild-scripts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ice-lab%2Fbuild-scripts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ice-lab%2Fbuild-scripts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ice-lab%2Fbuild-scripts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ice-lab","download_url":"https://codeload.github.com/ice-lab/build-scripts/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248542903,"owners_count":21121826,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["babel","react","webpack","webpack-plugin"],"created_at":"2025-04-12T08:39:26.235Z","updated_at":"2025-04-12T08:39:26.982Z","avatar_url":"https://github.com/ice-lab.png","language":"TypeScript","readme":"2.x | [1.x](https://github.com/ice-lab/build-scripts/blob/stable/1.x) | [0.x](https://github.com/ice-lab/build-scripts/blob/stable/0.x)\n\n# build-scripts\n\n[![NPM version](https://img.shields.io/npm/v/build-scripts.svg?style=flat)](https://npmjs.org/package/build-scripts)\n[![NPM downloads](https://img.shields.io/npm/dm/@alib/build-scripts.svg?style=flat)](https://npmjs.org/package/@alib/build-scripts)\n\n基于 Webpack 的插件化工程构建工具，支持快速建设一套开箱即用的工程方案。\n\n## 目录\n\n- [特性](#特性)\n- [常见问题](#常见问题)\n- [使用场景](#使用场景)\n- [能力介绍](#能力介绍)\n  - [配置文件](#配置文件)\n  - [配置插件](#配置插件)\n  - [本地自定义配置](#本地自定义配置)\n- [插件开发](#插件开发)\n  - [插件 API](#插件-API)\n  - [插件间通信](#插件间通信)\n- [版本升级](#版本升级)\n\n## 特性\n\n- 完善灵活的插件能力，帮助扩展不同工程构建的场景\n- 提供多构建任务机制，支持同时构建多份产物\n- 标准化构建\u0026调试的完整流程，同时提供 Hook 能力进行定制\n- 已支持多种场景：\n  - React 项目开发\n  - Rax 项目开发\n  - NPM 包开发\n  - 天马模块开发\n\n## 常见问题\n\n### NPM 包名是 `build-scripts` 还是 `@alib/build-scripts`？\n\n1.x 以及未来都以 `build-scripts` 为准，0.x 版本当时因为命名被占用只能使用 `@alib/build-scripts` 这个包名。\n\n### 2.x 相比 1.x 有什么变化？\n\n参考 [版本升级](#版本升级) 章节。\n\n### 何时使用 build-scripts？\n\n多个项目共享配置以及其他工程能力，同时支持插件扩展\u0026修改配置。\n\n### 使用 build-scripts 的项目如何修改工程配置？\n\nbuild-scripts 核心是提供一套完善的工程插件设计，本身不耦合任何工程配置，也不具备任何工程调试构建能力，具体的工程配置都是由插件提供的，因此此类问题建议查阅下方对应场景的文档。\n\n## 使用场景\n\n基于 build-scripts 目前已支持多种场景，覆盖大多数的研发场景，当然你可以完全自定义一套工程能力。\n\n### React 项目开发\n\n- 方案：icejs\n- 文档：https://ice.work/docs/guide/about\n- 代码：https://github.com/alibaba/ice\n\n### 天马模块\n\n私有方案\n\n### NPM 包开发\n\n- 方案：ICE PKG\n- 文档：https://pkg.ice.work/\n- 代码：https://github.com/ice-lab/icepkg\n\n### 自定义工程\n\n如果不想使用上述官方提供的解决方案，也可以基于 build-scripts 自定义完整的工程能力，具体请参考 [example](/examples/plugin-react-app/README.md) 。\n\n## 方案设计\n\n![image](https://nazha-image-store.oss-cn-shanghai.aliyuncs.com/frontends/build-scripts-arch.png)\n\n- `build-scripts` 提供核心配置、插件机制、构建生命周期等能力\n- `build-scripts` 本身不在耦合具体构建工具的设计，具体实现由上层工具决定\n\n## 能力介绍\n\nbuild-scripts 2.0 本身不耦合任何构建工具，以下能力均以官方实现的 [webpack-service](/packages/webpack-service/) 为基础\n\n\u003e webpack-service 是集合 build-scripts 和 webpack 提供的基础构建服务，能力上对标 build-scripts 1.x 版本\n\n### 配置文件\n\nbuild-scripts 默认将 `build.json` 作为工程配置文件，运行 build-scripts 命令时会默认读取当前目录的 `build.json` 文件。\n\n配置方式：\n\n```json\n{\n  \"externals\": {\n    \"react\": \"React\"\n  },\n  \"plugins\": [\n    \"build-plugin-component\",\n    \"./build.plugin.js\"\n  ]\n}\n```\n\nbuild.json 中核心包括两部分内容：\n\n- 基础配置：比如示例的 `externals` 字段，**默认情况下不支持任何字段，由基础插件通过 `registerUserConfig` API 注册扩展**\n- 插件配置：二三方插件，以及针对单个项目通过本地插件实现 webpack config 的更改\n\n除了 json 类型以外，build-scripts 也支持 ts 类型的配置文件：\n\n```js\n// build.plugin.ts\n\nexport default {\n  plugins: [],\n}\n```\n\n### 配置插件\n\n通过 `build.json` 中提供的 plugins 字段可配置插件列表，插件数组项每一项代表一个插件，build-scripts 将按顺序执行插件列表，插件配置形式如下：\n\n```json\n{\n  \"plugins\": [\n    // 数组第一项为插件名，第二项为插件参数\n    [\"build-plugin-fusion\", {\n      \"themePackage\": \"@icedesign/theme\"\n    }]\n  ]\n}\n```\n\n### 本地自定义配置\n\n如果基础配置和已有插件都无法支持业务需求，可以通过本地插件自定义配置来实现，新建 `build.plugin.js` 文件作为一个自定义插件，然后写入以下代码：\n\n```js\nmodule.exports = ({ context, onGetConfig }) =\u003e {\n  // 这里面可以写哪些，具体请查看插件开发章节\n  onGetConfig((config) =\u003e {\n  });\n}\n```\n\n最后在 `build.json` 里引入自定义插件即可：\n\n```json\n\n{\n  \"plugins\": [\n    \"build-plugin-app\",\n    \"./build.plugin.js\"\n  ]\n}\n```\n\n## 插件开发\n\n通过命令创建一个插件 npm 包：\n\n```bash\n$ npm init npm-template \u003cpluginName\u003e build-plugin-template\n$ cd \u003cpluginName\u003e\n```\n\n插件本质上是一个 Node.js 模块，入口如下：\n\n```js\nmodule.exports = ({ context, onGetConfig, onHook, ...rest }, options) =\u003e {\n  // 第一项参数为插件 API 提供的能力\n  // options：插件自定义参数\n};\n```\n\n插件方法会收到两个参数，第一个参数是插件提供的 API 接口和能力，推荐解构方式按需使用 API，第二个参数 options 是插件自定义的参数，由插件开发者决定提供哪些选项给用户自定义。\n\n### 插件 API\n\n插件可以方便扩展和自定义工程能力，这一切都基于 build-scripts 提供的插件 API。\n\n#### context\n\ncontext 参数包含运行时的各种环境信息：\n\n- `command` 当前运行命令 `start|build|test`\n- `commandArgs` script 命令执行时接受到的参数\n- `rootDir` 项目根目录\n- `originalUserConfig` 用户在 build.json 中配置的原始内容\n- `userConfig` 用户配置，包含被 modifyUserConfig 修改后的结果\n- `pkg` 项目 package.json 的内容\n\n```js\nmodule.exports = ({ context }) =\u003e {\n  const { userConfig, command, webpack } = context;\n  console.log('userConfig', userConfig);\n  console.log('command', command);\n};\n```\n\n#### onGetConfig\n\n通过 `onGetConfig` 获取通过 [registerTask](#registerTask) 注册的配置，并对配置进行自定义修改：\n\n```js\n// 场景一：修改所有 webpack 配置\nmodule.exports = ({ onGetWebpackConfig }) =\u003e {\n  onGetWebpackConfig((config) =\u003e {\n    config.entry('src/index');\n  });\n}\n\n// 场景二：多 webpack 任务情况下，修改指定任务配置\nmodule.exports = ({onGetConfig, registerTask}) =\u003e {\n  registerTask('web', webpackConfigWeb);\n  registerTask('weex', webpackConfigWeex);\n\n  onGetConfig('web'，(config) =\u003e {\n    config.entry('src/index');\n  });\n\n  onGetConfig('weex'，(config) =\u003e {\n    config.entry('src/app');\n  });\n}\n```\n\n#### onHook\n\n通过 onHook 监听命令运行时事件，onHook 注册的函数执行完成后才会执行后续操作，可以用于在命令运行中途插入插件想做的操作：\n\n```js\nmodule.exports = ({ onHook }) =\u003e {\n  onHook('before.start.load', () =\u003e {\n    // do something before dev\n  });\n  onHook('after.build.compile', stats =\u003e {\n    // do something after build\n  });\n};\n```\n\n目前的命令执行生命周期如下：\n\nstart 命令：\n\n| 生命周期               | 参数                                                           | 调用时机                                      |\n| ---------------------- | -------------------------------------------------------------- | --------------------------------------------- |\n| before.start.load      | { args: CommandArgs; webpackConfig: WebpackConfig[] }          | 获取 webpack 配置之前                         |\n| before.start.run       | { args: CommandArgs; webpackConfig: WebpackConfig[] }          | webpack 执行构建之前                          |\n| after.start.compile    | { url: string; stats: WebpackAssets; isFirstCompile: boolean } | 编译结束，每次重新编译都会执行                |\n| before.start.devServer | { url: string; devServer: WebpackDevServer }                   | server 中间件加载后，webpack devServer 启动前 |\n| after.start.devServer  | { url: string; devServer: WebpackDevServer }       | webpack devServer 启动后                      |\n\nbuild 命令：\n\n| 生命周期            | 参数                                                  | 调用时机              |\n| ------------------- | ----------------------------------------------------- | --------------------- |\n| before.build.load   | { args: CommandArgs; webpackConfig: WebpackConfig[] } | 获取 webpack 配置之前 |\n| before.build.run    | { args: CommandArgs; webpackConfig: WebpackConfig[] } | webpack 执行构建之前  |\n| after.build.compile | { url: string; stats: WebpackAssets; isFirstCompile } | 编译结束              |\n\ntest 命令：\n\n| 生命周期         | 参数                                                  | 调用时机           |\n| ---------------- | ----------------------------------------------------- | ------------------ |\n| before.test.load | { args: CommandArgs; webpackConfig: WebpackConfig[] } | 获取 jest 配置之前 |\n| before.test.run  | { args: CommandArgs; config: JestConfig }             | jest 执行构建之前  |\n| after.test       | { result: JestResult }                                | 测试结束           |\n\n#### registerUserConfig\n\n通过 registerUserConfig 注册 build.json 中的顶层配置字段，注册是可以进行用户字段校验，支持传入单个配置对象或者包含多个配置对象的数组。\n\n方法生效的生命周期，在 registerTask 和 onGetConfig 之间。\n\n配置对象字段如下：\n\n- name (string)\n\n字段名称，唯一标识，多个插件无法注册相同的字段\n保留字段：plugins\n\n- validation(string|function)\n\n字段校验，支持 string 快速校验，string|boolean|number，也可以自定义函数，根据 return 值判断校验结果\n\n- ignoreTasks(string[])\n\n配置忽略指定 webpack 任务\n\n- setConfig(function)\n\n字段效果，具体作用到 webpack 配置上，接收参数：\n\n- config：通过 registerTask 注册的配置\n- value: build.json 中的字段值\n- context：与外部 context 相同，新增字段 taskName 表现当前正在修改的 task\n\n```js\nmodule.exports = ({ registerUserConfig }) =\u003e {\n  registerUserConfig({\n    name: 'entry',\n    // validation: 'string',\n    validation: value =\u003e {\n      return typeof value === 'string';\n    },\n    config: (config, value, context) =\u003e {\n      config.mode(value);\n    },\n  });\n};\n```\n\n#### registerTask\n\n用于注册多 webpack 任务，比如 build-plugin-react-app 上已完整支持 React 链路开发，大部分情况下在默认 webpack 任务上拓展即可，无需额外注册.\n\n```js\n// 注册的 config 必须是以 webpack-chain 形式组织\nmodule.exports = ({ registerTask }) =\u003e {\n  registerTask('web', webpackConfigWeb);\n  registerTask('component', webpackConfigComponent);\n};\n```\n\n#### cancelTask\n\n用于取消已注册任务\n\n```js\nmodule.exports = ({ cancelTask }) =\u003e {\n  cancelTask('web');\n};\n```\n\n#### hasRegistration\n\n判断 build.json 中的顶层配置字段或者 cli 参数是否已经注册：\n\n```js\nmodule.exports = ({ hasRegistration }) =\u003e {\n  // 判断 build.json 顶层配置字段 entry 是否已配置\n  const hasEntryRegistered = hasRegistration('entry');\n\n  // 判断 cli --https 参数是否已被注册\n  const hasHttpsRegistered = hasRegistration('https'， 'cliOption');\n  ...\n}\n```\n\n#### modifyConfigRegistration\n\n用于修改已注册用户配置的行为：\n\n```js\nmodule.exports = ({ modifyConfigRegistration }) =\u003e {\n  modifyConfigRegistration('name', configRegistration =\u003e {\n    return {\n      ...configRegistration,\n      // 修正验证字段\n      validation: 'string',\n    };\n  });\n};\n```\n\n#### modifyUserConfig\n\n通过 modifyUserConfig 可以修改通过 registerUserConfig 注册的基础配置，在插件中快速复用基础配置的处理逻辑：\n\n```js\nmodule.exports = ({ modifyUserConfig }) =\u003e {\n  modifyUserConfig(originConfig =\u003e {\n    // 通过函数返回批量修改\n    return { ...originConfig, define: { target: 'xxxx' } };\n  });\n};\n```\n\n通过指定具体修改的基础配置，快速完成配置的修改：\n\n```js\nmodule.exports = ({ modifyUserConfig }) =\u003e {\n  modifyUserConfig('entry', 'src/app');\n\n  // 通过对象路径修改，比如修改对象 { outputAssetsPath: { js: 'js-dist'} } 可通过以下方式\n  modifyUserConfig('outputAssetsPath.js', 'js');\n\n  // 支持深合并，默认情况下 modifyUserConfig 将覆盖原有配置，通过配置参数支持配置的合并\n  modifyUserConfig('outputAssetsPath', {\n    js: 'js-output'\n  }, { deepmerge: true });\n};\n```\n\n\u003e API 执行的生命周期：所有插件对于修改配置函数将保存至 modifyConfigRegistration 中，在 runUserConfig 执行前完成对当前 userConfig 内容的修改\n\n#### registerCliOption\n\n注册各命令上支持的 cli 参数，比如 npm start --https 来开启 https：\n\n```js\nmodule.exports = ({ registerCliOption }) =\u003e {\n  registerCliOption({\n    name: 'https', // 注册的 cli 参数名称，\n    commands: ['start'], // 支持的命令，如果为空默认任何命令都将执行注册方法\n    config: (config, value, context) =\u003e {\n      // 对应命令链路上的需要执行的相关操作\n    },\n  });\n};\n```\n\n\u003e 注册函数执行周期，在 userConfig 相关注册函数执行之后。\n\n#### modifyCliRegistration\n\n用于修改已注册 cli 配置的行为：\n\n```js\nmodule.exports = ({ modifyConfigRegistration }) =\u003e {\n  modifyCliRegistration('https', cliRegistration =\u003e {\n    return {\n      ...cliRegistration,\n      // 修正 commands 字段\n      commands: ['start'],\n    };\n  });\n};\n```\n\n#### getAllTask\n\n用于获取所有注入任务的名称：\n\n```js\nmodule.exports = ({ getAllTask }) =\u003e {\n  const taskNames = getAllTask();\n  // ['web', 'miniapp']\n};\n```\n\n### 插件间通信\n\n在一些业务场景下，插件间需要进行通信：\n\n1. 不同插件之间需要知道彼此的存在来确定是否执行相应的逻辑\n2. 多个插件共有的配置信息可以抽出来，在某个插件中进行配置\n3. 上层插件的执行，需要依赖基础插件提供的方法\n\n基于上述的诉求，API 层面提供 `setValue` 和 `getValue` 来用于数据的存取，`registerMethod` 和 `applyMethod` 来解决方法的复用。\n\n#### setValue\n\n用来在 context 中注册变量，以供插件之间的通信。\n\n```js\nmodule.exports = ({ setValue }) =\u003e {\n  setValue('key', 123);\n};\n```\n\n#### getValue\n\n用来获取 context 中注册的变量。\n\n```js\nmodule.exports = ({ getValue }) =\u003e {\n  const value = getValue('key'); // 123\n};\n```\n\n#### registerMethod\n\n向工程核心注册相关方法，方便其他插件进行复用：\n\n```js\nmodule.exports = ({ registerMethod }) =\u003e {\n  // 注册方法\n  registerMethod('pipeAppRouterBefore', content =\u003e {\n    // 执行相关注册逻辑，可以返回相应的值\n    return true;\n  });\n};\n```\n\nregisterMethod 注册方式时，通过参数指定可以获取调用该方法的具体插件名：\n\n```js\nmodule.exports = ({ registerMethod }) =\u003e {\n  // 注册方法\n  registerMethod('pipeAppRouterBefore', (pluginName) =\u003e (content) =\u003e {\n    console.log('plugin name', pluginName);\n    console.log('content', content);\n    // 执行相关注册逻辑，可以返回相应的值\n    return true;\n  }, { pluginName: true });\n};\n```\n\n#### applyMethod\n\n调用其他插件的注册方法\n\n```js\nmodule.exports = ({ applyMethod }) =\u003e {\n  // 使用其他差价注册方法的方式，如果插件未注册，将返回一个 error 类型的错误\n  // 类似 new Error(`apply unkown method ${name}`)\n  const result = applyMethod('pipeAppRouterBefore', 'content');\n};\n```\n\n## 版本升级\n\n### 1.x -\u003e 2.x\n\n2.x 的核心变化：\n\n- 与 webpack 整体解耦，沉淀为插件开发服务\n- 修改与 webpack 耦合的相关 API\n\n具体的 API 变化如下：\n\n#### onGetWebpackConfig 移除\n\n`onGetWebpackConfig` 变更为 `onGetConfig`，使用方式保持与之前不变，对于调用 `onGetConfig` 获取的 config 配置内容由具体的框架决定。\n比如在 ICE PKG 下使用 API `onGetConfig` 获取的配置内容为基于 rollup 配置抽象的[配置对象](https://pkg.ice.work/reference/plugins-development)\n\n#### registerTask 变化\n\n`registerTask` 原先要求注册的任务配置必须是 `webpack-chain` 形式的配置，基于 build-scripts 2.0，其注册的内容由上层框架决定。\n比如在 ICE PKG 下，任务配置为一个对象，详解[具体配置项]((https://pkg.ice.work/reference/plugins-development))\n\n#### registerUserConfig 变化\n\n`registerUserConfig` 的参数 `configWebpack` 变更为 `setConfig`，`setConfig` 具体配置由上层框架决定：\n\n```js\nmodule.exports = ({ registerUserConfig }) =\u003e {\n  registerUserConfig({\n    name: 'custom-key',\n    validation: 'boolean' // 可选，支持类型有 string, number, array, object, boolean\n    setConfig: (config) =\u003e {\n      // config 内容由具体框架决定\n    },\n  });\n};\n```\n\n#### registerCliOption 变化\n\n`registerCliOption` 变化同 `registerUserConfig`\n\n```js\nmodule.exports = ({ registerCliOption }) =\u003e {\n  registerCliOption({\n    name: 'custom-options',\n    setConfig: (config) =\u003e {\n      // config 内容由具体框架决定\n    },\n  });\n};\n```\n\n### 0.x -\u003e 1.x\n\n1.x 核心变化：\n\n- 包名由 `@alib/build-scripts` 切换为 `build-scripts`\n- 不再依赖 webpack\u0026jest\u0026webpack-dev-server，建议由基础插件或项目自身依赖\n- 插件上下文 context 增加 originalUserConfig 字段，用于读取用户原始配置\n- userConfig 类型校验增强，支持 `string | object | array` 校验\n\n除了前两点属于不兼容改动，其他能力都保持向前兼容。\n\n#### 自定义工程\n\n在 package.json 中增加依赖：\n\n```diff\n{\n  \"devDependencies\": {\n+    \"jest\": \"^26.4.2\",\n+    \"webpack\": \"^4.27.1\",\n+    \"webpack-dev-server\": \"^4.0.0\",\n-    \"@alib/build-scripts\": \"^0.1.0\",\n+    \"build-scripts\": \"^1.0.0\",\n  }\n}\n```\n\n其中 jest 可按需判断是否需要安装，webpack 版本按需选择。修改完成后重装依赖然后重启即可。\n\n\u003e build-scripts 暂时不支持直接从 1.x 升级为 2.x，2.x 的升级必须搭配上层 service 实现，比如 build-scripts 1.x + build-plugin-component 的组件开发模式将会由 [ICE PKG](https://github.com/ice-lab/icepkg) 支持，ICE PKG 即是一个基于 build-scripts 2.x 实现的包开发方案\n\n#### React 项目（icejs）\n\n升级 icejs 2.0 即可。\n\n#### Rax 项目（rax-app）\n\nrax-app 3.8.0 以上已升级。\n\n#### 业务组件（build-plugin-component）\n\n在 package.json 中升级依赖：\n\n```diff\n{\n  \"devDependencies\": {\n-    \"@alib/build-scripts\": \"^0.1.0\",\n+    \"build-scripts\": \"^1.0.0\",\n-    \"build-plugin-component\": \"^1.0.0\",\n+    \"build-plugin-component\": \"^1.6.5\",\n  }\n}\n```\n\n\u003e build-plugin-component 从 1.6.5 开始同时兼容 build-scripts 0.x 和 1.x 两个版本\n\n#### 天马模块（@ali/build-plugin-pegasus-base）\n\n待支持\n\n## License\n\n[MIT](LICENSE)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fice-lab%2Fbuild-scripts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fice-lab%2Fbuild-scripts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fice-lab%2Fbuild-scripts/lists"}