javascript - Typescript 中的可摇树策略模式
问题描述
我一直在尝试构建一个库,该库要求其消费者对每个目标使用特定的策略。我目前的架构如下:
[应用程序] -> 包含 -> [播放器] -> 包含 -> [渲染器]
目前,Renderer
是不同平台需要更换的接口:
- 移动 -> 使用 MobileRenderer
- Web -> 使用 WebRenderer
我可以自由使用任何捆绑器——目前使用 Webpack 作为应用程序,使用 Rollup 作为库——我可以实现的目标如下:
我的库导出一个Player
接口和一个createPlayer
返回PlayerInterface
. 然后,在应用程序端,我有一个 Webpack 别名,它根据构建输入解析正确的平台库。
例如:
import { createPlayer } from "my-lib";
const player = createPlayer()
然后我们构建应用程序
npm run build --platform=web
webpack 会将my-lib
导入转换为my-lib/platforms/web
,其中还包含一个createPlayer
使用正确渲染器的导出函数。
我的问题是,从应用程序的角度来看,我们如何确保在构建时为每个平台导入正确的渲染器,同时允许摇树(所以只包括正确的源)?我发现使用构建系统来做这件事是很模糊的,因为它没有留下清晰的痕迹。
有没有更好的方法来做到这一点?
最好的,
解决方案
你有几个选择。我建议不要使用编译时开关,因为这需要您分发库的多个副本(这不是惯用的)。但是,如果您真的想这样做,我建议在构建时使用 webpackProvidePlugin
或resolve.alias
config 字段将您的代码动态链接到适当的渲染器。
在我看来,更实用的方法是为您的应用程序设置两个入口点,并允许实现者选择使用哪个入口点。这类似于react-dom
浏览器渲染和服务器渲染之间的切换(即react-dom
vs react-dom/server
):
// index.js
export * from './shared';
export {default as renderer} from './renderers/web';
// mobile/index.js
export * from '../shared';
export {default as renderer} from '../renderers/mobile';
然后,使用您的图书馆的人可以import {renderer, foo} from 'your-lib'
或import {renderer, foo} from 'your-lib/mobile'
.
上述两种方法都在构建时起作用。
虽然后一种方法通常会强制您选择在代码中使用哪个版本的库,但您可以使用 webpack 的resolve.alias
配置字段来强制将导入your-lib
重定向到your-lib/mobile
.
推荐阅读
- javascript - 元素不可点击,因为另一个元素遮住了它,重叠的元素
- html - 他们不根据屏幕大小调整行和列类
- google-chrome - 如何更改 Chrome 74 中的默认黑色地址栏
- ruby - 使用包含?命令搜索包含数字和字母混合的字符串
- css - 如何为活动的引导程序 4 导航栏项目添加背景颜色
- r - 在 R 中创建具有固定断点的调色板
- applescript-objc - 使用 AppleScript-Objc 确定进度指示器
- java - 如何在@PostMapping 中返回值
- java - 对目标文件的引用。为什么/如何创建和使用它?
- python - 从数据库读取时在 Dask 数据帧中设置分区大小的问题