web-dev-qa-db-ja.com

Webpackの相対CSS URL

Webpack + file-loader + sass-loaderでCSS背景画像の相対パスを解決できません。

コンパイルされたSCSSファイルには、SCSS/CSSドキュメントからの相対ではなく、/dist/からの相対の背景画像へのパスが含まれています。私はこの問題を調査しました。 sass-loaderはresolve-url-loader(ソースマップ付き)の使用を推奨しています。ただし、resolve-url-loaderを追加しても、コンパイルされたCSSに違いはありませんでした。

ファイルローダーで 'publicPath'を '../ ..'に設定することで問題を解決できました。または、css-loaderの「url」設定を無効にすることにより。どちらも良い解決策ではなく、ファイルのコピーや、HTMLやその他のソースを介した画像の参照で問題が発生します。

WebpackとCSSのオンライン例では、CSSと画像を同じフォルダー(多くの場合ルート)に配置します。これは、私のWebpack実装にとって最適な選択ではありません。サブフォルダー内のファイルを構造化するという概念は、かなり基本的な要件のようです。これは単に間違ったアプローチですか?

Webpack ^ 3.5.1。の実行サスローダー^ 6.0.6。ファイルローダー^ 0.11.2。 CSSローダー^ 0.28.4。

ファイル構造

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'
    })
  ]
}
7
Jason

ExtractTextPluginには、この問題を解決できるpublicPathオプションがあります。

{
  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配列を追加しました。すべてのスタイルシートが同じフォルダーにある場合に推奨されます。

5
Jason

url(...)のパスが正しくない理由は、出力cssファイルではなく、出力ディレクトリを基準にしたwebpack生成パスです。

css-url-relative-plugin を使用してこの問題を解決できます。出力CSSとアセットファイルの関係を再計算することにより、url(...)を正しい相対パスに置き換えます。

1
yibn2008