Storybook: Manter o caminho para o diretório estático na construção

Criado em 7 mar. 2017  ·  57Comentários  ·  Fonte: storybookjs/storybook

No meu diretório raiz, tenho uma pasta estática com os nomes public que é servida como /public/... caminho do meu servidor de nó. Isso significa que as imagens e os arquivos CSS são veiculados com o prefixo /public/ .

Mas quando eu uso o StoryBook com o comando: start-storybook -p 6006 -s ./public
O caminho com /public/ não está mais disponível.
Então mudei o comando para start-storybook -p 6006 -s ./ para servir o diretório raiz, e está tudo ok.

Mas quando eu construo meu livro de histórias com o comando build-storybook -s ./ o script irá copiar todos os arquivos do diretório raiz para storybook-static .
E se eu mudar o comando para build-storybook -s ./public , o caminho com o prefixo /public/ não estará mais disponível.

Existe uma maneira de especificar o caminho para o diretório estático?

feature request has workaround help wanted

Comentários muito úteis

Você acha que uma solução como start-storybook -p 6006 -s "./public:/static" para servir arquivos estáticos de ./public no caminho /static ser implementada? Isso levaria a usos extremamente flexíveis e se encaixaria nas convenções do Docker de mapeamento de caminho com as quais muitos de nós já estamos familiarizados.

Todos 57 comentários

Hmm, então este problema é cerca de build-storybook isso é algo que eu preciso verificar como funciona.

Você poderia experimentar o middleware personalizado? Não tenho certeza de que funcionará, mas pode.
https://github.com/storybooks/react-storybook/pull/435#issuecomment -264813688
https://github.com/storybooks/react-storybook/blob/master/src/server/middleware.js#L35

: +1: Este é um problema - não para a construção de livros de histórias, mas apenas para uso em desenvolvimento.

Veja como fiz para funcionar com middleware:

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;

Vou tentar conseguir um PR para isso, mas não tenho certeza se tenho tempo atm

Obrigado por compartilhar sua solução! ❤️

Olá a todos! Parece que não tem havido muito nesta edição ultimamente. Se ainda houver perguntas, comentários ou bugs, fique à vontade para continuar a discussão. Infelizmente, não temos tempo para abordar todos os problemas. Estamos sempre abertos a contribuições, portanto, envie-nos uma solicitação de pull se quiser ajudar. Os problemas inativos serão fechados após 60 dias. Obrigado!

Olá, sou eu de novo! Vou encerrar este problema para ajudar nossos mantenedores a se concentrarem no atual roteiro de desenvolvimento. Se o problema mencionado ainda é uma preocupação, abra um novo tíquete e mencione o antigo. Parabéns e obrigado por usar o Storybook!

Oi! @ndelangen @hansthinhle @patrickgordon

Estou enfrentando exatamente o mesmo problema. Isso já foi resolvido?

Obrigado!

oi @aviramga - minha solução que postei alguns resolveu pra gente. Nunca cheguei a fazer um PR para resolver isso.

Ainda posso fazer isso agora que minha memória foi carregada :)

Olá, @patrickgordon. Infelizmente, meu problema é apenas com o livro de histórias de construção: /

Estou usando com uma ferramenta chamada Percy para encontrar problemas de interface do usuário em meu aplicativo.

Você conseguiu encontrar uma solução para o build?

Parece que você pode contornar isso usando links simbólicos:

Adicione um diretório com um nome arbitrário (por exemplo, static-link , e coloque lá um arquivo chamado public (sem qualquer extensão) com o seguinte conteúdo:

../public

Então você deve conseguir o que precisa com -s static-link

@Hypnosphi obrigado pela dica! isso não parece funcionar embora.
Você pode explicar como funciona?

Todos os meus arquivos estáticos estão em um diretório chamado "estático" (não público).
Tentei maneiras que não funcionaram:

  1. Crie um diretório arbitrário com um arquivo chamado "estático" e ../static nele - ocorreu um erro de compilação quando executei o build-storybook
  2. O mesmo que o anterior, mas com um arquivo chamado "público" - ainda não vejo nenhuma imagem

Algum conselho?

obrigado

Qual sistema operacional você está usando?
https://en.wikipedia.org/wiki/Symbolic_link#Overview

Qual foi o erro?

Mac High Sierra

@Hypnosphi, mas apenas para ter certeza de que entendi corretamente, para ajustar seu exemplo ao meu caso de uso, preciso criar um novo diretório, por exemplo, link-estático nele coloque um arquivo chamado estático e nele escreva ../static

Corrigir?

OK, parece que minha instrução para criar um link simbólico estava errada. A maneira correta é esta:

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

Ele criará um "arquivo" no diretório de link estático que pode ser compartilhado no git (embora não funcione no Windows)

@Hypnosphi vou tentar. mas isso significa que tenho que executá-lo toda vez que executei um livro de histórias de construção?

Não, deve ser persistente

@Hypnosphi nope, ainda não está funcionando. Durante a construção, recebo um registro que diz:
cp: nenhum arquivo ou diretório: static-link / static

Segui suas instruções acima. Então, eu tenho um diretório vazio chamado link-estático com um link simbólico de link estático para link estático / estático

O que estou fazendo errado?

Agradeço muito por você ter ajudado :)

E você usa a opção -s static-link , certo?

@Hypnosphi você quer dizer build-storybook -c .storybook -s static-link ?

sim

eu faço

Desculpe, eu digitei incorretamente:

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

@Hypnosphi
porque ../static?

Estou certo de que o diretório de link estático está vazio?
Talvez você queira tentar uma conversa privada e publicar aqui nossos resultados finais? Eu sinto que estamos muito próximos e é apenas falta de comunicação :)

É o caminho relativo do local do link para o destino do link

@Hypnosphi Consegui fazê-lo funcionar usando caminho absoluto ... mas preciso fazê-lo funcionar com caminho relativo, pois desejarei implementar a mesma lógica no semáforo

@Hypnosphi encontrou uma solução alternativa. Muito obrigado por toda a sua ajuda, você é um salva-vidas !!

alguma dica para resolver isso?

Sim, basta executar a solução sugerida acima. Trabalhe com um link simbólico
ln -s /<absolute-path-your-static-directory> storybook-static-symlink/static

@aviramga esse método ainda está funcionando para você? Não estou tendo sorte ao usar um link simbólico.

Minha estrutura de pastas

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

Posso fazer isso funcionar ao servir o livro de histórias start-storybook -c sandbox -s sandbox,docs -p 6006 usando um arquivo de middleware:

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

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

Mas adicionar um link simbólico usando ln -s /docs sandbox/docs e executando build-storybook -c sandbox -s sandbox,docs -o storybook ainda não funciona.

As pastas em docs são copiadas, mas como o caminho do arquivo que preciso é /docs/folder/image.png as imagens 404.

Também conseguiu usar um link estático para resolver isso:

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"
}

Aconselho a não criar o link simbólico por meio do script package.json por motivos de compatibilidade, caso nem todos os desenvolvedores usem o mesmo sistema operacional.

Como alternativa, sugiro usar o plugin copy-webpack no arquivo .storybook / webpack.config.js , assim:

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;
}

Isso, por exemplo, montaria o conteúdo do diretório .storybook/static-foo em http://localhost:6006/ e o conteúdo de static-bar em http://localhost:6006/bar/ .

Observe também o uso de push para adicionar ao array plugins para evitar sobrescrever outros plug-ins, o que poderia interromper a configuração do Storybook Webpack.

Para referência futura, os links simbólicos são perfeitamente adequados para uso. Se você quiser / precisar usá-los com caminhos relativos, basta usar a opção -r da seguinte forma: ln -rs dir1 dir2

Eu pessoalmente acho que se o livro de histórias achar adequado copiar um diretório estático inteiro, isso deve ser claramente declarado na documentação. Caso contrário, este comportamento deve ser trocado por um que crie os links simbólicos apropriados. Eu descobri sobre a cópia porque estava travando meu servidor devido ao uso excessivo de espaço em disco!

Então, basicamente, não há uma solução oficial integrada e todas as "soluções" são apenas hacks aleatórios de baixa qualidade :)

Aconselho a não criar o link simbólico por meio do script package.json por motivos de compatibilidade, caso nem todos os desenvolvedores usem o mesmo sistema operacional.

Como alternativa, sugiro usar o plugin copy-webpack no arquivo .storybook / webpack.config.js , assim:

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;
}

Isso, por exemplo, montaria o conteúdo do diretório .storybook/static-foo em http://localhost:6006/ e o conteúdo de static-bar em http://localhost:6006/bar/ .

Observe também o uso de push para adicionar ao array plugins para evitar sobrescrever outros plug-ins, o que poderia interromper a configuração do Storybook Webpack.

isso não funciona;)

esta é uma configuração funcional:

.storybook / webpack.config.js
(assumindo que a pasta estática está na pasta raiz do projeto)

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 não funciona para mim por alguns motivos ...

Além disso, acho que você tem um tipo, já que sua pasta .storybook está em um nível de profundidade a partir de root , não em profundidade dupla. Então, você precisa mudar para:
from - from: path.resolve(__dirname, '../../static')
to - from: path.resolve(__dirname, '../static')

"copy-webpack-plugin": "^ 5.0.4"
Todos os caminhos estão certos. Verificado duas vezes.

Atualizar
Eu descobri com @BradMcGonigle a resposta superior criando o arquivo middleware.js dentro da minha pasta .storybook/ :

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

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

@BiosBoy para evitar qualquer confusão aqui rapidamente uma ideia sobre a estrutura do meu projeto (apenas o que você precisa saber):

My_sweet_projet_ROOT_DIR / components / .storybook / webpack.config.js
My_sweet_projet_ROOT_DIR / estático

Eu também uso next.js como o aplicativo principal onde ele consome componentes de reação da pasta de componentes.

Aqui está minha configuração (você pode reproduzi-la do seu lado - eu confio em você: 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()

Consegui contornar um problema semelhante usando uma tag de base:

  1. crie um arquivo manager-head.html no diretório .storybook. https://storybook.js.org/docs/configurations/add-custom-head-tags/
  2. adicionar
<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>

(com script.href = para qualquer caminho desejado)

arquivos em index.html agora são recuperados com o prefixo especificado

Este comportamento não deveria ser incorporado ao Storybook, onde se você sinalizar -s ./static , seus caminhos funcionarão da mesma maneira no Storybook e na produção? Parece absurdo que quando digo ao Storybook que meu diretório estático é ./static , que meus caminhos relativos, por exemplo ./static/image.png tenham que ser ./image.png ou usar algum link simbólico bobo 🤔

@eckmLJE Se você usar o snippet que postei acima, ele deve funcionar sem qualquer configuração de pacote web adicional ou um link simbólico. No entanto, poderíamos ver a saída disso automaticamente como parte do processo de construção.

Ainda estou enfrentando o problema em 2020 ...
Meu caso é muito simples: meu package.json tem este script: "storybook": "start-storybook -s ./dist/img -p 8888"

Então, quando executo npm run storybook , ele exibe info => Loading static files from: /home/vagrant/projects/MySuperProject/web/themes/ofb/ofb_ui/dist/img .

mas quando tento acessar um arquivo no diretório dist/img do navegador com este URL, não funciona: http://localhost:8888/myImage.png ...

Então pessoal, é um bug ou estou fazendo algo errado?

@ndelangen , você acha que podemos encaixar isso nas alterações importantes do 6.0? Eu acho que seria uma ótima solução, mas quebrada.

Parece que a api de CopyWepbackPlugin mudou e você precisa adicionar uma chave pattern à solução @mtrabelsi como esta:

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;
}

Vou adicionar meus dois centavos relacionados a esse problema. Embora eu ache que está intimamente relacionado, minha solução difere de @mtrabelsi porque descobri que simplesmente copiar meus ativos para o diretório ./static que é o resultado do comando build-storybook não era suficiente. Especificamente se estou implantando o aplicativo estático em um servidor Tomcat que atende o aplicativo estático de http://example.com/docs , em que docs é um diretório localizado nos webapps / do Tomcat no servidor.

Por causa do subcaminho, nenhum dos arquivos fora do diretório / css no diretório / static estava sendo carregado. Estou usando caminhos relativos para imagens e fontes (esses eram os ativos estáticos que não carregavam na versão implantada). Assim, solicitações como https://example.com/img/path/to/my/image falharam, quando deveria ter sido adicionado / estático, ou seja. https://example.com/static/img/path/to/my/image Minhas soluções, como eu disse, são muito próximas de @mtrabelsi, mas eu apenas

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;
}

Depois disso, as imagens e fontes foram carregadas de forma adequada.

@tmeasday sugere: por que não podemos fazer disso uma opção main.js para que apareça em start-storybook e build-storybook

@ vcastro45 Eu testei isso para o livro de histórias de início e para o livro de histórias de construção, e parece funcionar (testado no ramo next ).

Você poderia criar um repo de reprodução para mim?

@shilman É possível, mas teríamos que içar a configuração predefinida de
https://github.com/storybookjs/storybook/blob/9ea455a1746c489b7364448212663f2445af8a8b/lib/core/src/server/manager/manager-config.js#L101 -L102

até antes aqui:
https://github.com/storybookjs/storybook/blob/19c2420db80fcb3b89b34cdbbe03bf9010b0b3b2/lib/core/src/server/build-static.js#L190 -L191

E então passe para todas as funções inferiores na cadeia build / dev.
É um refatorador e tanto, não é algo que posso fazer em 1 dia.

Também seria outro momento em que realmente desejaríamos migrar tudo para o TS. Já que estaríamos mexendo em 50% dos arquivos lib / core de qualquer maneira.

@ndelangen OOF, não vamos fazer isso agora 🙈

Sim faremos isso algum dia

@ndelangen Eu documentei a solução alternativa por discussão com @tmeasday em # 11370. Proponha que movamos esta configuração para main.js e adicionemos uma opção para suportar este caso de uso em 6.x como um recurso, não uma alteração importante.

Você acha que uma solução como start-storybook -p 6006 -s "./public:/static" para servir arquivos estáticos de ./public no caminho /static ser implementada? Isso levaria a usos extremamente flexíveis e se encaixaria nas convenções do Docker de mapeamento de caminho com as quais muitos de nós já estamos familiarizados.

Olá a todos! Parece que não tem havido muito nesta edição ultimamente. Se ainda houver perguntas, comentários ou bugs, fique à vontade para continuar a discussão. Infelizmente, não temos tempo para abordar todos os problemas. Estamos sempre abertos a contribuições, portanto, envie-nos uma solicitação de pull se quiser ajudar. Os problemas inativos serão fechados após 30 dias. Obrigado!

@nfroidure, com certeza é uma ideia interessante!

@ndelangen , posso tentar com um PR, se desejar. Alguma chance de ser mesclado?

Bem, eu tenho algo aqui: https://github.com/storybookjs/storybook/pull/12222

Alguns testes estão falhando, mas não consigo ver nenhuma ligação entre essas falhas e minhas alterações.

LMKWYT;)

Obrigado por este PR @nfroidure !

Vou dar uma olhada nesta semana!

ZOMG !! Acabei de lançar https://github.com/storybookjs/storybook/releases/tag/v6.1.0-alpha.6 contendo PR # 12222 que faz referência a esse problema. Atualize hoje para experimentar!

Você pode encontrar este pré-lançamento na tag @next NPM.

Fechando esta questão. Abra novamente se achar que ainda há mais a fazer.

Existe um exemplo de como usar esse novo recurso?

Esta página foi útil?
0 / 5 - 0 avaliações