webpack css-loader не находит изображения в ссылке url() во внешней таблице стилей
Я новичок во всем мире Node/NPM/Webpack, поэтому извиняюсь, если это очевидно.
Я пытаюсь создать простой интерфейсный проект в комплекте с Webpack. У меня установлен узел и настроен файл package.json. Если я запускаю "npm start" в своем корневом каталоге, я не получаю ошибок от консоли, и я могу перейти к "localhost:3000" в браузере и посмотреть мой вывод "hello, world".
Моя следующая задача - включить таблицу стилей, которая содержит ссылку на изображение, например:
.myimg {background: url(path/to/file.jpg);}
С такими настройками я могу просматривать изображение через webpack-dev-server (зайдя на localhost: 3000 в веб-браузере), но если я собираю проект, путь к изображению будет неправильным. Я понятия не имею, что я делаю неправильно, поэтому я выбрасываю это в Stackiverse в надежде, что кто-нибудь там узнает, что я делаю глупо.
Вот мой файл package.json:
{
"name": "webpack-test1",
"version": "0.0.1",
"description": "My project WTF.",
"private": true,
"scripts": {
"start": "node server.js"
},
"devDependencies": {
"css-loader": "^0.15.2",
"file-loader": "^0.8.4",
"style-loader": "^0.12.3",
"url-loader": "^0.5.6"
},
"dependencies": {
"webpack": "^1.9.6",
"webpack-dev-server": "^1.8.2"
}
}
... и вот мой файл webpack.config.js:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: [
"./src/start.js"
],
output: {
filename: "bundle.js",
path: path.join(__dirname, 'build'),
publicPath: '/build/'
},
module: {
loaders: [
{ test: /\.css$/, loader: 'style-loader!css-loader' },
{ test: /\.(png|jpg)$/, loader: 'file-loader' }
]
}
};
... а затем файл index.html:
<!doctype html>
<html>
<head>
<title>Webpack Test</title>
</head>
<body>
<div class="imgtest">hello, world</div>
<script src="build/bundle.js"></script>
</body>
</html>
... файл "start.js", указанный в файле конфигурации:
require('./test.css');
console.log("y u no work?");
... и, наконец, содержимое самого файла CSS:
.imgtest { background: url(img/volcano.jpg);}
Как я уже говорил выше, в мире webpack-dev-server путь к изображению разрешается правильно, и он отображается в качестве фона для элемента DOM. В опубликованном мире браузер сообщает, что не может найти файл, а консоль Safari явно показывает неверный путь к файлу:
http://localhost/build/1b05d814aa13ac035c6b122b9f5974f8.jpg
Правильный локальный путь:
http://localhost/~username/webpack1/build/1b05d814aa13ac035c6b122b9f5974f8.jpg
Понятно, что я делаю что-то не так, но не могу понять, что. Любая помощь или совет приветствуется.
Спасибо!
2 ответа
Хорошо... тьфу. Я просто понял это. Проблема была с переменной publicPath внутри webpack.config.js. У меня было это:
publicPath: '/build/'
... который в ретроспективе, очевидно, является абсолютным путем. Вместо этого мне нужно было следующее:
publicPath: './build/'
... который является относительным путем. Вещи, кажется, работают сейчас.
ОБНОВИТЬ:
Я все еще очень плохо знаком с Webpack, так что все это все еще довольно запутанно. Было сказано, что...
Я думаю, что поступил неправильно. В моем проекте Webpack был файл index.html в корне проекта, и я пытался использовать его как файл webpack-dev-server и то, что сборка будет использовать в качестве точки входа. Это вызывало у меня бесконечные головные боли, и я не думаю, что какое-либо решение, с которым я столкнулся, действительно сработало. Тогда я нашел это:
https://www.npmjs.com/package/html-webpack-plugin
Это позволяет вам создать страницу index.html из шаблона, что означает, что она не обязательно должна существовать в виде файла. webpack-dev-server создает его на лету и сохраняет в памяти, и когда вы публикуете его в своей папке "build", в этой папке создается файл index.html.
Может быть, есть действительно "правильный" способ решения проблемы, которую я поднял здесь, но это, кажется, работает очень хорошо, и окольным путем, это решает мои проблемы, так как полностью уклоняется от всего вопроса о пути.
Во всяком случае, это немного бессвязно. Я надеюсь, что это кому-то поможет, и / или я надеюсь, что кто-то, кто знает больше об этом, придет сюда и уладит меня.
ОШИБКА, с которой я столкнулся, была
Module parse failed: PATH:\TO\IMG\XYZ.PNG Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected character '�' (1:0)
.
.
.
.
.
@ ./~/css-loader!./~/sass-loader!./node/static/sass/style.scss 6:399692-399747
Это решает мою проблему:
module: {
.
.
.,{
test: /\.scss$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader"),
root: path.resolve('./node/static/sass')
},
{
test: /\.(jpe?g|gif|png)$/,
loader: 'file-loader?emitFile=false&name=[path][name].[ext]'
}
]}
Запустите ваш веб-пакет снова.
Добавить весь фон: url('~/../somePath/toImage.png');
> thunderbolt@0.0.1 react-build PATH:\TO\PROJECT
> webpack --watch --display-error-details --display-cached --content-base ./
Hash: f6e4cbbf0068b5792247
Version: webpack 1.13.2
Time: 4882ms
Asset Size Chunks Chunk Names
js/bundle.js 760 kB 0 [emitted] main
css/bundle.css 393 kB 0 [emitted] main
+ 180 hidden modules
Child extract-text-webpack-plugin:
+ 76 hidden modules
Чтобы кратко объяснить, что делает загрузчик файлов - он копирует файл по новому пути и помещает этот путь в CSS, для моего случая файл CSS был вложен в какую-то общую папку, тогда как загрузчик файлов вставил бы его в корневой каталог public, с определенным путем =[путь] это все еще манипулирует относительным путем. Таким образом, отключение этого полностью решает мою проблему относительных путей, и добавьте, что у меня есть папка с вложенными изображениями, так что это также устраняет проблему разрешения этих путей. И двойная копия одних и тех же изображений - это то, что мне не нужно.