web-dev-qa-db-fra.com

URL relatives CSS dans Webpack

Webpack + chargeur de fichiers + sass-loader rencontre des difficultés pour résoudre les chemins relatifs des images d'arrière-plan CSS.

Le fichier SCSS compilé contient un chemin d'accès à l'image d'arrière-plan relatif à /dist/ et non au document SCSS/CSS. J'ai recherché ce problème; sass-loader recommande l'utilisation de resolut-url-loader (avec les cartes source). Cependant, l'ajout de resolut-url-loader n'a eu aucune incidence sur le CSS compilé.

J'ai pu résoudre le problème en définissant le paramètre 'publicPath' sur '../ ..' sur le chargeur de fichiers. Ou en désactivant le paramètre "url" sur le css-loader. Ce n'est pas non plus une bonne solution et pose des problèmes de copie de fichiers et de référence aux images via HTML ou d'autres sources.

Les exemples en ligne de Webpack et CSS placent le CSS et les images dans le même dossier (souvent à la racine). Ce n'est pas un choix optimal pour l'implémentation de mon webpack. Le concept de structurer des fichiers dans des sous-dossiers semble être une exigence assez fondamentale. Est-ce simplement une mauvaise approche?

Exécution de Webpack ^ 3.5.1. Sass-loader ^ 6.0.6. Chargeur de fichiers ^ 0.11.2. Css-loader ^ 0.28.4.

Structure du fichier

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 a une option publicPath qui peut résoudre ce problème.

{
  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
        }
      }
    ]
  })
}

Ajout du tableau include aux fichiers cibles d'un répertoire particulier. Recommandé pour les cas où toutes les feuilles de style sont situées dans le même dossier.

4
Jason

La raison pour laquelle le chemin dans url(...) est incorrect est Webpack générer un chemin relatif au répertoire de sortie, pas au fichier CSS de sortie.

Vous pouvez utiliser css-url-relative-plugin pour résoudre ce problème, il remplacera url(...) par le chemin relatif correct en recalculant la relation entre la sortie css et le fichier d’actifs.

0
yibn2008