web-dev-qa-db-de.com

Relative CSS-URLs in Webpack

Webpack + File-Loader + Sass-Loader hat Probleme mit der Auflösung relativer Pfade für CSS-Hintergrundbilder.

Die kompilierte SCSS-Datei enthält einen Pfad zum Hintergrundbild, der relativ zu /dist/ und nicht relativ zum SCSS/CSS-Dokument ist. Ich habe dieses Problem untersucht. sass-loader empfiehlt die Verwendung von resolur-url-loader (mit Quellkarten). Das Hinzufügen des resolur-url-loader machte jedoch für das kompilierte CSS keinen Unterschied.

Ich konnte das Problem beheben, indem Sie 'publicPath' im Datei-Loader auf '../ ..' setzen. Oder indem Sie die Einstellung 'url' im css-loader deaktivieren. Keine gute Lösung und verursacht Probleme beim Kopieren von Dateien und beim Referenzieren von Bildern über HTML oder andere Quellen.

Bei den Online-Beispielen für Webpack und CSS werden CSS und Bilder im selben Ordner (häufig im Stammverzeichnis) abgelegt. Dies ist keine optimale Wahl für meine Webpack-Implementierung. Das Konzept der Strukturierung von Dateien in Unterordnern scheint eine ziemlich grundlegende Voraussetzung zu sein. Ist das einfach der falsche Ansatz?

Webpack ausführen ^ 3.5.1. Sass-Loader ^ 6.0.6. File-Loader ^ 0.11.2. Css-loader ^ 0.28.4.

Dateistruktur

example/
├── dist/
│   ├── assets
│   │   ├── media
│   │   │   └── logo.png
│   │   └── styles
│   │       ├── app.css
│   │       └── app.css.map
│   ├── index.html
│   └── app.bundle.js
└── src/
    ├── assets
    │   ├── media
    │   │   └── logo.png
    │   └── styles
    │       └── app.scss
    └── app.js

app.scss

body {
  background: url(../media/logo.png);
}

app.css

body {
  background: url(assets/media/logo.png); //This should be ../media/logo.png
}

app.js

require('./assets/styles/app.scss');

webpack.config.js

const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
  entry: './src/app.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'app.bundle.js'
  },
  devtool: 'source-map',
  module: {
    loaders: [
      {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract({
          use: [
            {
              loader: 'css-loader',
              options: {
                sourceMap: true
              }
            }, {
              loader: 'resolve-url-loader'
            }, {
              loader: 'sass-loader',
              options: {
                sourceMap: true
              }
            }
          ]
        })
      }, {
        test: /\.png$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: 'assets/media/[name].[ext]'
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin({
      filename: 'assets/styles/app.css'
    })
  ]
}
5
Jason

ExtractTextPlugin verfügt über eine publicPath-Option, mit der dieses Problem behoben werden kann.

{
  test: /\.scss$/,
  include: [
    path.resolve(__dirname, "src/assets/styles")
  ],
  use: ExtractTextPlugin.extract({
    publicPath: '../../',
    use: [
      {
        loader: 'css-loader',
        options: {
          sourceMap: true
        }
      }, {
        loader: 'sass-loader',
        options: {
          sourceMap: true
        }
      }
    ]
  })
}

include-Array zu Zieldateien in einem bestimmten Verzeichnis hinzugefügt. Empfohlen für Fälle, in denen sich alle Stylesheets im selben Ordner befinden.

4
Jason

Der Grund, warum path in url(...) falsch ist, ist der webpack-Generierungspfad relativ zum Ausgabeverzeichnis, nicht die Css-Ausgabedatei.

Sie können css-url-relative-plugin verwenden, um dieses Problem zu lösen. url(...) wird durch den korrekten relativen Pfad ersetzt, indem Sie die Beziehung zwischen der Ausgabe-CSS-Datei und der Asset-Datei neu berechnen.

0
yibn2008