Storybook: 在构建中保留静态目录的路径

创建于 2017-03-07  ·  57评论  ·  资料来源: storybookjs/storybook

在我的根目录中,我有一个名为public的静态文件夹,该文件夹用作来自节点服务器的/public/...路径。 这意味着图像和CSS文件将带有/public/前缀。

但是当我通过以下命令使用StoryBook时: start-storybook -p 6006 -s ./public
带有/public/的路径不再可用。
所以我将命令更改为start-storybook -p 6006 -s ./以提供根目录,一切正常。

但是,当我使用命令build-storybook -s ./构建故事书时,脚本会将根目录中的所有文件复制到storybook-static
如果我将命令更改为build-storybook -s ./public ,则前缀/public/的路径将不再可用。

有没有一种方法可以指定静态目录的路径?

feature request has workaround help wanted

最有用的评论

您是否认为实施了像start-storybook -p 6006 -s "./public:/static"这样的解决方案来在/static路径上提供来自./public静态文件? 这将导致非常灵活的使用,并符合我们许多人已经熟悉的Docker的路径映射约定。

所有57条评论

嗯,所以这个问题大约是build-storybook ,我需要研究一下它是如何工作的。

您可以尝试自定义中间件吗?我不确定它是否可以工作,但是可能会。
https://github.com/storybooks/react-storybook/pull/435#issuecomment -264813688
https://github.com/storybooks/react-storybook/blob/master/src/server/middleware.js#L35

:+1:这是一个问题-并非用于构建故事书,而仅用于开发人员。

这是我如何使其与中间件一起工作的:

const express = require('express');
const path = require('path');
const paths = require("../config/paths");

const expressMiddleWare = (router) => {
    console.log(path.join(__dirname), paths.appPublic);
    router.use('/public', express.static(paths.appPublic))
};

module.exports = expressMiddleWare;

我将尝试为此获得PR,但不确定是否有时间

感谢您分享您的解决方案! ❤️

嗨,大家好! 似乎最近在这个问题上没有发生太多事情。 如果仍有问题,意见或错误,请随时继续讨论。 不幸的是,我们没有时间解决每个问题。 我们随时欢迎捐款,因此,如果您想提供帮助,请向我们发送请求请求。 不活跃的问题将在60天后关闭。 谢谢!

嘿,又是我! 我将关闭此问题,以帮助我们的维护人员专注于当前的开发路线图。 如果仍然提到上述问题,请打开一张新票并提及这张旧票。 干杯,感谢您使用Storybook!

嗨! @ndelangen @hansthinhle @patrickgordon

我面临着完全相同的问题。 这个解决了吗?

谢谢!

@aviramga-我发表了一些解决方案,为我们解决了这个问题。 我从来没有做过公关来解决它。

现在我的记忆已经慢了,实际上仍然可以这样做:)

嗨@patrickgordon。 不幸的是,我的问题只与build-storybook有关:/

我将其与Percy工具结合使用,以在我的应用中查找ui问题。

您设法找到构建的解决方案了吗?

看起来您可以使用符号链接来解决此问题:

添加一个具有任意名称的目录(例如static-link ,并放置一个名为public (不带任何扩展名)的文件,其内容如下:

../public

然后,您应该能够使用-s static-link实现您所需要的

@Hypnosphi感谢您的提示! 这似乎不起作用。
您能解释一下它是如何工作的吗?

我所有的静态文件都位于名为“ static”的目录下(不是公共目录)。
我尝试了行不通的方法:

  1. 用文件名为“ static”和../static的文件创建一个任意目录-运行build-storybook时出现case错误
  2. 与上述相同,但文件名为“ public”-仍然看不到任何图像

有什么建议吗?

谢谢

您正在使用哪个操作系统?
https://zh.wikipedia.org/wiki/Symbolic_link#概述

这是什么错误?

Mac High Sierra

@Hypnosphi,但是只是为了确保我理解正确,要调整您的示例以适应我的用例,我需要创建一个新目录,例如static-link,在其中放置一个名为static的文件,并在其中写入../static

正确?

OK,看来我创建符号链接的指令是错误的。 正确的方法是这样的:

mkdir static-link
ln -s static static-link/static

它将在静态链接目录中创建一个可在git中共享的“文件”(尽管在Windows上无法使用)

@Hypnosphi我会

不,应该持久

@Hypnosphi不,仍然无法正常工作。 在构建时,我得到一条日志,上面写着:
cp:无此类文件或目录:static-link / static

我按照了您的上述指示。 所以我有一个名为static-link的空目录,带有从static到static-link / static的符号链接

我究竟做错了什么?

非常感谢您抽出宝贵时间来帮助您:)

然后您使用-s static-link选项,对不对?

@Hypnosphi您的意思是build-storybook -c .storybook -s静态链接

我做

抱歉,我输错了:

ln -s ../static static-link/static

@Hypnosphi
为什么../static?

我是否纠正了静态链接目录为空的问题?
也许您想尝试进行私人对话并在此处发布我们的最终结果? 我觉得我们非常亲密,只是沟通不畅:)

这是从链接位置到链接目标的相对路径

@Hypnosphi我能够使用绝对路径来使它工作...但是我确实需要使其与相对路径一起工作,因为我想在信号量中实现相同的逻辑

@Hypnosphi找到了一种解决方法。 非常感谢您的所有帮助,您可以挽救生命!!

解决这个问题有什么建议吗?

是的,只需运行上面建议的解决方案。 使用符号链接
ln -s /<absolute-path-your-static-directory> storybook-static-symlink/static

@aviramga这个方法对您仍然有效吗? 我没有使用符号链接的运气。

我的文件夹结构

|- docs
  |- folders-with-images
|- sandbox (holds my storybook files)
|- src
  |- README.md with image paths `/docs/folder/image.png`

使用中间件文件提供故事书start-storybook -c sandbox -s sandbox,docs -p 6006时,我可以使用此功能:

const express = require('express');
const path = require('path');

module.exports = router => {
  router.use('/docs', express.static(path.join(__dirname, '..', 'docs')));
}

但是使用ln -s /docs sandbox/docs添加符号链接并运行build-storybook -c sandbox -s sandbox,docs -o storybook仍然不起作用。

docs中的文件夹被复制,但是由于我需要的文件路径是/docs/folder/image.png 404,所以图像404。

还设法使用静态链接来解决此问题:

package.json:

"scripts": {
  "storybook": "(mkdir ./src/static-link || true) && (ln -s ../static ./src/static-link/static || true) && start-storybook -p 6006 -s ./src/static-link"
}

出于兼容性原因,我建议不要通过package.json脚本创建符号链接,以防并非每个开发人员都使用相同的操作系统。

作为替代方案,我建议在.storybook / webpack.config.js文件中使用copy-webpack-plugin ,如下所示:

const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = config => {
  function resolve(dir) {
    return path.join(__dirname, '..', dir);
  }

  // Other configuration properties

  config.plugins.push(
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, 'static-foo'),
        to: '.'
      },
      {
        from: path.resolve(__dirname, '../static-bar'),
        to: './bar'
      }
    ])
  );

  return config;
}

例如,这会将目录.storybook/static-foo的内容装载到http://localhost:6006/ ,将static-bar的内容装载到http://localhost:6006/bar/

还要注意,使用push添加到plugins数组中是为了避免覆盖其他插件,这可能会破坏Storybook Webpack的配置。

供将来参考,符号链接非常好使用。 如果要/需要将它们与相对路径一起使用,则只需使用-r开关,如下所示:ln -rs dir1 dir2

我个人认为,如果故事书适合复制整个静态目录,则应在文档中明确说明。 否则,应该将这种行为切换为创建适当符号链接的行为。 我发现了有关复制的内容,因为它由于过多的磁盘空间使用而使服务器崩溃!

因此,基本上没有官方内置的解决方案,并且所有“解决方案”都只是随机的cr脚骇客:)

出于兼容性原因,我建议不要通过package.json脚本创建符号链接,以防并非每个开发人员都使用相同的操作系统。

作为替代方案,我建议在.storybook / webpack.config.js文件中使用copy-webpack-plugin ,如下所示:

const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = config => {
  function resolve(dir) {
    return path.join(__dirname, '..', dir);
  }

  // Other configuration properties

  config.plugins.push(
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, 'static-foo'),
        to: '.'
      },
      {
        from: path.resolve(__dirname, '../static-bar'),
        to: './bar'
      }
    ])
  );

  return config;
}

例如,这会将目录.storybook/static-foo的内容装载到http://localhost:6006/ ,将static-bar的内容装载到http://localhost:6006/bar/

还要注意,使用push添加到plugins数组中是为了避免覆盖其他插件,这可能会破坏Storybook Webpack的配置。

这不起作用;)

这是一个有效的配置:

.storybook / webpack.config.js
(假设静态文件夹位于项目的根文件夹中)

const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = async ({ config }) => {

  function resolve(dir) {
    return path.join(__dirname, '..', dir);
  }

  // Other configuration properties

  config.plugins.push(
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../../static'),
        to: './static'
      }
    ])
  );

  return config;
}

由于某些原因, @ mtrabelsi对我不起作用...

另外,我猜您有一种类型,因为您的.storybook文件夹位于root ,而不是两倍的深。 因此,您需要切换到:
from - from: path.resolve(__dirname, '../../static')
to - from: path.resolve(__dirname, '../static')

“ copy-webpack-plugin”:“ ^ 5.0.4”
所有路径都是正确的。 仔细检查。

更新资料
我通过在.storybook/文件夹中创建middleware.js文件找到了@BradMcGonigle答案上限:

const express = require('express');
const path = require('path');

module.exports = router => {
  router.use('/docs', express.static(path.join(__dirname, '..', 'docs')));
}

@BiosBoy为了避免在这里造成任何混乱,请快速了解我的项目结构(仅您需要了解的内容):

My_sweet_projet_ROOT_DIR / components / .storybook / webpack.config.js
My_sweet_projet_ROOT_DIR /静态

我还使用next.js作为主要应用程序,在该应用程序中使用components文件夹中的react组件。

这是我的设置(您可以在您的身边进行复制-我相信您:D)

My_sweet_projet_ROOT_DIR / package.json

{
  "name": "sweet_like_butter",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@zeit/next-css": "^1.0.1",
    "next": "^8.1.0",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "styled-components": "^4.2.0"
  },
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  },
  "devDependencies": {
    "babel-plugin-styled-components": "^1.10.0"
  }
}

My_sweet_projet_ROOT_DIR / next.config.js

const withCSS = require('@zeit/next-css')
module.exports = withCSS()

通过使用基本标记,我可以解决类似的问题:

  1. 在.storybook目录中创建一个manager-head.html文件。 https://storybook.js.org/docs/configurations/add-custom-head-tags/
<head>
  <script>
    const hostname = window.location.hostname
    if (hostname !== "" && hostname !== "localhost") {
      const script = document.createElement('base')
      script.href = '/storybook-static/'
      document.getElementsByTagName('head')[0].appendChild(script)
    }
  </script>
</head>

(使用script.href =到所需的路径)

现在使用指定的前缀检索index.html中的文件

这种行为不应该内置到Storybook中吗?如果您标记-s ./static那么您的路径在Storybook中的工作方式将与生产中的相同? 似乎毫无意义,当我告诉Storybook我的静态目录是./static时,我的相对路径(例如./static/image.png必须改为./image.png或使用一些愚蠢的符号链接🤔

@eckmLJE如果使用我上面发布的代码片段,则无需任何其他Webpack配置或符号链接即可使用。 不过,我们可以考虑在构建过程中自动将其输出。

我在2020年仍然面临这个问题...
我的情况很简单:我的package.json具有以下脚本: "storybook": "start-storybook -s ./dist/img -p 8888"

因此,当我运行npm run storybook ,它将显示info => Loading static files from: /home/vagrant/projects/MySuperProject/web/themes/ofb/ofb_ui/dist/img .

但是,当我尝试使用此URL从浏览器访问dist/img目录中的文件时,它不起作用: http://localhost:8888/myImage.png ...

伙计们,这是错误还是我做错了?

@ndelangen您认为我们可以适应6.0重大更改吗? 我认为这将是一个很好的解决方案,但还是一个突破性的解决方案。

似乎CopyWepbackPlugin的api已更改,您需要向@mtrabelsi解决方案中添加一个pattern密钥,如下所示:

const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = async ({ config }) => {
  config.plugins.push(
    new CopyWebpackPlugin({
      pattern: [
        {
          from: path.resolve(__dirname, '../../static'),
          to: './static'
        }
      ]
    })
  );

  return config;
}

我将添加与此问题相关的两美分。 尽管我认为这是密切相关的,但是我的解决方案与@mtrabelsi的不同之处在于,我发现仅凭build-storybook命令的结果将资产复制到./static目录是不够的。 具体来说,如果我将静态应用程序部署到从http://example.com/docs提供静态应用程序的Tomcat服务器上,其中docs是位于服务器上Tomcat webapps /中的目录。

由于存在子路径,因此/ static目录中/ css目录之外的文件均未加载。 我正在使用图像和字体的相对路径(这些是无法在已部署版本上加载的静态资产)。 因此,如https://example.com/img/path/to/my/image类的请求失败了,应该添加/ static,即。 https://example.com/static/img/path/to/my/image正如我所说,我的解决方案非常接近@mtrabelsi,但是如果将fonts和img放到输出的根目录中,我只是将两个目录删除:

const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = async ({ config }) => {

  function resolve(dir) {
    return path.join(__dirname, '..', dir);
  }

  // Other configuration properties

  config.plugins.push(
    new CopyWebpackPlugin({
      pattern: [
        {
          from: path.resolve(__dirname, './_assets'), // My static font and images are located in the .storybook dir
          to: './' // Drop both the fonts/ and img/ directory into the root of the build output.
        }
      ]
    })
  );

  return config;
}

此后,将适当加载图像和字体。

@tmeasday建议:为什么不能将此选项main.js选项,使其同时出现在start-storybookbuild-storybook

@ vcastro45我已经为start-storybook和build-storybook进行了测试,并且似乎可以正常工作(在next分支上进行了测试)。

您能为我创建一个复制仓库吗?

@shilman可以,但是我们必须从
https://github.com/storybookjs/storybook/blob/9ea455a1746c489b7364448212663f2445af8a8b/lib/core/src/server/manager/manager-config.js#L101 -L102

到这里之前:
https://github.com/storybookjs/storybook/blob/19c2420db80fcb3b89b34cdbbe03bf9010b0b3b2/lib/core/src/server/build-static.js#L190 -L191

然后将其传递给build / dev链中所有较低的功能。
这是一个重构,不是我一天之内可以做的事情。

这也是我们真正想要将其全部迁移到TS的又一刻。 因为我们无论如何都要接触lib / core文件的50%。

@ndelangen OOF,让我们现在就不这样做了🙈

是的,我们有一天会做

@ndelangen我已经在# 11370中与main.js并添加一个选项以支持6.x中的此用例,这是一项功能,而不是重大更改。

您是否认为实施了像start-storybook -p 6006 -s "./public:/static"这样的解决方案来在/static路径上提供来自./public静态文件? 这将导致非常灵活的使用,并符合我们许多人已经熟悉的Docker的路径映射约定。

嗨,大家好! 似乎最近在这个问题上没有发生太多事情。 如果仍有问题,意见或错误,请随时继续讨论。 不幸的是,我们没有时间解决每个问题。 我们随时欢迎捐款,因此,如果您想提供帮助,请向我们发送请求请求。 不活跃的问题将在30天后关闭。 谢谢!

@nfroidure无疑是一个有趣的想法!

@ndelangen如果您愿意,我可以尝试使用PR。 有机会合并吗?

好吧,我在这里有一些东西: https :

某些测试失败,但是我看不到这些失败与更改之间的任何联系。

LMKWYT;)

感谢您的PR @nfroidure

我这周来看一下!

ZOMG! 我刚刚发布了https://github.com/storybookjs/storybook/releases/tag/v6.1.0-alpha.6,其中包含引用此问题的PR#12222。 立即升级以试用!

您可以在@next NPM标签上找到此预发行版本。

解决此问题。 如果您认为还有更多事情要做,请重新打开。

是否有使用此新功能的示例?

此页面是否有帮助?
0 / 5 - 0 等级