Skip to content

Latest commit

 

History

History
171 lines (112 loc) · 8.62 KB

BUNDLERS.md

File metadata and controls

171 lines (112 loc) · 8.62 KB

Deploying WebAuthn-Local-Client WITH A Bundler

This project has non-ESM dependencies, which unfortunately cannot be bundled in with your other app code. Modern bundlers unfortunately don't out-of-the-box support configurations that can handle such a situation.

As such, this project provides plugins for Astro, Vite, and Webpack, to take care of the various steps needed to get these non-ESM dependencies into an otherwise bundled web app built by those tools.

Bundler Plugins

The plugins for Astro, Vite, and Webpack are included in the bundler-plugins/ directory. They should handle all necessary steps to load the dependencies.

Note: You should not need to manually copy any files out of the @lo-fi/webauthn-local-client/dist/bundlers/ directory, as the plugins access the webauthn-local-client dependency (in node_modules) directly to pull the files needed. But for reference, the files these plugins access are:

  • @lo-fi/webauthn-local-client/dist/bundlers/walc.mjs

    ESM library module that's suitable for bundling and importing into your web app.

    Note: this is not the same as @lo-fi/webauthn-local-client/dist/auto/walc.js, which is only intended for web application projects WITHOUT a bundler

  • @lo-fi/webauthn-local-client/dist/bundlers/walc-external-bundle.js

    Non-ESM (plain global .js) bundle of dependencies that must be loaded separately from (and prior to) your app's bundle. This single file includes the concatenated contents of these individual dependencies (from @lo-fi/webauthn-local-client/dist/auto/external/):

    • libsodium.js
    • libsodium-wrappers.js
    • cbor.js
    • asn1.all.min.js

Note: The ASN1 dependency is licensed under MPL 2.0, which is generally compatible with this library's MIT license. However, MPL 2.0 specifically requires preservation of the copyright/license header (block comment at top of asn1.all.min.js). To comply with this licensing requirement, ensure your tooling does not remove this comment from the bundle file.

Astro Plugin (aka Integration)

If using Astro 4+, it's strongly suggested to import this library's Astro-plugin to manage the loading of its non-ESM dependencies. Add something like the following to your astro.config.mjs file:

import { defineConfig } from "astro/config";

import WALC from "@lo-fi/webauthn-local-client/bundlers/astro";

export default defineConfig({
    // ..

    integrations: [ WALC(), ],

    vite: {
        plugins: [
            // pulls in some necessary bits of WALC's vite plugin
            WALC.vite(),
        ],

        optimizeDeps: {
            esbuildOptions: {
                // WALC uses "top-level await", which is ES2022+
                target: "es2022",
            },
        },

        build: {
            // WALC uses "top-level await", which is ES2022+
            target: "es2022"
        },
    },

    // ..
});

This plugin works for the astro dev (dev-server), as well as astro build / astro preview modes. In all cases, it copies the @lo-fi/webauthn-local-client/dist/bundlers/walc-external-bundle.js file into the public/ directory of your project root, as well as the dist/ directory when running a build. It also injects an inline <script> element into the <head> of all generated pages, which dynamically loads the /walc-external-bundle.js script file (which has all the external dependencies needed).

Note: At present, this plugin is not configurable in any way (i.e., calling WALC() above with no arguments). If something about its behavior is not compatible with your Astro project setup -- which can vary widely and be quite complex to predict or support by a basic plugin -- it's recommended you simply copy over the @lo-fi/webauthn-local-client/bundler-plugins/astro.mjs plugin and make necessary changes.

Vite Plugin

If using Vite 5+ directly, it's strongly suggested to import this library's Vite-plugin to manage the loading of its non-ESM dependencies. Add something like the following to your vite.config.js file:

import { defineConfig } from "vite";
import WALC from "@lo-fi/webauthn-local-client/bundlers/vite";

export default defineConfig({
    // ..

    plugins: [ WALC(), ],

    optimizeDeps: {
        esbuildOptions: {
            // WALC uses "top-level await", which is ES2022+
            target: "es2022",
        },
    },

    build: {
        // WALC uses "top-level await", which is ES2022+
        target: "es2022"
    },

    // ..
});

This plugin works for the vite dev (dev-server), vite preview (also dev-server), and vite build modes. In all cases, it copies the dist/bundlers/walc-external-bundle.js file into the public/ directory of your project root. It also injects a <script src="/walc-external-bundle.js"></script> tag into the markup of the index.html file that Vite produces for your app.

Note: At present, this plugin is not configurable in any way (i.e., calling WALC() above with no arguments). If something about its behavior is not compatible with your Vite project setup -- which can vary widely and be quite complex to predict or support by a basic plugin -- it's recommended you simply copy over the @lo-fi/webauthn-local-client/bundler-plugins/vite.mjs plugin and make necessary changes.

Top-level await

This library uses "top-level await", a feature added to JS in ES2022. The current default target for Vite seems to be browsers older than this, so the above config explicitly sets the targets to "es2022".

You may experience issues where your tooling/configuration either ignores this setting, or otherwise breaks with it set. This may variously result in seeing an error about the top-level awaits in this library being incompatible with the built-target, or an error about await needing to only be in async functions or the top-level of a module (which it is!).

You may need to configure Vite to skip trying to optimize the walc.mjs file during bundling, something like:

export default defineConfig({

    // ..

    optimizeDeps: {
        exclude: [ "@lo-fi/webauthn-local-client" ]
    }

    // ..
});

SSR Breakage

An unfortunate gotcha of some tools that wrap Vite (e.g., Nuxt, etc) and do SSR (server-side rendering) is that they break a key assumption/behavior of this module's Vite plugin: the HTML injection of <script src="/walc-external-bundle.js"></script>.

As such, you'll likely need to manually add that <script> tag to your HTML pages/templates. The Vite plugin still copies that file into the public/ folder for you, so it should load once the tag is added to your HTML.

Webpack Plugin

If using Webpack 5+, make sure you're already using the HTML Webpack Plugin to manage building your index.html (and/or other HTML pages).

Then import this library's Webpack-plugin to manage the loading of its non-ESM dependencies. Add something like the following to your webpack.config.js:

// 'HtmlWebpackPlugin' is a required dependency of the
// webauthn-local-client Webpack plugin
import HtmlWebpackPlugin from "html-webpack-plugin";
import WALC from "@lo-fi/webauthn-local-client/bundlers/webpack";

export default {
    // ..

    plugins: [
        // required WALC dependency
        new HtmlWebpackPlugin({
            // ..
        }),

        WALC()
    ],

    // ..
};

This plugin copies the @lo-fi/webauthn-local-client/dist/bundlers/walc-external-bundle.js file into the build root (default dist/), along with the other bundled files. It also injects a <script src="walc-external-bundle.js"></script> tag into the markup of the index.html file (and any other HTML files) that Webpack produces for your app.

Note: At present, this plugin is not configurable in any way (i.e., calling WALC() above with no arguments). If something about its behavior is not compatible with your Webpack project setup -- which can vary widely and be quite complex to predict or support by a basic plugin -- it's recommended you simply copy over the @lo-fi/webauthn-local-client/bundler-plugins/webpack.mjs plugin and make necessary changes.

Import/Usage

To import and use webauthn-local-client in a bundled browser app:

import { register, auth } from "@lo-fi/webauthn-local-client";

When imported like this, Astro, Vite, and Webpack should (via these plugins) properly find and bundle the @lo-fi/webauthn-local-client/dist/bundlers/walc.mjs ESM library module with the rest of your app code, hopefully without any further steps necessary.