Невозможно разрешить абсолютные пути url () для фоновых изображений в CSS с помощью Webpack


У меня есть следующая конфигурация Webpack (грубо говоря, она была упрощена для этого поста):

const rootPublic = path.resolve('./public');
const LOCAL_IDENT_NAME = 'localIdentName=[name]_[local]_[hash:base64:5]';
const CSS_LOADER = `css?sourceMap&${LOCAL_IDENT_NAME}&root=${rootPublic}`;
const SASS_LOADER = 'sass?sourceMap&includePaths[]=' + path.resolve(__dirname, './src/styles');

// ... loaders:

loaders: [
  {
    test: /.(jpe?g|png|gif|svg)$/,
    loader: 'url-loader?limit=10000&name=[path][name].[ext]'
  },
  {
    test: /.scss$/,
    loader: config.DEVELOPMENT_MODE ? `style!${CSS_LOADER}!autoprefixer!${SASS_LOADER}`
                : ExtractTextPlugin.extract('style', `${CSS_LOADER}!autoprefixer!${SASS_LOADER}`)
  }, // ...
]

Теперь это прекрасно работает для изображений, на которые обычно ссылаются в файлах scss:

.some-static-class {
  background: url('/images/bg.png');
}

Однако он нене работает при использовании директивы :local:

:local .SomeClass {
  background: url('/images/bg.png');
}

И я думаю, что это потому, что root определен для загрузчика CSS. Я получаю ошибку сборки: Module not found: Error: Cannot resolve 'file' or 'directory' ./../../../../../../../../images/bg.gif

Если вместо этого я удаляю root из конфигурации css-loader, то он строит нормально, но тогда путь "выглядит" правильно в инспекторе Chrome, но когда вы на самом деле открываете ссылку в новой вкладке, она указывает на: chrome-devtools://devtools/bundled/"/images/bg.png", которая, очевидно, не решается правильно.

Я не уверен, что проблема в конфигурации url-loader, или что именно происходит.

Я поиграл с различными конфигурациями webpack, чтобы указать разрешение.корень, решительность.modulesDirectories и т. д., Но совершенно не уверен, оказывают ли они какое-либо влияние или я просто делаю это совершенно неправильно. Я тоже наткнулся на resolve-url-loader но не уверен, что это вообще то, что мне нужно.

Есть идеи? Приводе mtia!

Обновить

Должен отметить, что он отлично работает в Safari, но не в Chrome. Так что это похоже на специфическую для Chrome ошибку, но это не практично, чтобы делать все наши разработки в Safari.

Я также наткнулся на Vue-style-loader , который является развилкой style-loader, которая утверждает, что исправляет эту проблему, но способ ее исправления заключается в использовании устаревшего устаревшего escape / unescape метод.

2 7

2 ответа:

Одно из возможных решений, которое я смог придумать, было следующим:

Использовать resolve-url-loader (сразу после sass-loader):

style!${CSS_LOADER}!autoprefixer!resolve-url!${SASS_LOADER}

Затем определите решение.псевдоним для статических изображений:

resolve: {
  alias: {
    images: path.join(__dirname, 'public/images')
  }
}

И затем в CSS вы можете указать на изображения следующим образом:

:local .SomeClass {
  background: url('images/bg.png');
}

В зависимости от структуры URL-адреса, возможно, Вам также потребуется настроить url-loader имя param:

{
  test: /\.(jpe?g|png|gif|svg)$/,
  loader: 'url-loader?limit=10000&name=images/[name].[ext]'
}

Так что я не знаю, есть ли более чистый способ решить эту проблему, но это лучшее, что я мог придумать. далеко. Я приветствую любые отзывы или альтернативы.

Спасибо!

Обновление 6/30/2016

Есть пара PR-программ, которые решают эту проблему, но сопровождающий предпочитает, чтобы решение было в CSS AST, а не в css loader...

Https://github.com/webpack/style-loader/pull/124 https://github.com/webpack/style-loader/pull/96

Вот надеюсь, что реальное исправление произойдет в ближайшее время...

С webpack 2:

В вашем .файлы scss используют ~ перед путем.

.yourClass {
      background: url('~img/wallpaper.png');
}

Используйте корень resolve из webpack, добавьте его в свой webpack.конфиг.js:

resolve: {
        modules: [
            path.resolve(root),
            'node_modules'
        ]
    },

Он должен работать также для @import, например @import " ~otherfile.scss "