Giter VIP home page Giter VIP logo

Comments (3)

gidztech avatar gidztech commented on May 27, 2024 2

I'm running into this issue in CI too with Storybook 7. I've not got any solution/workaround at the moment.

from loki.

gidztech avatar gidztech commented on May 27, 2024

I have a PR open now to resolve the issue. The static file server needed to be implemented for the app target just like the Docker one. #472

from loki.

gidztech avatar gidztech commented on May 27, 2024

I came up with a hacky workaround while I wait for a fix to be approved/released. I originally patched Loki with my branch version, but building from .tgz files was very slow.

The preview for Storybook references the static assets (fonts, stylesheet and scripts) with ./ prefix, which causes issues with Loki's current use of file:// protocol. In addition, it loads scripts as ES modules, which also is problematic under the current setup. This is configured via a preview template, but Storybook allows you to customize it using the previewMainTemplate property in .storybook/main.ts.

I copied template.ejs into my .storybook folder and applied the following changes:

  1. Removed the ./ prefix to the static assets
  2. Removed crossorigin from the fonts
  3. Replaced the ES imports with injected script tags
  4. Referenced a different preview runtime script (see more later)
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title><%= htmlWebpackPlugin.options.title || 'Storybook'%></title>

    <% if (htmlWebpackPlugin.files.favicon) { %>
    <link rel="shortcut icon" href="<%= htmlWebpackPlugin.files.favicon%>" />
    <% } %>

    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <link rel="prefetch" href="sb-common-assets/nunito-sans-regular.woff2" as="font" type="font/woff2" />
    <link rel="prefetch" href="sb-common-assets/nunito-sans-italic.woff2" as="font" type="font/woff2" />
    <link rel="prefetch" href="sb-common-assets/nunito-sans-bold.woff2" as="font" type="font/woff2" />
    <link rel="prefetch" href="sb-common-assets/nunito-sans-bold-italic.woff2" as="font" type="font/woff2" />
    <link rel="stylesheet" href="sb-common-assets/fonts.css" />

    <% if (typeof headHtmlSnippet !== 'undefined') { %> <%= headHtmlSnippet %> <% } %> <%
    htmlWebpackPlugin.files.css.forEach(file => { %>
    <link href="<%= file %>" rel="stylesheet" />
    <% }); %>

    <style>
      #storybook-root[hidden],
      #storybook-docs[hidden] {
        display: none !important;
      }
    </style>
  </head>
  <body>
    <% if (typeof bodyHtmlSnippet !== 'undefined') { %> <%= bodyHtmlSnippet %> <% } %>

    <div id="storybook-root"></div>
    <div id="storybook-docs"></div>

    <% if (typeof globals !== 'undefined' && Object.keys(globals).length) { %>
    <script>
      <% for (var varName in globals) { %>
          <% if (globals[varName] != undefined) { %>
            window['<%=varName%>'] = <%= JSON.stringify(globals[varName]) %>;
          <% } %>
      <% } %>
    </script>
    <% } %>

    <script>
      function insertScript(src) {
        const script = document.createElement('script');
        script.src = src;
        document.body.append(script);
      }

      insertScript('sb-preview/runtime_browser.js');

      <% htmlWebpackPlugin.files.js.forEach(file => { %>
        insertScript('<%= file %>');
      <% }); %>
    </script>
  </body>
</html>

Since the original sb-preview/runtime.js file is a built ES module, this can't be loaded unless you use type="module" or import syntax, but that would result in a request to the file that we can't do. Instead, I wrote a function that compiles the ES module into a browser script using Webpack. That way we can include it in the main bundle. Obviously this removes all the performance benefits of ES modules.

async function createStorybookRuntimeForBrowser(): Promise<boolean> {
  return new Promise((resolve, reject) => {
    webpack(
      {
        entry: path.resolve('node_modules/@storybook/preview/dist/runtime.js'),
        output: {
          filename: 'runtime_browser.js',
          path: path.resolve('storybook-static/sb-preview'),
        },
      },
      (err, stats) => {
        if (err || stats?.hasErrors()) {
          reject();
        }
        resolve(true);
      }
    );
  });
}

You can either run this node function before storybook build as part of your npm script, or you can call it within webpackFinal async handler before returning config. I chose the latter. You can tweak the config further by only running the function and setting the custom template if you are doing a production build of Storybook. That way, your dev version can remain as normal.

This is a complete hack and I hope #472 will remove the need for this nonsense, but I thought I'd share my workaround in case anyone finds it helpful.

from loki.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.