Skip to content

Commit

Permalink
feat: Allow disabling CSS and JS minification per file
Browse files Browse the repository at this point in the history
See #651
  • Loading branch information
abusch authored and ctron committed Dec 20, 2023
1 parent 07ec22d commit 4b68c74
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 14 deletions.
1 change: 1 addition & 0 deletions examples/vanilla/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

<link data-trunk rel="scss" href="src/index.scss"/>
<link data-trunk rel="css" href="src/app.css"/>
<link data-trunk data-no-minify rel="css" href="src/not_minified.css"/>
<base data-trunk-public-url/>
</head>
<body>
Expand Down
4 changes: 4 additions & 0 deletions examples/vanilla/src/not_minified.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.should_not_be_minified:checked:hover {
--empty-prop: ;
background-color: black;
}
3 changes: 3 additions & 0 deletions site/content/assets.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ This will typically look like: `<link data-trunk rel="{type}" href="{path}" ..ot

- In the future, Trunk will resolve local `@imports`, will handle minification (see [trunk#7](https://github.com/trunk-rs/trunk/issues/7)), and we may even look into a pattern where any CSS found in the source tree will be bundled, which would enable a nice zero-config "component styles" pattern. See [trunk#3](https://github.com/trunk-rs/trunk/issues/3) for more details.
- `data-integrity`: (optional) the `integrity` digest type for code & script resources. Defaults to plain `sha384`.
- `data-no-minify`: (optional) by default, CSS files are minified in `--release` mode (unless building with `--no-minification`). Setting this attribute disables minification for that particular file. Defaults to false.

## tailwind

Expand Down Expand Up @@ -103,6 +104,8 @@ This will typically look like: `<script data-trunk src="{path}" ..other options

Trunk will copy script files found in the source HTML without content modification. This content is hashed for cache control. The `src` attribute must be included in the script pointing to the script file to be processed.

- `data-no-minify`: (optional) by default, scripts are minified in `--release` mode (unless building with `--no-minification`). Setting this attribute disables minification for that particular file. Defaults to false.

## JS Snippets

JS snippets generated from the [wasm-bindgen JS snippets feature](https://rustwasm.github.io/docs/wasm-bindgen/reference/js-snippets.html) are automatically copied to the dist dir, hashed and ready to rock. No additional setup is required. Just use the feature in your application, and Trunk will take care of the rest.
Expand Down
10 changes: 8 additions & 2 deletions src/pipelines/css.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! CSS asset pipeline.
use super::{AssetFile, AttrWriter, Attrs, TrunkAssetPipelineOutput, ATTR_HREF};
use super::{AssetFile, AttrWriter, Attrs, TrunkAssetPipelineOutput, ATTR_HREF, ATTR_MINIFY};
use crate::{
config::RtcBuild,
pipelines::AssetFileType,
Expand All @@ -24,6 +24,8 @@ pub struct Css {
attrs: Attrs,
/// The required integrity setting
integrity: IntegrityType,
/// Whether to minify or not
minify: bool,
}

impl Css {
Expand All @@ -45,12 +47,15 @@ impl Css {

let integrity = IntegrityType::from_attrs(&attrs, &cfg)?;

let minify = attrs.get(ATTR_MINIFY).is_none();

Ok(Self {
id,
cfg,
asset,
attrs,
integrity,
minify,
})
}

Expand All @@ -65,12 +70,13 @@ impl Css {
async fn run(self) -> Result<TrunkAssetPipelineOutput> {
let rel_path = crate::common::strip_prefix(&self.asset.path);
tracing::info!(path = ?rel_path, "copying & hashing css");
let minify = self.cfg.release && self.minify && !self.cfg.no_minification;
let file = self
.asset
.copy(
&self.cfg.staging_dist,
self.cfg.filehash,
self.cfg.release && !self.cfg.no_minification,
minify,
AssetFileType::Css,
)
.await?;
Expand Down
18 changes: 8 additions & 10 deletions src/pipelines/js.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! JS asset pipeline.
use super::{AssetFile, AttrWriter, Attrs, TrunkAssetPipelineOutput, ATTR_SRC};
use super::{AssetFile, AttrWriter, Attrs, TrunkAssetPipelineOutput, ATTR_MINIFY, ATTR_SRC};
use crate::{
config::RtcBuild,
pipelines::AssetFileType,
Expand All @@ -26,6 +26,8 @@ pub struct Js {
integrity: IntegrityType,
/// If it's a JavaScript module (vs a classic script)
module: bool,
/// Whether to minify or not
minify: bool,
}

impl Js {
Expand All @@ -44,14 +46,8 @@ impl Js {
let asset = AssetFile::new(&html_dir, path).await?;

let integrity = IntegrityType::from_attrs(&attrs, &cfg)?;

let module = attrs.get("type").map(|s| s.as_str()) == Some("module");

// Remove src and data-trunk from attributes.
let attrs = attrs
.into_iter()
.filter(|(x, _)| *x != "src" && !x.starts_with("data-trunk"))
.collect();
let minify = attrs.get(ATTR_MINIFY).is_none();

Ok(Self {
id,
Expand All @@ -60,6 +56,7 @@ impl Js {
module,
attrs,
integrity,
minify,
})
}

Expand All @@ -74,12 +71,13 @@ impl Js {
async fn run(self) -> Result<TrunkAssetPipelineOutput> {
let rel_path = crate::common::strip_prefix(&self.asset.path);
tracing::info!(path = ?rel_path, "copying & hashing js");
let minify = self.cfg.release && self.minify && !self.cfg.no_minification;
let file = self
.asset
.copy(
&self.cfg.staging_dist,
self.cfg.filehash,
self.cfg.release && !self.cfg.no_minification,
minify,
if self.module {
AssetFileType::Mjs
} else {
Expand Down Expand Up @@ -130,7 +128,7 @@ impl JsOutput {
dom.select(&super::trunk_script_id_selector(self.id))
.replace_with_html(format!(
r#"<script src="{base}{file}"{attrs}/>"#,
attrs = AttrWriter::new(&attrs, &[]),
attrs = AttrWriter::new(&attrs, AttrWriter::EXCLUDE_SCRIPT),
base = &self.cfg.public_url,
file = self.file
));
Expand Down
15 changes: 13 additions & 2 deletions src/pipelines/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const ATTR_HREF: &str = "href";
const ATTR_SRC: &str = "src";
const ATTR_TYPE: &str = "type";
const ATTR_REL: &str = "rel";
const ATTR_MINIFY: &str = "data-no-minify";
const SNIPPETS_DIR: &str = "snippets";
const TRUNK_ID: &str = "data-trunk-id";
const PNG_OPTIMIZATION_LEVEL: u8 = 6;
Expand Down Expand Up @@ -352,11 +353,21 @@ impl<'a> AttrWriter<'a> {
ATTR_INLINE,
ATTR_SRC,
ATTR_TYPE,
ATTR_MINIFY,
];
/// Whereas on link elements, the MIME type for css is A-OK. You can even specify a custom
/// MIME type.
pub(self) const EXCLUDE_CSS_LINK: &'static [&'static str] =
&[TRUNK_ID, ATTR_HREF, ATTR_REL, ATTR_INLINE, ATTR_SRC];
pub(self) const EXCLUDE_CSS_LINK: &'static [&'static str] = &[
TRUNK_ID,
ATTR_HREF,
ATTR_REL,
ATTR_INLINE,
ATTR_SRC,
ATTR_MINIFY,
];

/// Attributes to ignore for <script> tags
pub(self) const EXCLUDE_SCRIPT: &'static [&'static str] = &[ATTR_SRC, ATTR_MINIFY];

pub(self) fn new(attrs: &'a Attrs, exclude: &'a [&'a str]) -> Self {
Self { attrs, exclude }
Expand Down

0 comments on commit 4b68c74

Please sign in to comment.