Angular: Como analisar variáveis ​​JSON no SCSS

8

Dentro de um aplicativo Angular, faço visuais D3 através de D3 ou Vega simples . Também existe um estilo SCSS.

Eu gostaria de poder me referir às mesmas variáveis ​​globais de estilo do Javascript e do SCSS. Os arquivos JSON fazem o truque muito bem para armazenar configurações carregadas no Typescript por meio de uma importdeclaração simples . Mas como alguém faz o mesmo com o SCSS?

node-sass-json-importer parece um bom candidato, mas adicioná-lo a um aplicativo CLI Angular 9 não é óbvio para mim.

Este post do StackOverflow abordou o assunto há algum tempo, mas envolveu a modificação de recursos sob os node_modulesquais dificilmente é sustentável.

Também existem algumas informações no documento original sobre como é possível ajustar o webpack em um aplicativo não angular . Não sei como relacionar isso a um aplicativo Angular criado por meio da CLI.

Webpack / sass-loader Blockquote

Webpack v1

import jsonImporter from 'node-sass-json-importer';

// Webpack config
export default {
  module: {
    loaders: [{
      test: /\.scss$/,
      loaders: ["style", "css", "sass"]
    }],
  },
  // Apply the JSON importer via sass-loader's options.
  sassLoader: {
    importer: jsonImporter()
  }
};

Webpack v2

import jsonImporter from 'node-sass-json-importer';

// Webpack config
export default {
  module: {
    rules: [
      test: /\.scss$/,
      use: [
        'style-loader',
        {
          loader: 'css-loader',
          options: {
            importLoaders: 1
          },
        },
        {
          loader: 'sass-loader',
          // Apply the JSON importer via sass-loader's options.
          options: {
            importer: jsonImporter(),
          },
        },
      ],
    ],
  },
};
Zumbido
fonte
1
Talvez isso seja uma opção? Npmjs.com/package/@angular-builders/custom-webpack
MikeOne
Isso ajuda? github.com/vigetlabs/sass-json-vars
Tarun Lalwani
parece estar relacionado ao node-sass-json-importador, mas meu desafio restante seria fazer com que isso funcionasse em um aplicativo CLI do Angular 9
BuZz
Eu não votei em nada. Qualquer um pode votar, não apenas o OP.
BuZz 28/03

Respostas:

5

Você pode fazer isso sem alterar nenhum node_modulesarquivo, usando @angular-builders/custom-webpackpara configurar regras personalizadas do Webpack e, como menciona, node-sass-json-importerpara importar arquivos JSON nos arquivos SCSS.

Você precisará instalar node-sassa implementationopção porque node-sass-json-importeré compatível com node-sass.

  1. Instalar pacotes @angular-builders/custom-webpack, node-sass-json-importere node-sass:

    npm i -D @angular-builders/custom-webpack node-sass-json-importer node-sass
  2. Crie o arquivo de configuração do Webpack ( webpack.config.js) no diretório raiz do projeto com o seguinte conteúdo:

    const jsonImporter = require('node-sass-json-importer');
    
    module.exports = {
      module: {
        rules: [{
          test: /\.scss$|\.sass$/,
          use: [
            {
              loader: require.resolve('sass-loader'),
              options: {
                implementation: require('node-sass'),
                sassOptions: {
                  // bootstrap-sass requires a minimum precision of 8
                  precision: 8,
                  importer: jsonImporter(),
                  outputStyle: 'expanded'
                }
              },
            }
          ],
        }],
      },
    }
    
  3. Alterar builderpara @angular-builders/custom-webpack:[architect-target]e add customWebpackConfigopção para build, servee testconstruir alvos dentro angular.json:

    "projects": {
      ...
      "[project]": {
        ...
        "architect": {
          "build": {
            "builder: "@angular-builders/custom-webpack:browser",
            "options": {
              "customWebpackConfig": {
                "path": "webpack.config.js"
              },
              ...
            },
            ...
          },
          "serve": {
            "builder: "@angular-builders/custom-webpack:dev-server",
            "customWebpackConfig": {
              "path": "webpack.config.js"
            },
            ...
          },
          "test": {
            "builder: "@angular-builders/custom-webpack:karma",
            "customWebpackConfig": {
              "path": "webpack.config.js"
            },
            ...
          },
        },
        ...
      },
      ...
    }
    

Agora você pode incluir qualquer .jsonarquivo dentro de qualquer .scssarquivo componente :

hello-world.component.scss:

@import 'hello-world.vars.json';

.hello-bg {
  padding: 20px;
  background-color: $bg-color;
  border: 2px solid $border-color;
}

hello-world.vars.json:

{
  "bg-color": "yellow",
  "border-color": "red"
}

Eu criei um repositório do Github com todos esses trabalhos que você pode clonar e testar a partir daqui: https://github.com/clytras/angular-json-scss

git clone https://github.com/clytras/angular-json-scss.git
cd angular-json-scss
npm install
ng serve
Christos Lytras
fonte
3

Outra opção é usar raw-loader, pois está disponível por padrão no angular-cli. Dessa forma, você pode carregar o arquivo scss bruto no componente ts:

// Adding `!!` to a request will disable all loaders specified in the configuration
import scss from '!!raw-loader!./config.scss';

console.info('scss', scss);

Você precisa declarar o módulo no .d.tsarquivo:

declare module '!!raw-loader!./*.scss';

Então você pode extrair qualquer informação que desejar.

Portanto, em vez de carregar o JSON no scss, você pode carregar o scss no ts.

kemsky
fonte
Isso funcionou para mim, mas achei um pouco difícil de seguir. Forneça exemplos de nomes de arquivos para o módulo declarado (.d.ts) e a folha de estilos (.scss). Também seria útil se você fornecesse algum exemplo de código .scss e como você o acessaria. Consegui usar expressões regulares, mas um arquivo .scss mais complicado pode ser mais difícil de segmentar dessa maneira.
Todd
2

Eu tenho uma abordagem relativamente simples para você:

Separe a node-sassetapa da ng buildetapa e use os .cssarquivos gerados em vez dos sassarquivos em seu aplicativo angular.

Isso tem duas vantagens:

  • não há necessidade de ajustar e editar fortemente nenhum módulo de nó
  • controle total sobre como o sass é compilado

Para a implementação, eu iria em frente da seguinte maneira:

  1. adicione ./node_modules/.bin/node-sass --importer node_modules/node-sass-json-importer/dist/cli.js --recursive ./src --output ./srcaos scripts no seu package.jsonexemplo, com o nome build-sass. Você pode ajustar este comando para incluir apenas os arquivos sass para os quais você precisa do modo recursivo (certifique-se de ignorá-los no angular.json, para que não sejam compilados duas vezes).
  2. execute o comando uma vez npm run build-sasspara gerar os .cssarquivos no projeto.
  3. referências alteração nos componentes angulares quando necessário a partir do .sassa.css
  4. (opcionalmente) adicione um comando de conveniência npm run build-sass && ng buildcomo compileem seu package.json, que você pode executar sempre que quiser construir o projeto inteiro.

Embora essa abordagem seja relativamente simples, ela apresenta algumas desvantagens

  • para todos os componentes em que você deseja usar o css, o recurso hot-reload ng serveexigirá que você execute o seu npm run build-sasspara ver as alterações feitas em seus estilos em tempo real
  • seu projeto parecerá um pouco mais confuso, pois existem .scsse .cssarquivos para o mesmo componente na /srcpasta na qual o arquivo .cssé gerado. Você precisará garantir (por exemplo, adicionando um sufixo ou comentário) que ninguém edite acidentalmente as geradas .csse que essas alterações sejam substituídas.

Outras abordagens quase sempre envolvem a edição intensa de arquivos existentes ou a criação de seu próprio compilador webpack.

kacase
fonte