Невозможно разрешить абсолютные пути 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 ответа:
Одно из возможных решений, которое я смог придумать, было следующим:
Использовать
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 "