Webpack使用file-loader处理图片
在页面中引入图片有两种方式
- img标签引入
- css引入
file-loader
配置
{
test: /\.jpg|\.png|\.jpeg|\.svg|\.ttf|\.woff$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: './img',
publicPath: '/img'
}
}]
}
其中
outputPath
负责输出目录, 即打包后的写在磁盘的位置.
publicPath
则是对页面引入资源的补充,比如img
标签引入或者css
引入等.
问题
按上面路径配置时, 打包后文件都在build/img
开发环境
下可以正确引入文件,引入路径为localhost:8080/img
生产环境
下引入路径为f:///img
导致找不到图片
file-loader
的官方说明
outputPath
Specify a filesystem path where the target file(s) will be placedpublicPath
Specifies a custom public path for the target file(s)
output
: 指定将放置目标文件的文件系统路径. 这跟我们遇到的文件没多大关系.那问题就是在publicPath
publicPath
: 指定目标文件的自定义公共
路径,它是定义公共路径,所以我们在开发模式下能正确引入文件,因为都在同一个路径下,即localhost:8080
.
生产模式下如何解决该问题呢?
别忘了我们引进图片有两种方式,img
标签或者css
引入.
当我将file-loader
路径配置修改为
outputPath: './img',
publicPath: '../img'
因为打包后目录结构是
结果通过css
引入的图片打包后还可以正确引入,路径是../img
但是通过img
标签引入的图片则报错,引入路径是项目根目录/img
,正确的应该是项目根目录/build/img
我们看看打包后的js
中的引入路径
看起来好像是正确的,但是有一点,CSS
和JS
引入图片的机制是不一样,详细可以看 css和js引用图片的路径问题
当我们要引用一个图片时,在js文件中要以引用它的html的路径为准;而在css文件中,要以该css的路径为准,而与引用该CSS文件的页面所在的位置无关
我们已经找到问题所在了, 那么该如何解决呢?
解决方法
不设置file-loader
的outputPath
和publicPath
,默认跟随webpack
的打包目录, 这还不够,我们还得将css
文件也打包到跟图片文件同级.
打包后目录为
这样不管是生产环境
还是开发环境下
都能正确引入图片.
但是当图片多了之后build
目录下会有很多的文件,我们还是希望图片文件打包后在img
文件夹.让我们再来看看这该怎么解决.
我们已经知道了设置了file-loader
下的publicPath
就是css
文件与js
文件引入图片的路径,因为css
和js
引入的机制不同,我们只需要将css
文件打包之后与html
同级即可.
修改webpack
配置
{
test: /\.jpg|\.png|\.jpeg|\.svg|\.ttf|\.woff$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: './img',
publicPath: './img'
}
}]
}
修改前
new ExtractTextPlugin('css/[name].css')
修改后
new ExtractTextPlugin('[name].css')
打包后目录结构
完美解决.
更新 --- 将CSS
单独打包,并且图片路径能正常引用
修改extract-text-webpack-plugin
的options以及file-loader
的publicPath
打包后的目录
css/
img/
...
根据两个文件夹的位置关系, 我们设置extract-text-webpack-plugin
use: ExtractTextPlugin.extract({
fallback: ...,
use: loaders,
publicPath: '../' // 注意,这个是重点,根据目录结构不同值也不同
})
移除file-loader
的干扰
...
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: './img', // 运行在服务器时发布路径
// publicPath: './img' // 注销掉这一行,不设置.
}
...