Skip to content

Commit ee34398

Browse files
authored
fix: Only copy pre-compiled themes once (#1184)
* refactor: break `bs_theme_dependencies()` into smaller functions * refactor: Copy js assets when prepping theme out file * fix: Only copy precompiled dependency once * chore: use hash of bootstrap js file * docs: Add news item
1 parent c9bb6e1 commit ee34398

28 files changed

+96
-69
lines changed

NEWS.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# bslib (development version)
22

3+
## Improvements and bug fixes
4+
5+
* `bs_theme_dependencies()` now avoids unecessarily copying internal package files to R's temporary directory more than once when preparing precompiled theme dependencies (e.g. for a standard `bs_theme()` theme). (#1184)
6+
37
# bslib 0.9.0
48

59
## Breaking changes

R/bs-dependencies.R

+88-65
Original file line numberDiff line numberDiff line change
@@ -71,71 +71,10 @@ bs_theme_dependencies <- function(
7171
cache <- sass_cache_get_dir(cache)
7272
}
7373

74-
out_file <- NULL
75-
# Look for a precompiled css file if user asks for it AND the default options
76-
# are used.
77-
if (
78-
precompiled &&
79-
identical(sass_options, sass_options(output_style = "compressed"))
80-
) {
81-
precompiled_css <- precompiled_css_path(theme)
82-
if (!is.null(precompiled_css)) {
83-
out_dir <- file.path(tempdir(), paste0("bslib-precompiled-", version))
84-
if (!dir.exists(out_dir)) {
85-
dir.create(out_dir)
86-
}
87-
out_file <- file.path(out_dir, basename(precompiled_css))
88-
file.copy(precompiled_css, out_file)
89-
90-
# Usually sass() would handle file_attachments and dependencies,
91-
# but we need to do this manually
92-
out_file <- attachDependencies(out_file, htmlDependencies(as_sass(theme)))
93-
write_file_attachments(
94-
as_sass_layer(theme)$file_attachments,
95-
out_dir
96-
)
97-
}
98-
}
74+
out_file <- maybe_precompiled_css(theme, sass_options, precompiled)
9975

100-
# If precompiled css not found, compile normally.
10176
if (is.null(out_file)) {
102-
contrast_warn <- get_shiny_devmode_option(
103-
"bslib.color_contrast_warnings",
104-
default = FALSE,
105-
devmode_default = TRUE,
106-
devmode_message = paste(
107-
"Enabling warnings about low color contrasts found inside `bslib::bs_theme()`.",
108-
"To suppress these warnings, set `options(bslib.color_contrast_warnings = FALSE)`"
109-
)
110-
)
111-
theme <- bs_add_variables(theme, "color-contrast-warnings" = contrast_warn)
112-
113-
out_file <- sass(
114-
input = theme,
115-
options = sass_options,
116-
output = output_template(basename = "bootstrap", dirname = "bslib-"),
117-
cache = cache,
118-
write_attachments = TRUE,
119-
cache_key_extra = list(
120-
get_exact_version(version),
121-
get_package_version("bslib")
122-
)
123-
)
124-
}
125-
126-
out_file_dir <- dirname(out_file)
127-
128-
js_files <- bootstrap_javascript(version)
129-
js_map_files <- bootstrap_javascript_map(version)
130-
success_js_files <- file.copy(
131-
c(js_files, js_map_files),
132-
out_file_dir,
133-
overwrite = TRUE
134-
)
135-
if (any(!success_js_files)) {
136-
warning(
137-
"Failed to copy over bootstrap's javascript files into the htmlDependency() directory."
138-
)
77+
out_file <- sass_compile_theme(theme, sass_options, cache)
13978
}
14079

14180
htmltools::resolveDependencies(
@@ -145,9 +84,9 @@ bs_theme_dependencies <- function(
14584
htmlDependency(
14685
name = "bootstrap",
14786
version = get_exact_version(version),
148-
src = out_file_dir,
87+
src = dirname(out_file),
14988
stylesheet = basename(out_file),
150-
script = basename(js_files),
89+
script = basename(bootstrap_javascript(version)),
15190
all_files = TRUE, # include font and map files
15291
meta = list(
15392
viewport = "width=device-width, initial-scale=1, shrink-to-fit=no"
@@ -159,6 +98,90 @@ bs_theme_dependencies <- function(
15998
)
16099
}
161100

101+
maybe_precompiled_css <- function(theme, sass_options, precompiled) {
102+
if (!precompiled) return()
103+
if (!identical(sass_options, sass_options(output_style = "compressed"))) {
104+
return()
105+
}
106+
107+
precompiled_css <- precompiled_css_path(theme)
108+
if (is.null(precompiled_css)) {
109+
return()
110+
}
111+
112+
version <- theme_version(theme)
113+
bs_js_hash <- rlang::hash_file(bootstrap_javascript(version))
114+
out_dir <- file.path(
115+
tempdir(),
116+
sprintf("bslib-precompiled-%s-%s", version, bs_js_hash)
117+
)
118+
119+
out_file <- file.path(out_dir, basename(precompiled_css))
120+
out_file <- attachDependencies(out_file, htmlDependencies(as_sass(theme)))
121+
122+
if (dir.exists(out_dir)) {
123+
# We've already copied all the files for this precompiled theme, there's no
124+
# need to copy them again.
125+
return(out_file)
126+
}
127+
128+
dir.create(out_dir)
129+
file.copy(precompiled_css, out_file)
130+
131+
# Usually sass() would handle file_attachments and dependencies,
132+
# but we need to do this manually
133+
write_file_attachments(
134+
as_sass_layer(theme)$file_attachments,
135+
out_dir
136+
)
137+
138+
bootstrap_javascript_copy_assets(version, dirname(out_file))
139+
140+
out_file
141+
}
142+
143+
sass_compile_theme <- function(theme, sass_options, sass_cache) {
144+
version <- theme_version(theme)
145+
146+
contrast_warn <- get_shiny_devmode_option(
147+
"bslib.color_contrast_warnings",
148+
default = FALSE,
149+
devmode_default = TRUE,
150+
devmode_message = paste(
151+
"Enabling warnings about low color contrasts found inside `bslib::bs_theme()`.",
152+
"To suppress these warnings, set `options(bslib.color_contrast_warnings = FALSE)`"
153+
)
154+
)
155+
theme <- bs_add_variables(theme, "color-contrast-warnings" = contrast_warn)
156+
157+
out_file <- sass(
158+
input = theme,
159+
options = sass_options,
160+
output = output_template(basename = "bootstrap", dirname = "bslib-"),
161+
cache = sass_cache,
162+
write_attachments = TRUE,
163+
cache_key_extra = list(
164+
get_exact_version(version),
165+
get_package_version("bslib")
166+
)
167+
)
168+
169+
bootstrap_javascript_copy_assets(version, dirname(out_file))
170+
171+
out_file
172+
}
173+
174+
bootstrap_javascript_copy_assets <- function(version, to) {
175+
js_files <- bootstrap_javascript(version)
176+
js_map_files <- bootstrap_javascript_map(version)
177+
success_js_files <- file.copy(c(js_files, js_map_files), to, overwrite = TRUE)
178+
if (any(!success_js_files)) {
179+
warning(
180+
"Failed to copy over bootstrap's javascript files into the htmlDependency() directory."
181+
)
182+
}
183+
}
184+
162185
#' Themeable HTML components
163186
#'
164187
#' @description

R/sysdata.rda

842 Bytes
Binary file not shown.

inst/components/dist/components.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

inst/components/dist/components.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

inst/components/dist/web-components.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

inst/components/dist/web-components.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/figures/navset-card-pill.png

111 Bytes
Loading

man/figures/navset-card-underline.png

18 Bytes
Loading

man/figures/navset-pill-list.png

252 Bytes
Loading

man/figures/navset-pill.png

233 Bytes
Loading

man/figures/navset-tab-basic.png

127 Bytes
Loading

man/figures/navset-tab-card.png

234 Bytes
Loading

man/figures/navset-tab.png

206 Bytes
Loading

man/figures/navset-underline.png

15 Bytes
Loading

man/figures/page-navbar.png

264 Bytes
Loading
127 Bytes
Loading
167 Bytes
Loading

man/figures/value-box-custom.png

70 Bytes
Loading

man/figures/value-box-gradient-1.png

213 Bytes
Loading

man/figures/value-box-named-color.png

112 Bytes
Loading

man/figures/value-box-named-theme.png

136 Bytes
Loading
151 Bytes
Loading
150 Bytes
Loading
108 Bytes
Loading

man/figures/value-box-text-color.png

131 Bytes
Loading

man/figures/value-box-text-theme.png

172 Bytes
Loading

man/figures/value-box-theme-class.png

146 Bytes
Loading

0 commit comments

Comments
 (0)