Angular: So analysieren Sie JSON-Variablen in SCSS

8

Innerhalb einer Angular-Anwendung mache ich D3-Visuals entweder über D3 oder Vega . Es gibt auch SCSS-Styling.

Ich möchte in der Lage sein, auf dieselben globalen Variablen für das Styling von Javascript und von SCSS zu verweisen. JSON-Dateien eignen sich sehr gut zum Speichern von Einstellungen, die ich über eine einfache importAnweisung in Typescript lade . Aber wie geht man bei SCSS vor?

node-sass-json-importer scheint ein guter Kandidat zu sein, aber das Hinzufügen zu einer Angular 9 CLI-Anwendung ist für mich nicht offensichtlich.

In diesem StackOverflow-Beitrag wurde das Thema vor einiger Zeit behandelt, es wurden jedoch Ressourcen geändert, unter node_modulesdenen dies kaum nachhaltig ist.

Es gibt auch einige Eingaben im ursprünglichen Dokument, wie man das Webpack in einer Nicht-Angular-App optimieren kann . Ich weiß nicht, wie ich das mit einer Angular-App in Verbindung bringen soll, die über die CLI erstellt wurde.

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(),
          },
        },
      ],
    ],
  },
};
Summen
quelle
1
Vielleicht ist das eine Option? npmjs.com/package/@angular-builders/custom-webpack
MikeOne
Hilft das? github.com/vigetlabs/sass-json-vars
Tarun Lalwani
Es scheint sich auf Node-Sass-JSON-Importer zu beziehen, aber meine verbleibende Herausforderung wäre es, dies in einer Angular 9 CLI-App zum
Laufen zu bringen
Ich habe nichts abgelehnt. Jeder kann abstimmen, nicht nur das OP.
BuZz

Antworten:

5

Sie können dies tun, ohne node_modulesDateien @angular-builders/custom-webpackzu ändern, indem Sie benutzerdefinierte Webpack-Regeln einrichten und node-sass-json-importerJSON-Dateien in SCSS-Dateien importieren.

Sie müssen node-sassfür die implementationOption installieren, da sie node-sass-json-importermit kompatibel ist node-sass.

  1. Installieren von Paketen @angular-builders/custom-webpack, node-sass-json-importerund node-sass:

    npm i -D @angular-builders/custom-webpack node-sass-json-importer node-sass
  2. Erstellen Sie die Webpack-Konfigurationsdatei ( webpack.config.js) im Projektstammverzeichnis mit den folgenden Inhalten:

    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. Ändern builderzu @angular-builders/custom-webpack:[architect-target]und Add - customWebpackConfigOption build, serveund testBuild - Ziele innerhalb 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"
            },
            ...
          },
        },
        ...
      },
      ...
    }

Jetzt können Sie jede .jsonDatei in jede Komponentendatei aufnehmen .scss:

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

Ich habe ein Github-Repository mit all diesen Funktionen erstellt, das Sie von hier aus klonen und testen können: 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
quelle
3

Eine andere Option ist die Verwendung raw-loader. Sie ist standardmäßig in angle-cli verfügbar. Auf diese Weise können Sie eine unformatierte scss-Datei in die ts-Komponente laden:

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

console.info('scss', scss);

Sie müssen das Modul in der .d.tsDatei deklarieren :

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

Dann können Sie alle gewünschten Informationen extrahieren.

Anstatt JSON in scss zu laden, können Sie scss in ts laden.

kemsky
quelle
Das hat bei mir funktioniert, aber ich fand es etwas schwierig zu folgen. Bitte geben Sie Beispieldateinamen für das deklarierte Modul (.d.ts) und das Stylesheet (.scss) an. Es wäre auch hilfreich, wenn Sie einen beispielhaften .scss-Code angeben und angeben würden, wie Sie darauf zugreifen würden. Ich konnte reguläre Ausdrücke verwenden, aber eine kompliziertere .scss-Datei ist möglicherweise schwieriger zu erreichen.
Todd
2

Ich habe einen relativ einfachen Ansatz für Sie:

Trennen Sie den node-sassSchritt vom ng buildSchritt und verwenden Sie die generierten .cssDateien anstelle der sassDateien in Ihrer Winkel-App.

Dies hat zwei Vorteile:

  • Es ist nicht erforderlich, Knotenmodule stark zu optimieren und zu bearbeiten
  • volle Kontrolle darüber, wie der Sass kompiliert wird

Für die Implementierung würde ich wie folgt vorgehen:

  1. Fügen Sie ./node_modules/.bin/node-sass --importer node_modules/node-sass-json-importer/dist/cli.js --recursive ./src --output ./srcden Skripten in Ihrem package.jsonzB den Namen hinzu build-sass. Sie können diesen Befehl so anpassen, dass nur die Sass-Dateien enthalten sind, für die Sie den rekursiven Modus benötigen (ignorieren Sie sie in der Datei angle.json, damit sie nicht zweimal kompiliert werden).
  2. Führen Sie den Befehl einmal npm run build-sassaus, um die .cssDateien im Projekt zu generieren .
  3. Ändern Sie bei Bedarf die Referenzen in Winkelkomponenten von .sassbis.css
  4. Fügen Sie (optional) einen Komfortbefehl npm run build-sass && ng buildwie compilein Ihrer package.json hinzu, den Sie ausführen können, wann immer Sie das gesamte Projekt erstellen möchten.

Dieser Ansatz ist zwar relativ einfach, weist jedoch einige Nachteile auf

  • Für alle Komponenten, für die Sie das CSS verwenden möchten, ng servemüssen Sie für die Hot-Reload-Funktion von Ihre ausführen npm run build-sass, um alle Änderungen, die Sie an Ihren Stilen vorgenommen haben, in Echtzeit anzuzeigen
  • Ihr Projekt wird ein bisschen unordentliche aussehen, da es .scssund .cssDateien für die gleiche Komponente in dem /srcOrdner , von denen die .csserzeugt wird. Sie müssen sicherstellen (z. B. durch Hinzufügen eines Suffixes oder Kommentars), dass niemand versehentlich das Generierte bearbeitet .cssund diese Änderungen überschrieben werden.

Andere Ansätze beinhalten fast immer das intensive Bearbeiten vorhandener oder das Schreiben eines eigenen Webpack-Compilers.

Kacase
quelle