ice-lab / build-scripts Goto Github PK
View Code? Open in Web Editor NEW:octopus: 基于 Webpack 的插件化工程构建工具,支持快速建设一套开箱即用的工程方案。
License: MIT License
:octopus: 基于 Webpack 的插件化工程构建工具,支持快速建设一套开箱即用的工程方案。
License: MIT License
webpack-chain 的部分能力受限,是否考虑开放部分直接修改 webpack config 的能力?
遇到几个 case 无法支持:
{
rules: [{
test: /\.js$/,
use: (options) => {
return [
'babel-loader',
]
}
}]
}
如题。以及生成type文件的位置如何配置。
看了下readme中并没有对应的说明,还是只能自己配置webpack?
依次执行
npm init @alilc/element lowcode-material-demo
创建 React-单组件 物料项目yarn install
yarn lowcode:dev
src/index.ts
import * as React from 'react';
import { forwardRef, ForwardRefRenderFunction } from 'react';
interface ComponentProps {
title: string;
content: string;
hhhh: string;
}
const ExampleComponent = (props: ComponentProps, ref: any) => {
const { title, content, ...others } = props;
return (
<div ref={ref} className="ExampleComponent" {...others}>
<h1>{title}</h1>
<p>test test</p>
<p>{others.hhhh}</p>
{content || 'Hello ExampleComponent'}
</div>
);
};
const RefExampleComponent = forwardRef(ExampleComponent as ForwardRefRenderFunction<any, ComponentProps>);
RefExampleComponent.displayName = 'ExampleComponent';
export default RefExampleComponent;
meta.ts
import { ComponentMetadata, Snippet } from '@alilc/lowcode-types';
const LowcodeMaterialDemoMeta: ComponentMetadata = {
"componentName": "LowcodeMaterialDemo",
"title": "LowcodeMaterialDemo",
"docUrl": "",
"screenshot": "",
"devMode": "proCode",
"npm": {
"package": "lowcode-material-demo",
"version": "0.1.0",
"exportName": "default",
"main": "src/index.tsx",
"destructuring": false,
"subName": ""
},
"configure": {
"props": [
{
"title": {
"label": {
"type": "i18n",
"en-US": "title",
"zh-CN": "title"
}
},
"name": "title",
"setter": {
"componentName": "StringSetter",
"isRequired": true,
"initialValue": ""
}
},
{
"title": {
"label": {
"type": "i18n",
"en-US": "content",
"zh-CN": "content"
}
},
"name": "content",
"setter": {
"componentName": "StringSetter",
"isRequired": true,
"initialValue": ""
}
},
{
"title": {
"label": {
"type": "i18n",
"en-US": "hhhh",
"zh-CN": "hhhh"
}
},
"name": "hhhh",
"setter": {
"componentName": "StringSetter",
"isRequired": true,
"initialValue": ""
}
},
{
"title": {
"label": {
"type": "i18n",
"en-US": "cbb",
"zh-CN": "cbb"
}
},
"name": "cbb",
"setter": {
"componentName": "StringSetter",
"isRequired": true,
"initialValue": ""
}
},
{
"title": {
"label": {
"type": "i18n",
"en-US": "ref",
"zh-CN": "ref"
}
},
"name": "ref",
"setter": {
"componentName": "MixedSetter",
"props": {
"setters": [
{
"componentName": "FunctionSetter"
},
{
"componentName": "ObjectSetter",
"props": {
"config": {
"extraSetter": {
"componentName": "MixedSetter",
"isRequired": false,
"props": {}
}
}
},
"isRequired": false,
"initialValue": {}
}
]
}
}
},
{
"title": {
"label": {
"type": "i18n",
"en-US": "key",
"zh-CN": "key"
}
},
"name": "key",
"setter": {
"componentName": "MixedSetter",
"props": {
"setters": [
{
"componentName": "StringSetter",
"isRequired": false,
"initialValue": ""
},
{
"componentName": "NumberSetter",
"isRequired": false,
"initialValue": 0
}
]
}
}
}
],
"supports": {
"style": true
},
"component": {}
}
};
const snippets: Snippet[] = [
{
"title": "LowcodeMaterialDemo",
"screenshot": "",
"schema": {
"componentName": "LowcodeMaterialDemo",
"props": {}
}
}
];
export default {
...LowcodeMaterialDemoMeta,
snippets
};
meta.ts 中的内容是因为没有自动更新,然后手动修改的
通过 modifyUserConfig 修改后,最新的 userConfig 会在下一个执行插件中生效,而当前插件中通过 api.context.userConfig 没有发生变化
目前 build-scripts 工程工具应用于 icejs、rax-app 等框架体系,框架中内置了大量的插件及其功能。而对于三方插件其执行顺序永远在内置插件之后,对于一些强制依赖所有配置完成修改后的能力(如 rax-app wirteToDisk 配置依赖 outputDir 的设置)将会出现失效的情况。因此希望能提供一些机制动态设置插件执行顺序
目前插件的规范是以默认导出的 JavaScript 模块的方式导出:
// esm
export default () => {}
// cjs
module.exports = () => {}
通过导出规范的约束,增加执行顺序的设置
// esm
export default {
plugin: () => {},
enforce: 'pre'
}
// cjs
module.exports = {
plugin: () => {},
enfore: 'pre'
}
enforce 可选值为 pre(前置执行)、normal(默认)、post(后置执行)
执行顺序如下:
运行抛出异常 CONFIG Failed to get config
,排查ing ~
https://github.com/ice-lab/build-scripts/blob/master/packages/build-scripts/src/core/Context.ts#L993
发现源码有抛出详细的异常信息,但是这时候 hook 还没有注册,这该如何拿到呢?
目前 build.config.mjs
支持以 esm 规范进行开发,插件在最终执行的时候通过 require 执行,导致无法使用 esm 规范
期望能够统一使用 esm 规范进行开发
我在开发低代码引擎的设置器,官方的脚手架工具是这个,它用的就是@alib/build-scripts的版本是0.1.32。
目前我找不到build-scripts的文档,build.json如下
执行build-scripts start会报错:
现在开发要调用接口,怎么办
逻辑后置可能产生的问题:
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 基本保持一致(除部分存在命名上变更)。主要变更有:
onGetWebpackConfig
→ 变更为 onGetConfig
,使用方式保持与之前不变// 入参 config 与 registerTask 配置 对应
interface onGetConfig<T> {
(name: string, fn: (config: T)): void;
(fn: (config: T)): void;
}
registerTask
入参变更
ctx
不再默认导出 webpack
之前存在从 ctx 下导出 wepback 的场景,目的是保证使用的是统一 webpack 实例。新模式下,需要 Service 注入给 Plugin 消费。
const ctx = createContext({
command: 'start',
rootDir: this.options.rootDir,
bundlers: {
webpack
}
})
configWebpack
字段修改为 setConfig
,入参为 Task Config。Task 通过插件注册,注册方式如下:
const plugin = ({
registerTask
}) => {
// 以 webpack 为例,注册 webpack-chain 配置
registerTask('taskName', webpackConfig);
}
Context API 变更
registerCommandModules
getCommandModule
getWebpackConfig
getProjectFile
- 移进 utils 文件夹,修改名为 loadPkg依赖包升级
Service 可消费的 api
md 中的代码区不能正确显示在md文件中间位置,而是直接挂到了最末尾位置
ERR! [Config File] Config key 'module' is not supported
my build.json
{
"entry": {
"preview": "./src/preview.tsx",
"app": "./src/index.js"
},
"vendor": false,
"devServer": {
"hot": false
},
"publicPath": "/",
"externals": {
"react": "var window.React",
"react-dom": "var window.ReactDOM",
"prop-types": "var window.PropTypes",
"@alifd/next": "var window.Next",
"@alilc/lowcode-engine": "var window.AliLowCodeEngine",
"@alilc/lowcode-editor-core": "var window.AliLowCodeEngine.common.editorCabin",
"@alilc/lowcode-editor-skeleton": "var window.AliLowCodeEngine.common.skeletonCabin",
"@alilc/lowcode-designer": "var window.AliLowCodeEngine.common.designerCabin",
"@alilc/lowcode-engine-ext": "var window.AliLowCodeEngineExt",
"@ali/lowcode-engine": "var window.AliLowCodeEngine",
"moment": "var window.moment",
"lodash": "var window._"
},
"plugins": [
[
"build-plugin-react-app"
],
[
"build-plugin-moment-locales",
{
"locales": [
"zh-cn"
]
}
],
"./build.plugin.js"
],
"module": {
"rules": [
{
"use": "babel-loader"
},
]
}
}
then when i run "npm run start "
> @alilc/[email protected] start /Users/limi/Downloads/lowcode-demo
> build-scripts start --disable-reload --port 5556
@alib/build-scripts 0.1.32
ERR! CONFIG Failed to get config.
ERR! [Config File] Config key 'module' is not supported
Error: [Config File] Config key 'module' is not supported
at Context.<anonymous> (/Users/limi/Downloads/lowcode-demo/node_modules/@alib/build-scripts/lib/core/Context.js:340:31)
at Generator.next (<anonymous>)
at /Users/limi/Downloads/lowcode-demo/node_modules/@alib/build-scripts/lib/core/Context.js:8:71
at new Promise (<anonymous>)
at __awaiter (/Users/limi/Downloads/lowcode-demo/node_modules/@alib/build-scripts/lib/core/Context.js:4:12)
at Context.runUserConfig (/Users/limi/Downloads/lowcode-demo/node_modules/@alib/build-scripts/lib/core/Context.js:334:36)
at Context.<anonymous> (/Users/limi/Downloads/lowcode-demo/node_modules/@alib/build-scripts/lib/core/Context.js:406:24)
at Generator.next (<anonymous>)
at fulfilled (/Users/limi/Downloads/lowcode-demo/node_modules/@alib/build-scripts/lib/core/Context.js:5:58)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @alilc/[email protected] start: `build-scripts start --disable-reload --port 5556`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @alilc/[email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/limi/.npm/_logs/2022-04-12T02_08_33_543Z-debug.log
目前针对测试用例的代码调试,只能通过 console 等手段来进行,希望 test 命令支持跟 chrome 或者 ide 结合的断点调试能力
请教下,为什么 onGetWebpackConfig 不执行?
提示 WARN CONFIG No webpack config found.
"build-plugin-component": "^1.11.0",
"build-scripts": "^1.3.0",
"jest": "^26.4.2",
"webpack": "^4.43.0",
"webpack-dev-server": "^3.11.3"
// build.json 文件内容
{
"externals": {
"react": "var window.React",
"react-dom": "var window.ReactDOM",
},
"plugins": [
"build-plugin-component",
"./build.plugin.js"
]
}
// build.plugin.js 文件内容
module.exports = ({ onGetWebpackConfig }) => {
onGetWebpackConfig((config) => {
// 这里为啥不执行?
console.log('---------');
console.log('---------');
console.log('---------');
});
};
开发中有时需要在依赖包的代码中进行修改与调试,现在发现修改后无法生效,重新 start 也不行,这个要怎么处理?
目前仅支持 build.json,其他都必须通过 --config
指定,建议默认支持三个:build.json > build.config.js > build.config.ts
Node: 14.17.4
npm: 6.14.14
> build-scripts start
build-scripts 1.1.1
internal/modules/cjs/loader.js:892
throw err;
^
Error: Cannot find module 'inquirer'
Require stack:
- ..../node_modules/build-scripts/bin/child-process-start.js
build-scripts 支持了 registerUserConfig
、registerCliOption
来扩展工程配置,注册的时候会支持检验配置的类型,比如:
registerUserConfig({
name: 'target',
validation: 'object'
});
而在日常实践中,大多数配置可能需要支持多种数据类型,比如既可以是字符串也可以是数组(string|string[]
)。对于这种形式的配置项只能通过函数的形式支持,不方便开发进行快捷定义多类型的配置。
期望 build-scripts 在 validation
配置上支持以 string|array|object
的形式,快捷定义多类型的工程配置:
registerUserConfig({
name: 'target',
validation: 'string|object'
});
validation 配置为 字符串的形式下,默认以 |
字符解析多种数据类型,可选类型为:string | number | array | object | boolean
对于更加严格的配置控制,依旧推荐通过函数的方式传入
build-scripts 内置依赖 webpack 4.x,让具体的项目依赖中无需关心 webpack 版本。
而随着 webpack 5 的发布,越来越多工程配置开始希望使用 webpack 5 的新能力,目前在 build-scripts 工程体系下需要进行如下的配置开启 webpack 5 的使用:
"customWebpack": true
的方式指定使用项目依赖中的 webpack上述的配置方式相对比较繁琐,对于开发者并不友好,希望能够移除底层对于 webpack 的依赖。
webpack 从 dependencies 中移除,具体的 webpack 版本 由具体的基础插件对 webpack 版本进行管控。
我们工程是用vue写的,正在使用飞冰开发自己的物料库,在开发页面级物料时发现build-scripts只支持react工程的调试和构建,希望build-scripts能支持vue工程的调试和构建
如何区分多环境呢,我发现cross-env不好使呢
发现引入es模块文件超过500kb就构建不起来?需要在.babelrc 中开启 compact: false
在项目根目录或者packages/* 子包下面添加发现不生效,如何才能生效呢?
在组件开发项目中:
{
"build-plugin-component": "^1.9.2",
"build-scripts": "^1.2.1",
"webpack": "^5.64.4",
"webpack-dev-server": "^4.6.0"
}
运行 build-scripts start 报错
ERR! Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options has an unknown property 'overlay'. These properties are valid:
object { allowedHosts?, bonjour?, client?, compress?, devMiddleware?, headers?, historyApiFallback?, host?, hot?, http2?, https?, ipc?, liveReload?, magicHtml?, onAfterSetupMiddleware?, onBeforeSetupMiddleware?, onListening?, open?, port?, proxy?, server?, setupExitSignals?, static?, watchFiles?, webSocketServer? }
运行 build-scripts build 正常
在 build-scripts 2.0 设计中支持的 plugin 设置包括以下两种:
PluginOption 的类型名称定位上不够清晰,跟其内部的 plugin 关系有重叠
备选方案:
统一导出 plugins 配置类型: type Plugin = PluginOption | PluginLegacy | [string, object]
PluginOption 包含 { name, setup, runtime }
/ { name, config, runtime }
使用rax
构建微信小程序,使用build/wechat-miniprogram
作为微信开发者工具的项目根目录,执行rax-app build
命令后,文件夹build/wechat-miniprogram
在构建过程中被删除并重新生成,旧文件夹的删除导致了微信开发者工具不能读取项目的project.config.json
,不得不在微信开发者工具中重新打开项目。
我认为在执行build命令时,不删除文件夹build/wechat-miniprogram
,而是仅清空build/wechat-miniprogram
下的内容可能会更合理
macOS 10.15.7
node v14.15.4
npm v7.4.3
rax-app v3.3.3
@alib/build-scripts v0.1.30
rax-app build
编译项目后,将build/wechat-miniprogram
作为项目根目录使用微信开发者工具打开rax-app build
,构建完成后,微信开发者工具不能正常读取项目内容根据rax文档的小程序配置将项目根目录作为微信开发者工具的项目根目录,但是这需要在项目根目录创建project.config.json
。个人认为project.config.json
应该作为rax
根据build.config.js
构建的产物出现在build/wechat-miniprogram
文件夹下更合理,同时,希望project.config.json
中的appid
是在构建过程中build.config.js
读取环境变量生成的,因此这个方案不能满足我的要求。
目前遇到的需求是在start命令下,在代码编译前做一些log输出,当前start相关的声明周期无法满足这个需求。
> build-scripts start --config=build.config.js --port=3456
build-scripts 1.0.1
ERR! CONFIG Failed to get config.
ERR! [Config File] Config key 'entry' is not supported
如题,我在 自定义插件中 获取 dev server 端口号,无法获取。
tnpm i
npm run test
npm run test 可以正常
build-scripts/packages/build-scripts/src/service/build.ts
Lines 28 to 41 in 5e2cef2
目前会在 before.build.load 之后,before.build.run 之前删除,对于开发者通过自定义钩子往构建目录添加内容会有一定的认知成本,希望优化成执行 build 整体逻辑之前进行清空
由于项目需要根据适配不同的环境,用的场景也不一样,需要支持多config打包
希望增加SIGINT信号钩子
build-plugin-cone-split-schema
该插件会在编译时生成大量临时文件,
进程完成前中断,则临时文件会保留,
再次启动,这些临时文件会影响第二次编译,
且这些临时文件会污染git changes
build-scripts 提供了多任务的能力,开发者可以针对同一工程构建添加多个 webpack 任务。而所有的用户配置对 webpack 任务的修改默认对所有的任务生效。面向一些多任务的场景,存在定制的配置需求,并不希望基础的用户配置对当前任务照成影响(目前出现影响后通过自定义 webpack 配置重新覆盖,成本较高)
onGetWebpackConfig 已支持指定 task 生效的方式,而 registerUserConfig 和 registerCliOption 默认均未提供
为了方便不同插件间对于已添加配置有更强的定制能力,期望通过一下方式增强自定义工程配置的能力:
// registerUserConfig / registerCliOptions 支持 ignoreTask
registerUserConfig({
name: 'target',
validation: 'object',
ignoreTasks: ['ssr'],
configWebpack: () => {}
});
// 新增 modifyRegisterConfig 获取修改配置,理论上应该支持除 name 外,所有配置属性修改
modifyConfigRegistration('configName', (config) => {
return {
ignoreTasks: ['ssr', 'web']
}
});
start 命令下部分场景希望不启动 dev server
复现步骤
tnpm install
npm run setup
npm run build
错误信息看的有点懵,麻烦帮忙看看如何解决下
想加入css-loader 请问如何
@ClarkXia @maoxiaoke
目前支持的配置文件有:
问题:
.mjs
进行代码解析,会导致配置代码无法使用 cjs 语法(比如 config.ts 中使用 require 语法)区分仓库为 es module (使用 import 加载)和 commonjs (使用 require 加载)。以下会识别为 es module 仓库:
.mjs
、.mts
结尾的配置文件type: module
的 .js
和 .ts
的文件方案一存在的问题在于社区仍存在大量生态不支持项目配置 type: module
,现阶段下,在非 type: module
的仓库中无法使用 import
语法。因此方案二不以 type: module
来区分 es module。策略如下:
.cjs
和 .cts
结尾的文件以 commonjs 方式加载A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.