Skip to content

Commit

Permalink
Release 0.7.0
Browse files Browse the repository at this point in the history
- Deprecate the `skipBundlingFilter` option in favor of filtering out all tags with a `data-ssr-only` attribute in the module template when the `ignoreSSROnly` experimental option is set to true
  • Loading branch information
jaredcwhite committed Mar 28, 2023
1 parent 010588d commit 196366b
Show file tree
Hide file tree
Showing 9 changed files with 39 additions and 12 deletions.
10 changes: 10 additions & 0 deletions .gitpod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This configuration file was automatically generated by Gitpod.
# Please adjust to your needs (see https://www.gitpod.io/docs/introduction/learn-gitpod/gitpod-yaml)
# and commit this file to your remote git repository to share the goodness with others.

# Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart

tasks:
- init: npm install


9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Changelog

All notable changes to this project will be documented in this file.

## Upcoming

## [0.7.0](https://github.com/whitefusionhq/esbuild-plugin-html-modules/compare/v0.6.0...v0.7.0) - 2023-03-28

- Deprecate the `skipBundlingFilter` option in favor of filtering out all tags with a `data-ssr-only` attribute in the module template when the `ignoreSSROnly` experimental option is set to true
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ htmlModulesPlugin({
extractGlobalStyles: true,
extractScopedStyles: true,
exportLocalStylesExtension: "css-local",
skipBundlingFilter: /\.tmpl\.html$/,
ignoreSSROnly: true,
transformLocalStyles: async (css, { filePath }) => {
const postCssConfig = await postcssrc()
const postCssProcessor = postcss([...postCssConfig.plugins])
Expand All @@ -108,7 +108,7 @@ If you define a `transformLocalStyles` function, then any local style tag contai

As part of transforming local styles, you can optionally export those transformed styles into "sidecar" CSS output file. This can be helpful if you would like another process to use those styles in SSR. By setting the `exportLocalStylesExtension` option, a file with the provided extension will be saved right alongside the HTML module. **Note:** it's highly recommended you add that extension to your `.gitignore` file as they're purely build-time automated.

You can also specify a filename filter for HTML modules you do _not_ wish to include in esbuild's bundled JS output. This will effectively set their exported default template to a blank fragment and ignore all script tags. You would want to do this for HTML modules which are intended purely for SSR and are not designed for inclusion in a frontend JS bundle. In the `skipBundlingFilter: /\.tmpl\.html$/` example above, any HTML module ending in the double extension `.tmpl.html` will be skipped in this fashion.
For controlling the bundling characteristics of "split" components where some (or all!) functionality is server-only, you can set the `ignoreSSROnly` option to `true`. This will then filter out (aka remove) any elements in the module with a `data-ssr-only` attribute present. For example, you could have a `template` tag, `script` tag, and `style` tag which _all_ feature `data-ssr-only`, and therefore the bundled module would export a blank fragment. This technique can work well for "resumable" components which don't require access to the full module template at client-side runtime.

**Note:** this does _not_ skip the styles processing. Any local style tags will still be transformed if those options have been set, and any scoped or global styles will be extracted if those options have been set.

Expand Down
12 changes: 9 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = (options = {}) => ({
// Process .html files as ES modules
build.onLoad({ filter }, async (args) => {
const results = await fs.readFile(args.path, "utf8")
const ignoreSSROnly = options.experimental?.ignoreSSROnly || false

let scripts = []
let removeNodes = []
Expand All @@ -19,7 +20,7 @@ module.exports = (options = {}) => ({

const scriptTags = root.getElementsByTagName("script")
scriptTags.forEach((node) => {
if (node.getAttribute("type") === "module") {
if (node.getAttribute("type") === "module" && !(ignoreSSROnly && node.hasAttribute("data-ssr-only"))) {
scripts.push(node.rawText)
}
removeNodes.push(node)
Expand Down Expand Up @@ -67,6 +68,7 @@ module.exports = (options = {}) => ({
styleExports += transformedCSS
}
}
if (styleTag.hasAttribute("data-ssr-only")) styleTag.remove()
})
)
if (styleExports.length > 0) {
Expand All @@ -80,6 +82,9 @@ module.exports = (options = {}) => ({
)
}

if (ignoreSSROnly) {
root.querySelectorAll("[data-ssr-only]").forEach(node => removeNodes.push(node))
}
const scriptContent = scripts.join("")
removeNodes.forEach((node) => node.remove())

Expand All @@ -88,8 +93,9 @@ module.exports = (options = {}) => ({
let wrapper = globalCSS.length > 0 ? `import "data:text/css,${encodeURI(globalCSS)}"\n` : ""

if (
options.experimental?.skipBundlingFilter &&
args.path.match(options.experimental.skipBundlingFilter)
htmlFragment.trim().length === 0 ||
(options.experimental?.skipBundlingFilter &&
args.path.match(options.experimental.skipBundlingFilter))
) {
// we'll export nothing
wrapper += `
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "esbuild-plugin-html-modules",
"version": "0.6.0",
"version": "0.7.0",
"description": "An esbuild plugin to load HTML modules",
"main": "index.js",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion test/fixture/esbuild.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ esbuild.build({
extractGlobalStyles: true,
extractScopedStyles: true,
exportLocalStylesExtension: "css-local",
skipBundlingFilter: /\.tmpl\.html$/,
ignoreSSROnly: true,
transformLocalStyles: async (css, { filePath }) => {
const postCssConfig = await postcssrc()
const postCssProcessor = postcss([...postCssConfig.plugins])
Expand Down
2 changes: 1 addition & 1 deletion test/fixture/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import HelloWorld, { howdy, yo } from "./hello-world.html" assert { type: "html" }
import Nothing from "./ssr-only.tmpl.html" assert { type: "html" }
import Nothing from "./ssr-only.html" assert { type: "html" }

window.testing = {
HelloWorld,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<p>This should all get completely ignored!</p>
<template data-ssr-only>
<p>This should all get completely ignored!</p>
</template>

<script type="module">
<script type="module" data-ssr-only>
This should also get ignored!
</script>

<style>
<style data-ssr-only>
.nest {
& .me {
--only-this-will-work: var(--value);
Expand Down
2 changes: 1 addition & 1 deletion test/test_output.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ test('global CSS bundled', (t) => {

test('ssr only output', (t) => {
const testing = processBundle()
const sidecarCSS = readFileSync("test/fixture/ssr-only.tmpl.css-local").toString()
const sidecarCSS = readFileSync("test/fixture/ssr-only.css-local").toString()

assert.match(sidecarCSS, /\.nest \.me/)
assert.equal(testing.Nothing.children.length, 0)
Expand Down

0 comments on commit 196366b

Please sign in to comment.