build-shiny-module
À propos
Cette compétence aide les développeurs à créer des modules Shiny réutilisables avec une isolation appropriée des espaces de noms en utilisant NS(). Elle couvre la construction de paires interface utilisateur/serveur, la gestion des valeurs réactives, et permet la communication et l'imbrication des modules. Utilisez-la pour extraire des composants réutilisables d'applications en croissance ou pour encapsuler une logique complexe derrière des interfaces claires.
Installation rapide
Claude Code
Recommandénpx skills add pjt222/agent-almanac -a claude-code/plugin add https://github.com/pjt222/agent-almanacgit clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/build-shiny-moduleCopiez et collez cette commande dans Claude Code pour installer cette compétence
Documentation
Build Shiny Module
創具正命名空間隔離、反應式溝通、可組合之可復用 Shiny UI/server 模組對。
適用時機
- 自漸長之 Shiny 應用抽可復用組件
- 建多處可用之 UI 小部件
- 以潔介面封繁之反應邏輯
- 自更小可測之單位組大應用
輸入
- 必要:模組之旨與功能描
- 必要:輸入/輸出之合同(模組受何返何)
- 選擇性:模組是否嵌他模組(預設:否)
- 選擇性:框架脈絡(golem、rhino、或 vanilla)
步驟
步驟一:定模組介面
書代碼前,定模組所受所返:
Module: data_filter
Inputs: reactive dataset, column names to filter on
Outputs: reactive filtered dataset
UI: filter controls (selectInput, sliderInput, dateRangeInput)
預期: 明之合同,指定反應輸入、反應輸出、UI 元素。
失敗時: 若介面不明,模組恐過廣。分為單責之小模組。
步驟二:創模組 UI 函
#' Data Filter Module UI
#'
#' @param id Module namespace ID
#' @return A tagList of filter controls
#' @export
dataFilterUI <- function(id) {
ns <- NS(id)
tagList(
selectInput(
ns("column"),
"Filter column",
choices = NULL
),
uiOutput(ns("filter_control")),
actionButton(ns("apply"), "Apply Filter", class = "btn-primary")
)
}
要則:
- 函名循
<name>UI約定 - 首參恆為
id - 於頂立
ns <- NS(id) - 每
inputId與outputId皆包於ns() - 返
tagList()以允彈性置
預期: UI 函創命名空間之輸入/輸出元素。
失敗時: 若用模組二次時 ID 碰撞,查每 ID 皆包於 ns()。常漏:renderUI() 或 uiOutput() 內之 ID——此亦需 ns()。
步驟三:創模組伺服器函
#' Data Filter Module Server
#'
#' @param id Module namespace ID
#' @param data Reactive expression returning a data frame
#' @param columns Character vector of filterable column names
#' @return Reactive expression returning the filtered data frame
#' @export
dataFilterServer <- function(id, data, columns) {
moduleServer(id, function(input, output, session) {
ns <- session$ns
# Update column choices when data changes
observeEvent(data(), {
available <- intersect(columns, names(data()))
updateSelectInput(session, "column", choices = available)
})
# Dynamic filter control based on selected column
output$filter_control <- renderUI({
req(input$column)
col_data <- data()[[input$column]]
if (is.numeric(col_data)) {
sliderInput(
ns("value_range"),
"Range",
min = min(col_data, na.rm = TRUE),
max = max(col_data, na.rm = TRUE),
value = range(col_data, na.rm = TRUE)
)
} else {
selectInput(
ns("value_select"),
"Values",
choices = unique(col_data),
multiple = TRUE,
selected = unique(col_data)
)
}
})
# Return filtered data as a reactive
filtered <- eventReactive(input$apply, {
req(input$column)
col <- input$column
df <- data()
if (is.numeric(df[[col]])) {
req(input$value_range)
df[df[[col]] >= input$value_range[1] &
df[[col]] <= input$value_range[2], ]
} else {
req(input$value_select)
df[df[[col]] %in% input$value_select, ]
}
}, ignoreNULL = FALSE)
return(filtered)
})
}
要則:
- 函名循
<name>Server約定 - 首參恆為
id - 餘參為反應式表達或靜值
- 用
moduleServer(id, function(input, output, session) { ... }) - 伺服器內創之動態 UI 用
session$ns - 明返反應值
預期: 伺服器函處輸入、返反應輸出。
失敗時: 若反應值不更,查動態 UI 之輸入用 session$ns(非外之 ns)。若模組返 NULL,確 return() 為 moduleServer() 內末表達。
步驟四:於父應用接模組
# In app_ui.R or ui
ui <- page_sidebar(
title = "Analysis App",
sidebar = sidebar(
dataFilterUI("filter1")
),
card(
DT::dataTableOutput("table")
)
)
# In app_server.R or server
server <- function(input, output, session) {
# Raw data source
raw_data <- reactive({ mtcars })
# Call module — capture its return value
filtered_data <- dataFilterServer(
"filter1",
data = raw_data,
columns = c("cyl", "mpg", "hp", "wt")
)
# Use the module's returned reactive
output$table <- DT::renderDataTable({
filtered_data()
})
}
預期: 模組於 UI 顯,其所返反應流至下游輸出。
失敗時: 若模組 UI 不渲,驗 UI 與伺服器呼間 id 字串相符。若所返反應為 NULL,查伺服器函實返值。
步驟五:組嵌模組(選)
含他模組之模組:
analysisUI <- function(id) {
ns <- NS(id)
tagList(
dataFilterUI(ns("filter")),
plotOutput(ns("plot"))
)
}
analysisServer <- function(id, data) {
moduleServer(id, function(input, output, session) {
# Call inner module with namespaced ID
filtered <- dataFilterServer("filter", data = data, columns = names(data()))
output$plot <- renderPlot({
req(filtered())
plot(filtered())
})
return(filtered)
})
}
要則:UI 中以 ns("inner_id") 嵌。伺服器中僅以 "inner_id" 呼——moduleServer 處命名空間之鏈。
預期: 內模組於外模組之命名空間中正渲。
失敗時: 若內模組 UI 不現,恐忘於外 UI 函中以 ns() 包內模組 ID。若伺服器溝通斷,查內模組 ID 相符(伺服器呼中無 ns())。
步驟六:隔離測模組
# Quick test app for the module
if (interactive()) {
shiny::shinyApp(
ui = fluidPage(
dataFilterUI("test"),
DT::dataTableOutput("result")
),
server = function(input, output, session) {
data <- reactive(iris)
filtered <- dataFilterServer("test", data, names(iris))
output$result <- DT::renderDataTable(filtered())
}
)
}
預期: 模組於最小測應用中正工。
失敗時: 若模組於隔離敗而於全應用工(或反),查對全域變或父會話狀態之隱依。
驗證
- 模組 UI 函受
id為首參且用NS(id) - UI 中每輸入/輸出 ID 皆包於
ns() - 模組伺服器用
moduleServer(id, function(input, output, session) { ... }) - 伺服器中動態 UI 之 ID 用
session$ns - 模組可實例化多次而無 ID 碰撞
- 反應返值可為父應用存取
- 模組於最小獨立測應用中工
常見陷阱
renderUI()中忘ns():伺服器內創之動態 UI 須用session$ns——外之ns於moduleServer()內不可得- 傳非反應數據:隨時變之模組參須為反應式表達。傳
reactive(data)非data - ID 失配:UI 呼中之
id字串須與伺服器呼中之id完相符 - 不返反應:若模組算父所需之物,須
return()一反應。忘此為默錯 - 嵌模組之命名空間:UI:
ns("inner_id")。伺服器:僅"inner_id"。混致雙包或漏前綴
相關技能
scaffold-shiny-app— 加模組前立應用結構test-shiny-app— 以 testServer() 單元測測模組design-shiny-ui— 模組 UI 之 bslib 版型與主題optimize-shiny-performance— 模組內之快取與 async 模式
Dépôt GitHub
Compétences associées
content-collections
MétaCette compétence propose une configuration éprouvée en production pour Content Collections, un outil axé sur TypeScript qui transforme des fichiers Markdown/MDX en collections de données typées de manière sûre avec une validation Zod. Utilisez-la lors de la création de blogs, de sites de documentation ou d'applications Vite + React riches en contenu pour garantir la sécurité de typage et la validation automatique du contenu. Elle couvre tout, de la configuration du plugin Vite et de la compilation MDX à l'optimisation des déploiements et la validation des schémas.
polymarket
MétaCette compétence permet aux développeurs de créer des applications avec la plateforme de marchés prédictifs Polymarket, incluant l'intégration d'API pour le trading et les données de marché. Elle fournit également une diffusion de données en temps réel via WebSocket pour surveiller les transactions en direct et l'activité du marché. Utilisez-la pour mettre en œuvre des stratégies de trading ou pour créer des outils traitant les mises à jour de marché en direct.
creating-opencode-plugins
MétaCette compétence aide les développeurs à créer des plugins OpenCode qui s'interconnectent avec plus de 25 types d'événements tels que les commandes, les fichiers et les opérations LSP. Elle fournit la structure du plugin, les spécifications de l'API événementielle et les modèles d'implémentation pour les modules JavaScript/TypeScript. Utilisez-la lorsque vous avez besoin d'intercepter, de surveiller ou d'étendre le cycle de vie de l'assistant IA OpenCode avec une logique personnalisée pilotée par les événements.
sglang
MétaSGLang est un framework de service LLM haute performance spécialisé dans la génération rapide et structurée pour les workflows JSON, regex et agentiques grâce à son cache de préfixe RadixAttention. Il offre une inférence nettement plus rapide, particulièrement pour les tâches avec des préfixes répétés, ce qui le rend idéal pour les sorties complexes et structurées ainsi que les conversations multi-tours. Choisissez SGLang plutôt que des alternatives comme vLLM lorsque vous avez besoin d'un décodage contraint ou que vous construisez des applications avec un partage étendu de préfixes.
