Skip to content

Sass

Problemas de importação

Importar arquivos .scss tanto internos quanto externos podem ser problemáticos, e podem variar dependendo de onde você os importa. Iremos falar de cada um aqui.

Import de css externo e interno dentro de um componente, direto no javascript:

<script>
  import "my-lib/css.css";
  import "my-lib/scss.scss";
  import "./my-scss.scss";
  import "./my-scss.scss;
<script>

Este tipo de importe será avaliado pelo webpack, ou pelo rollup dependendo se você está executando o aplicativo ou o storybook, ambos iram verificar se o pacote exporta esta lib e irá importar o arquivo, caso contrário ele não deixara o import externo ocorrer utilizando o formato my-lib/css.css, assim deve ser utilizado o formato ../../<path-to-node-modules>/node_modules/my-lib/css.css. Vale ressaltar que este tipo de import permite a reutilização dos arquivos, isto é importar o mesmo arquivo em 2 componentes não causa duplicatas no bundle.

Import na tag de style usando import:

<style lang="scss">
  import "my-lib/css.css";
  import "my-lib/scss.scss";
  import "./my-scss.scss";
  import "./my-scss.scss";
<style>

Devido ao comportamento do svelte-preprocessos, o uso de import não é resolvido em build, e permanecera conforme escrito, ele entende o import como o import de módulos css nativo.

Import na tag de style usando use:

<style lang="scss">
  @use "my-lib/css.css";
  @use "my-lib/scss.scss";
  @use "./my-scss.scss";
  @use "./my-scss.scss";
<style>

Com este uso ele irá encontrar as bibiotecas, mas para a importação de libs externas pode ser que você precisa utilizar o formato antigo @use "~my-lib/css.css";. Outro ponto a se destacar é que o uso do svelte-preprocesso faz com que o arquivo seja copiado para o componente, isso significa que o mesmo arquivo sendo importado em 2 componente causa duplicatas no bundle. Recomendamos este uso somente para variáveis e mixins scss.

Import em arquivos scss:

// file: global.scss

@use "my-lib/css.css";
@use "my-lib/scss.scss";
@use "./my-scss.scss";
@use "./my-scss.scss";

Este tipo de importe, assim como no javascript, irá verificar se o pacote exporta esses arquivos ou se o arquivos é interno. Isso significa que você não conseguirá importar arquivos css de pacotes que não declararam ele no package.json tendo de recorrer ao bom e velho ../../<path-to-node-modules>/node_modules/my-lib/css.css.

Este formato também é resolvido no build e não cria duplicatas no bundle, entretanto ele possui um problema de referência. Quando um arquivo sass importa outro arquivo sass, e este arquivo importa algo por referência digamos uma imagem, a resolução esperada era que a referência fosse em relação ao arquivo que o importa, entretanto o rollup consegue lidar com isso, mas o webpack não.

Considere os arquivos e diretórios a seguir:

src/
├─ styles/
│  ├─ sub-folder/
│  │  ├─ fonts.scss
│  ├─ global.scss
├─ assets/
│  ├─ some-font.svg

Se o arquivo fonts.scss é:

@font-face {
  font-family: "Some Font";
  src: url("../../assets/some-font.svg") format("svg"),
}

O arquivo global.scss é:

@use "./sub-folder/fonts.scss";

body {
  font-family: "Some Font";
}

Importando o arquivo global.scss em algum javascript global do storybook, e no main.js que seria o global da aplicação, temos que, o rollup vai encontrar corretamente o arquivo de font buscado, porém o webpack do storybook não. No webpack teremos que colocar o endereço ../assets/some-font.svg, que seria o relativo ao arquivo global.scss. É como se a resolução do webpack fosse copiar o texto dos scss até o ultimo nível, e ao chegar em algum javascript que faz a importação ele resolve os assets relativos.

Muito desse problema surge por termos 3 blunder veja aqui.