npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

esbuild-plugin-html-modules

v0.8.0

Published

An esbuild plugin to load HTML modules

Downloads

270

Readme

esbuild-plugin-html-modules

npm CI Test

An esbuild plugin to load HTML Modules. This is a proposed spec defined here by @dandclark which would allow HTML files to be exported and importable as ES modules where the HTML itself is transformed into an exported HTML template and a <script type="module"> tag is run as the JavaScript of the module. The template is available from inside the module script code via import.meta.document, and externally as the default ES export of the file.

An HTML module could look like this:

<script type="module">
  export const hello = () => {
    return import.meta.document.querySelector("h1")
  }
</script>

<h1>Hello World</h1>

<p>Everything here is included in the default document export.</p>

And you could import it like this:

// in some JS file:

import HelloWorld, { hello } from "src/hello-world.html" with { type: "html" }

console.log(hello())

console.log(HelloWorld.querySelector("p"))

Install

npm install esbuild-plugin-html-modules -D
yarn add esbuild-plugin-html-modules -D

Usage

Add the plugin to your esbuild config file. For example:

const esbuild = require('esbuild')
const htmlModulesPlugin = require('esbuild-plugin-html-modules')

esbuild.build({
  bundle: true,
  entryPoints: ['src/index.js'],
  outfile: 'dist/index.js',
  plugins: [
    htmlModulesPlugin()
  ]
}).catch(() => process.exit(1))

You can also pass a specific filter in if you wish to support only specific extensions, like .module.html or .mod.html, in your project:

  plugins: [
    htmlModulesPlugin({ filter: /\.mod\.html$/ })
  ]

Now you'll be able to import HTML modules. Take a peek at the files in the test/fixture folder for an example of how this could work.

Other configuration options are contained within the experimental section because they go beyond the proposed spec to offer some helpful features. Here's an example:

const postcssrc = require("postcss-load-config")
const postcss = require("postcss")


// later in the esbuild config:

htmlModulesPlugin({
  experimental: {
    extractGlobalStyles: true,
    exportLocalStylesExtension: "css-local",
    ignoreSSROnly: true,
    transformLocalStyles: async (css, { filePath }) => {
      const postCssConfig = await postcssrc()
      const postCssProcessor = postcss([...postCssConfig.plugins])

      const results = await postCssProcessor.process(css, { ...postCssConfig.options, from: filePath })
      return results.css
    }
  }
})

Transforming Styles

[!WARNING] The extractScopedStyles: true experimental option was removed in v0.8. We recommend you use the newer @scope standard in a global stylesheet if you want to author "scoped" light DOM styles.

If you define extractGlobalStyles: true, then any style tag featuring a scope="global" attribute or a global boolean attribute will have those styles extracted out of there and included in esbuild's CSS bundle output.

If you define a transformLocalStyles function, then any local style tag contained within your HTML (not explicitly scoped) will have its contents transformed by the function. Above you can see this done using PostCSS, but you could use another processor such as Sass if you prefer. This is useful for style tags which get included in shadow DOM templates (and you wouldn't want to include those styles in the CSS bundle).

Bundling Lifecycle

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.

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.

Testing

Run:

npm run test

Contributing

  1. Fork it (https://github.com/whitefusionhq/esbuild-plugin-html-modules/fork)
  2. Clone the fork using git clone to your local development machine.
  3. Create your feature branch (git checkout -b my-new-feature)
  4. Commit your changes (git commit -am 'Add some feature')
  5. Push to the branch (git push origin my-new-feature)
  6. Create a new Pull Request