通过 webpack 的 file-loader 把 css 中的 background-image 图片提取出来构建到产出目录,发现图片被生成在了产出目录的根目录。
目录结构:构建之后:
原本 src/css/02.png 的 png 图片构建之后目录变为 build/02.png。丢失了一层 css 目录,导致 css 中引用图片404。
有没有办法保证 src/css/02.png 构建之后的目录结构为 build/css/02.png,而不是 build/02.png。
附上极简的 demo 包文件下载。
再附上文件完整源码:
webpack.config.js :
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry : {
"demo" : "./src/js/demo.js"
},
output: {
path: path.resolve("./build"),
filename: 'js/[name].js'
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
// loader: 'style-loader!css-loader'
loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: 'css-loader' })
},
{
test: /\.(png|jpe?g|gif)(\?\S*)?$/,
loader: 'file-loader',
query: {
name: 'css/[name].[ext]'
}
}]
},
plugins : [new ExtractTextPlugin("css/[name].css")]
}
demo/src/js/demo.js
import "../css/layout.css";
demo/src/css/layout.css
h1 { color: red; background: url(./02.png) no-repeat; }
几点尝试:
1、修改 file-loader的配置,比如 name 追加css目录路径:
这样可以实现图片在 build/css/内生成,但是同时也会修改掉 layout.css的源码,使
h1 { color: red; background: url(./02.png) no-repeat; }
变为
h1 { color: red; background: url(css/02.png) no-repeat; }
图片是构建到了 css 目录下了,然而引用路径又变成了 css/02.png。无奈依然404。
2、指定 publicPath
比如:
output: {
path: path.resolve("./build"),
filename: 'js/[name].js',
publicPath : '/build/'
},
其实比较难把握项目的跟目录,换句话说,根目录下不一定有 build这个目录,有可能在根目录下的任何一级子目录。或者另外一种方法,使用生产环境的绝对路径
output: {
path: path.resolve("./build"),
filename: 'js/[name].js',
publicPath : 'http://xxx.123.cn/demo/build/' + versions
},
生成的样式表通过绝对路径引用生成的图片地址,看起来完美了,但是有个尴尬的地方,这个 version(版本号)从何而来,并不是每个公司都通过 webpack的 hash 生成版本号,可能有自己的一套版本发布系统,webpack 只是做资源文件的合并打包,本身不参与正式的版本生成,不幸的是,鄙人就属于这种情况(悲了个剧的),资源文件构建前需要指定 publicPath,要指定 publicPath 就得知道版本号,而这个版本要要资源文件构建完成之后,才会生成,死循环了。
所以,需要样式表通过相对路径引用同级目录下的图片。而想要在 webpack 构建之后保留样式表和图片的相对路径引用,有点尴尬。求各位大神指点迷津...
设置一下 path 看看