* commit '6e270d0bd4efe001a3fd003ee2600a45b121d007': (161 commits) auto upgrade version to 2.0.20220826175704 bugfix: bug auto upgrade version to 2.0.20220826171804 REPORT-77978 fix: 下拉树水印表现异常问题 auto upgrade version to 2.0.20220826110757 无JIRA fix:按钮 textAlign 失效 auto upgrade version to 2.0.20220826090446 auto upgrade version to 2.0.20220825194716 DESIGN-4402 fix: 复选树视觉问题 auto upgrade version to 2.0.20220825163610 KERNEL-12552 feat: 不执行BI.init(),很多方法调用会出现问题 BI-107557 单选下拉null值显示处理 && 更新图标 auto upgrade version to 2.0.20220825115604 chore: 修改loader auto upgrade version to 2.0.20220824175535 DESIGN-4402 fix: 复选树视觉问题 auto upgrade version to 2.0.20220824165610 chore: 更新 auto upgrade version to 2.0.20220823231616 auto upgrade version to 2.0.20220823191436 ...research/test
@ -0,0 +1,48 @@ |
|||||||
|
import { ${WorkerName}MainThreadWorker } from './main_thread/${workerName}_main_thread'; |
||||||
|
// 不需要一起打包的话则不需要引入这行 |
||||||
|
// FuiWorkerPlugin中的属性会同步到fui-worker中,同时支持loader行内传入属性 |
||||||
|
// 根据实际需求传入inline,返回格式 true -> blob url,false -> servicePath |
||||||
|
import { workerUrl } from 'fui-worker!./worker_thread/${workerName}_worker_thread'; |
||||||
|
|
||||||
|
export class ${WorkerName}WorkerHelper { |
||||||
|
private worker: ${WorkerName}MainThreadWorker; |
||||||
|
|
||||||
|
/** |
||||||
|
* 拿到helper中的worker |
||||||
|
*/ |
||||||
|
public getWorker() { |
||||||
|
if (this.worker) { |
||||||
|
return this.worker; |
||||||
|
} |
||||||
|
|
||||||
|
this.worker = BI.Workers.createWorker(${WorkerName}MainThreadWorker, { |
||||||
|
workerUrl: this.urlFormatter(workerUrl), |
||||||
|
workerName: BI.UUID(), |
||||||
|
}); |
||||||
|
|
||||||
|
return this.worker; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 格式化worker url,比如补充一些环境信息到参数里 |
||||||
|
* 可通过 #hash 将参数传入blob url |
||||||
|
* @param url worker url |
||||||
|
*/ |
||||||
|
private urlFormatter(url: string) { |
||||||
|
return url; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 终止worker |
||||||
|
*/ |
||||||
|
public terminate() { |
||||||
|
this.worker?.terminate(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 使用示例 |
||||||
|
// const workerHelper = new ${WorkerName}WorkerHelper(); |
||||||
|
|
||||||
|
// workerHelper.getWorker() |
||||||
|
// .testCommunication() |
||||||
|
// .then(res => console.log(res)); |
@ -0,0 +1,13 @@ |
|||||||
|
import { WorkerAbilityTestActionType } from '../../utils/action_type'; |
||||||
|
import { WorkerAbilityTestPayload, WorkerAbilityTestReponse } from '../../utils/payload_type'; |
||||||
|
|
||||||
|
export class WorkerAbilityTestMainThreadAction extends BI.Workers.WorkerBaseAction { |
||||||
|
/** |
||||||
|
* 通信能力检测 |
||||||
|
*/ |
||||||
|
public communicationTest(): Promise<WorkerAbilityTestReponse['CommunicationTest']> { |
||||||
|
const mainThreadPostTime: WorkerAbilityTestPayload['CommunicationTest'] = Date.now(); |
||||||
|
|
||||||
|
return this.controller.requestPromise(WorkerAbilityTestActionType.CommunicationTest, mainThreadPostTime); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
import { WorkerAbilityTestMainThreadAction } from './action/action.worker_ability_test'; |
||||||
|
|
||||||
|
export class ${WorkerName}MainThreadWorker extends BI.Workers.MainThreadWorker { |
||||||
|
private communicationTest: WorkerAbilityTestMainThreadAction; |
||||||
|
|
||||||
|
public initActions(): void { |
||||||
|
this.communicationTest = this.createAction(WorkerAbilityTestMainThreadAction); |
||||||
|
} |
||||||
|
|
||||||
|
public testCommunication() { |
||||||
|
return this.communicationTest.communicationTest(); |
||||||
|
} |
||||||
|
} |
@ -1,5 +0,0 @@ |
|||||||
class CrudMainTreadWorker extends BI.Workers.MainThreadWorker { |
|
||||||
protected initActions(): void { |
|
||||||
// to init some actions
|
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,8 @@ |
|||||||
|
/* |
||||||
|
* Worker 事务标识 |
||||||
|
* 每类事务有命名空间, 包含多个具体事务 |
||||||
|
*/ |
||||||
|
|
||||||
|
export const enum WorkerAbilityTestActionType { |
||||||
|
CommunicationTest = 'CommunicationTest', |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
/** |
||||||
|
* 跨线程通信各事务的发送数据类型声明 |
||||||
|
*/ |
||||||
|
export interface WorkerAbilityTestPayload { |
||||||
|
CommunicationTest: number; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 跨线程通信各事务的响应数据类型声明 |
||||||
|
*/ |
||||||
|
export interface WorkerAbilityTestReponse { |
||||||
|
CommunicationTest: number; |
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
import { WorkerAbilityTestActionType } from '../../utils/action_type'; |
||||||
|
import { WorkerAbilityTestPayload, WorkerAbilityTestReponse } from '../../utils/payload_type'; |
||||||
|
|
||||||
|
export class WorkerAbilityTestWorkerThreadAction extends BI.Workers.WorkerBaseAction { |
||||||
|
protected addActionHandler(): void { |
||||||
|
this.controller.addActionHandler( |
||||||
|
WorkerAbilityTestActionType.CommunicationTest, |
||||||
|
this.communicationTest.bind(this) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 通信能力检测的处理器 |
||||||
|
*/ |
||||||
|
private communicationTest( |
||||||
|
payload: WorkerAbilityTestPayload['CommunicationTest'] |
||||||
|
): WorkerAbilityTestReponse['CommunicationTest'] { |
||||||
|
const mainThreadPostTime = payload; |
||||||
|
// 收到主线程信息的耗时 |
||||||
|
const workerGetMessageDuration = Date.now() - mainThreadPostTime; |
||||||
|
|
||||||
|
return workerGetMessageDuration; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
// TODO: 这边需要先import fineui资源 |
||||||
|
import { WorkerAbilityTestWorkerThreadAction } from './action/action.worker_ability_test'; |
||||||
|
|
||||||
|
class ${WorkerName}WorkerTreadWorker extends BI.Workers.WorkerThreadWorker { |
||||||
|
public communicationTest: WorkerAbilityTestWorkerThreadAction; |
||||||
|
|
||||||
|
public initActions(): void { |
||||||
|
this.communicationTest = this.createAction(WorkerAbilityTestWorkerThreadAction); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export const ${workerName}WorkerTreadWorker = BI.Workers.createWorker(${WorkerName}WorkerTreadWorker); |
@ -1,5 +0,0 @@ |
|||||||
class CrudWorkerTreadWorker extends BI.Workers.MainThreadWorker { |
|
||||||
protected initActions(): void { |
|
||||||
// to init some actions
|
|
||||||
} |
|
||||||
} |
|
Before Width: | Height: | Size: 673 KiB After Width: | Height: | Size: 693 KiB |
Before Width: | Height: | Size: 371 B After Width: | Height: | Size: 394 B |
Before Width: | Height: | Size: 454 B After Width: | Height: | Size: 473 B |
Before Width: | Height: | Size: 494 B After Width: | Height: | Size: 509 B |
Before Width: | Height: | Size: 462 B After Width: | Height: | Size: 476 B |
Before Width: | Height: | Size: 417 B After Width: | Height: | Size: 434 B |
Before Width: | Height: | Size: 308 B After Width: | Height: | Size: 330 B |
Before Width: | Height: | Size: 393 B After Width: | Height: | Size: 409 B |
Before Width: | Height: | Size: 431 B After Width: | Height: | Size: 466 B |
Before Width: | Height: | Size: 401 B After Width: | Height: | Size: 415 B |
Before Width: | Height: | Size: 352 B After Width: | Height: | Size: 376 B |
Before Width: | Height: | Size: 178 B After Width: | Height: | Size: 216 B |
Before Width: | Height: | Size: 217 B After Width: | Height: | Size: 233 B |
Before Width: | Height: | Size: 255 B After Width: | Height: | Size: 255 B |
Before Width: | Height: | Size: 215 B After Width: | Height: | Size: 215 B |
Before Width: | Height: | Size: 429 B After Width: | Height: | Size: 495 B |
Before Width: | Height: | Size: 505 B After Width: | Height: | Size: 581 B |
Before Width: | Height: | Size: 547 B After Width: | Height: | Size: 619 B |
Before Width: | Height: | Size: 515 B After Width: | Height: | Size: 580 B |
Before Width: | Height: | Size: 468 B After Width: | Height: | Size: 538 B |
Before Width: | Height: | Size: 336 B After Width: | Height: | Size: 392 B |
Before Width: | Height: | Size: 419 B After Width: | Height: | Size: 476 B |
Before Width: | Height: | Size: 458 B After Width: | Height: | Size: 513 B |
Before Width: | Height: | Size: 429 B After Width: | Height: | Size: 477 B |
Before Width: | Height: | Size: 381 B After Width: | Height: | Size: 434 B |
Before Width: | Height: | Size: 217 B After Width: | Height: | Size: 233 B |
Before Width: | Height: | Size: 255 B After Width: | Height: | Size: 255 B |
Before Width: | Height: | Size: 215 B After Width: | Height: | Size: 215 B |
Before Width: | Height: | Size: 117 B After Width: | Height: | Size: 216 B |
@ -1 +1 @@ |
|||||||
lodash core plus="debounce,throttle,get,set,findIndex,findLastIndex,findKey,findLastKey,isArrayLike,invert,invertBy,uniq,uniqBy,omit,omitBy,zip,unzip,rest,range,random,reject,intersection,drop,countBy,union,zipObject,initial,cloneDeep,clamp,isPlainObject,take,takeRight,without,difference,defaultsDeep,trim,merge,groupBy,uniqBy,before,after,unescape" |
lodash core plus="debounce,throttle,get,set,findIndex,findLastIndex,findKey,findLastKey,isArrayLike,invert,invertBy,uniq,uniqBy,omit,omitBy,zip,unzip,rest,range,random,reject,intersection,drop,countBy,union,zipObject,initial,cloneDeep,clamp,isPlainObject,take,takeRight,without,difference,defaultsDeep,trim,merge,groupBy,uniqBy,before,after,unescape,chunk" |
||||||
|
@ -0,0 +1,9 @@ |
|||||||
|
const WorkerPluginName = 'FuiWorkerPlugin'; |
||||||
|
const WorkerLoaderName = 'FuiWorkerWorkerLoader'; |
||||||
|
const FileNamePrefix = 'worker-'; |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
WorkerPluginName, |
||||||
|
WorkerLoaderName, |
||||||
|
FileNamePrefix, |
||||||
|
}; |
@ -0,0 +1,79 @@ |
|||||||
|
/* |
||||||
|
* worker-plugin |
||||||
|
*/ |
||||||
|
|
||||||
|
const path = require('path'); |
||||||
|
const webpack = require('webpack'); |
||||||
|
const { WorkerPluginName } = require('./constants'); |
||||||
|
const ModuleFilenameHelpers = require('webpack/lib/ModuleFilenameHelpers'); |
||||||
|
|
||||||
|
class FuiWorkerPlugin { |
||||||
|
constructor(options = {}) { |
||||||
|
this.options = options; |
||||||
|
} |
||||||
|
|
||||||
|
apply(compiler) { |
||||||
|
// 为主线程构建添加 __WORKER__ 环境变量, 构建中区分不同线程源码, 实现代码拆减
|
||||||
|
compiler.hooks.afterPlugins.tap(WorkerPluginName, compiler => { |
||||||
|
new webpack.DefinePlugin({ |
||||||
|
// __WORKER__ 表示当前所在线程是否是 worker 线程
|
||||||
|
// 主线程构建中为 false
|
||||||
|
__WORKER__: false, |
||||||
|
}).apply(compiler); |
||||||
|
}); |
||||||
|
|
||||||
|
// 添加自定义的worker entry-loader
|
||||||
|
compiler.hooks.afterResolvers.tap(WorkerPluginName, compiler => { |
||||||
|
/** |
||||||
|
* https://webpack.js.org/configuration/resolve/#resolveloader
|
||||||
|
* 使用 resolveloader 添加自定义的 worker loader |
||||||
|
*/ |
||||||
|
if (!compiler.options.resolveLoader) { |
||||||
|
compiler.options.resolveLoader = { |
||||||
|
alias: {}, |
||||||
|
}; |
||||||
|
} |
||||||
|
if (!compiler.options.resolveLoader.alias) { |
||||||
|
compiler.options.resolveLoader.alias = {}; |
||||||
|
} |
||||||
|
|
||||||
|
// 动态添加 worker 的 worker-loader, 命名为 "fui-worker"
|
||||||
|
compiler.options.resolveLoader.alias['fui-worker'] = path.resolve(__dirname, './worker-loader.js'); |
||||||
|
}); |
||||||
|
|
||||||
|
// 将FuiWorkerPlugin的参数传递给fui-worker loader
|
||||||
|
compiler.hooks.compilation.tap(WorkerPluginName, compilation => { |
||||||
|
compilation.hooks.normalModuleLoader.tap(WorkerPluginName, (context, module) => { |
||||||
|
// 仅提供给fui-worker
|
||||||
|
const fuiLoader = module.loaders.find(loader => loader.loader.indexOf('fui-worker') !== -1); |
||||||
|
|
||||||
|
if (fuiLoader) { |
||||||
|
const resource = module.resource; |
||||||
|
|
||||||
|
if (!resource) return; |
||||||
|
|
||||||
|
// fui-worker通过options读取
|
||||||
|
context.options = context.options || {}; |
||||||
|
|
||||||
|
const index = resource.indexOf('?'); |
||||||
|
|
||||||
|
if (ModuleFilenameHelpers.matchObject( |
||||||
|
this.options, |
||||||
|
index < 0 ? resource : resource.substr(0, index) |
||||||
|
)) { |
||||||
|
for (const key of Object.keys(this.options)) { |
||||||
|
// 忽略关键属性
|
||||||
|
if (key === "include" || key === "exclude" || key === "test") { |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
context.options[key] = this.options[key]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = FuiWorkerPlugin; |
@ -0,0 +1,137 @@ |
|||||||
|
/* |
||||||
|
* fui-worker worker-loader |
||||||
|
*/ |
||||||
|
|
||||||
|
const webpack = require('webpack'); |
||||||
|
const loaderUtils = require('loader-utils'); |
||||||
|
const SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin'); |
||||||
|
const { WorkerLoaderName, FileNamePrefix } = require('./constants'); |
||||||
|
const { resolve } = require('path'); |
||||||
|
|
||||||
|
// 正常 loader 处理逻辑
|
||||||
|
function loader() { |
||||||
|
const callback = this.async(); |
||||||
|
this.cacheable(false); |
||||||
|
|
||||||
|
// 过滤掉当前的 worker-loader, 保留 worker 侧构建需要的其他 loader(babel-loader/ts-loader 等)
|
||||||
|
const otherLoaders = this.loaders.filter((loader, index) => { |
||||||
|
if (index === this.loaderIndex) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
}); |
||||||
|
/** |
||||||
|
* 拼接构建需要的 loader 字符串, 用于指定 childCompiler 的构建 loader |
||||||
|
* 比如: /path/to/babel-loader/lib/index.js!/path/to/ts-loader/index.js! |
||||||
|
*/ |
||||||
|
const loaderPath = otherLoaders.reduce((pre, loader) => `${pre}${loader.path}!`, ''); |
||||||
|
|
||||||
|
/** |
||||||
|
* worker 独立构建的 entry |
||||||
|
* 构建 loader + worker 源码入口文件路径 |
||||||
|
* |
||||||
|
* https://webpack.js.org/concepts/loaders/#inline
|
||||||
|
* `!!` 实现在 childCompiler 中忽略其他所有 loader, 只保留主构建的 loader |
||||||
|
* 不然 worker 入口在 childCompiler 中会继续由 worker-loader 处理, 造成死循环 |
||||||
|
*/ |
||||||
|
const workerEntry = `!!${loaderPath}${this.resourcePath}`; |
||||||
|
|
||||||
|
// 把资源纳入构建流程的依赖, 实现 dev 模式下的 watch
|
||||||
|
this.addDependency(workerEntry); |
||||||
|
|
||||||
|
// 生成的 service 独立 bundle 名称
|
||||||
|
const entryFileName = `${FileNamePrefix}index`; |
||||||
|
|
||||||
|
// 获取传递给 loader 的 options
|
||||||
|
const options = Object.assign(loaderUtils.getOptions(this) || {}, this.options); |
||||||
|
|
||||||
|
// 创建 childCompiler, 用于实现 worker 构建为独立 js 资源
|
||||||
|
const childCompiler = this._compilation.createChildCompiler(WorkerLoaderName, { |
||||||
|
globalObject: 'this', |
||||||
|
}); |
||||||
|
childCompiler.context = this._compiler.context; |
||||||
|
|
||||||
|
// 指定独立构建的 entry 和生成 js 资源名称
|
||||||
|
new SingleEntryPlugin(this.context, workerEntry, entryFileName).apply(childCompiler); |
||||||
|
|
||||||
|
// 设置 worker 侧的环境变量
|
||||||
|
new webpack.DefinePlugin({ |
||||||
|
__WORKER__: true, |
||||||
|
}).apply(childCompiler); |
||||||
|
|
||||||
|
// 添加 window 全局对象, 映射为 worker 线程全局对象 self
|
||||||
|
// 如果在 worker 源码中添加, 可能没有前置到所有引用模块前
|
||||||
|
new webpack.BannerPlugin({ |
||||||
|
banner: 'self.window = self;', |
||||||
|
raw: true, |
||||||
|
entryOnly: true, |
||||||
|
}).apply(childCompiler); |
||||||
|
|
||||||
|
// 去除源码中的less css引用
|
||||||
|
const regExp = /\.(css|less)$/; |
||||||
|
|
||||||
|
new webpack.NormalModuleReplacementPlugin( |
||||||
|
regExp, |
||||||
|
result => { |
||||||
|
if (regExp.test(result.request)) { |
||||||
|
result.request = resolve(__dirname, './empty.js'); |
||||||
|
} |
||||||
|
|
||||||
|
if (regExp.test(result.resource)) { |
||||||
|
result.resource = resolve(__dirname, './empty.js'); |
||||||
|
} |
||||||
|
}, |
||||||
|
).apply(childCompiler); |
||||||
|
|
||||||
|
const subCache = `subcache ${__dirname} ${workerEntry}`; |
||||||
|
childCompiler.hooks.compilation.tap(WorkerLoaderName, compilation => { |
||||||
|
if (compilation.cache) { |
||||||
|
if (!compilation.cache[subCache]) compilation.cache[subCache] = {}; |
||||||
|
compilation.cache = compilation.cache[subCache]; |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
childCompiler.runAsChild((error, entries, compilation) => { |
||||||
|
if (!error && compilation.errors && compilation.errors.length) { |
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
error = compilation.errors[0]; |
||||||
|
} |
||||||
|
|
||||||
|
// compatible with Array (v4) and Set (v5) prototypes
|
||||||
|
const entry = entries && entries[0] && entries[0].files.values().next().value; |
||||||
|
if (!error && !entry) { |
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
error = Error(`${WorkerLoaderName}, no entry for ${workerEntry}`); |
||||||
|
} |
||||||
|
|
||||||
|
if (error) { |
||||||
|
return callback(error); |
||||||
|
} |
||||||
|
|
||||||
|
// 支持blob url形式
|
||||||
|
return options.inline |
||||||
|
? callback( |
||||||
|
null, |
||||||
|
// 插入代码的转译和压缩由主构建配置的 babel/ts loader 处理, 不需要 worker-worker 来处理
|
||||||
|
// 添加 @ts-nocheck 避免 ts-check 报错
|
||||||
|
// 修复export const 下 const不会被转译的问题
|
||||||
|
`// @ts-nocheck
|
||||||
|
const blob = new Blob([${JSON.stringify(compilation.assets[entry].source())}]); |
||||||
|
const workerUrl = window.URL.createObjectURL(blob); |
||||||
|
export default workerUrl; |
||||||
|
` |
||||||
|
) |
||||||
|
: callback( |
||||||
|
null, |
||||||
|
`// @ts-nocheck
|
||||||
|
const servicePath = __webpack_public_path__ + ${JSON.stringify(entry)}; |
||||||
|
export default servicePath; |
||||||
|
` |
||||||
|
) |
||||||
|
}); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = loader; |
@ -1,11 +1,9 @@ |
|||||||
BI.prepares.push(function () { |
BI.Resizers = new BI.ResizeController(); |
||||||
BI.Resizers = new BI.ResizeController(); |
BI.Layers = new BI.LayerController(); |
||||||
BI.Layers = new BI.LayerController(); |
BI.Maskers = new BI.MaskersController(); |
||||||
BI.Maskers = new BI.MaskersController(); |
BI.Bubbles = new BI.BubblesController(); |
||||||
BI.Bubbles = new BI.BubblesController(); |
BI.Tooltips = new BI.TooltipsController(); |
||||||
BI.Tooltips = new BI.TooltipsController(); |
BI.Popovers = new BI.PopoverController(); |
||||||
BI.Popovers = new BI.PopoverController(); |
BI.Drawers = new BI.DrawerController(); |
||||||
BI.Drawers = new BI.DrawerController(); |
BI.Broadcasts = new BI.BroadcastController(); |
||||||
BI.Broadcasts = new BI.BroadcastController(); |
BI.StyleLoaders = new BI.StyleLoaderManager(); |
||||||
BI.StyleLoaders = new BI.StyleLoaderManager(); |
|
||||||
}); |
|
||||||
|