我在用webpack 4.43.0的版本的时候,加载图片显示 [object%20Module] ,出现问题当时有点懵,因为我的图片路径是对的,为什么加不出来,之后利用调试工具,看到src中的url为:[object%20Module] ,但是怎么会显示这个呢?有点郁闷,查官方的webpack API看怎么处理?
webpack加载图片有两个loader可以使用,一个是file-loader,一个是url-loader。看这两个loader的相关讲解:
file-loader:
The file-loader
resolves import
/require()
on a file into a url and emits the file into the output directory.
相关的方法及属性:
在一个 bundle 文件中 import(或 require
)目标文件:
file.js
import img from './file.png';
然后,在 webpack
配置中添加 loader。例如:
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {},
},
],
},
],
},
};
然后,通过你偏爱的方式去运行 webpack
。将 file.png
作为一个文件,生成到输出目录, (如果指定了选项,则使用指定的命名约定) 并返回文件的 public URI。
name
类型:String|Function
默认:'[hash].[ext]'
Specifies a custom filename template for the target file(s) using the query parameter name
. For example, to emit a file from your context
directory into the output directory retaining the full directory structure, you might use:
String
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
},
},
],
},
],
},
};
Function
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name(file) {
if (process.env.NODE_ENV === 'development') {
return '[path][name].[ext]';
}
return '[hash].[ext]';
},
},
},
],
},
],
},
};
ℹ️ 默认情况下,文件会按照你指定的路径和名称输出同一目录中,且会使用相同的 URI 路径来访问文件。
outputPath
类型:String|Function
默认:undefined
Specify a filesystem path where the target file(s) will be placed.
String
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'images',
},
},
],
},
],
},
};
Function
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: (url, resourcePath, context) => {
// `resourcePath` is original absolute path to asset
// `context` is directory where stored asset (`rootContext`) or `context` option
// To get relative path you can use
// const relativePath = path.relative(context, resourcePath);
if (/my-custom-image\.png/.test(resourcePath)) {
return `other_output_path/${url}`;
}
if (/images/.test(context)) {
return `image_output_path/${url}`;
}
return `output_path/${url}`;
},
},
},
],
},
],
},
};
publicPath
类型:String|Function
默认:__webpack_public_path__
Specifies a custom public path for the target file(s).
String
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
publicPath: 'assets',
},
},
],
},
],
},
};
Function
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
publicPath: (url, resourcePath, context) => {
// `resourcePath` is original absolute path to asset
// `context` is directory where stored asset (`rootContext`) or `context` option
// To get relative path you can use
// const relativePath = path.relative(context, resourcePath);
if (/my-custom-image\.png/.test(resourcePath)) {
return `other_public_path/${url}`;
}
if (/images/.test(context)) {
return `image_output_path/${url}`;
}
return `public_path/${url}`;
},
},
},
],
},
],
},
};
context
类型:String
默认:context
Specifies a custom file context.
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
context: 'project',
},
},
],
},
],
},
};
emitFile
类型:Boolean
默认:true
如果是 true,生成一个文件(向文件系统写入一个文件)。 如果是 false,loader 会返回 public URI,但不会生成文件。 对于服务器端 package,禁用此选项通常很有用。
file.js
// bundle file
import img from './file.png';
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: 'file-loader',
options: {
emitFile: false,
},
},
],
},
],
},
};
regExp
类型:RegExp
默认:undefined
Specifies a Regular Expression to one or many parts of the target file path. The capture groups can be reused in the name
property using [N]
placeholder.
file.js
import img from './customer01/file.png';
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
regExp: /\/([a-z0-9]+)\/[a-z0-9]+\.png$/,
name: '[1]-[name].[ext]',
},
},
],
},
],
},
};
ℹ️ If
[0]
is used, it will be replaced by the entire tested string, whereas[1]
will contain the first capturing parenthesis of your regex and so on...
placeholders
Full information about placeholders you can find here.
[ext]
类型:String
默认:file.extname
目标文件/资源的文件扩展名。
[name]
类型:String
默认:file.basename
文件/资源的基本名称。
[path]
类型:String
默认:file.directory
The path of the resource relative to the webpack/config context
.
[folder]
类型:String
默认:file.folder
The folder of the resource is in.
[emoji]
类型:String
默认:undefined
A random emoji representation of content
.
[emoji:<length>]
类型:String
默认:undefined
Same as above, but with a customizable number of emojis
[hash]
类型:String
默认:md5
指定生成文件内容哈希值的哈希方法。
[<hashType>:hash:<digestType>:<length>]
类型:String
The hash of options.content (Buffer) (by default it's the hex digest of the hash).
digestType
类型:String
默认:'hex'
The digest that the hash function should use. Valid values include: base26, base32, base36, base49, base52, base58, base62, base64, and hex.
hashType
类型:String
默认:'md5'
The type of hash that the has function should use. Valid values include: md5
, sha1
, sha256
, and sha512
.
length
类型:Number
默认:undefined
Users may also specify a length for the computed hash.
[N]
类型:String
默认:undefined
The n-th match obtained from matching the current file name against the regExp
.
示例
The following examples show how one might use file-loader
and what the result would be.
file.js
import png from './image.png';
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: 'dirname/[hash].[ext]',
},
}
],
},
],
},
};
结果:
# result
dirname/0dcbbaa701328ae351f.png
file.js
import png from './image.png';
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[sha512:hash:base64:7].[ext]',
},
},
],
},
],
},
};
结果:
# result
gdyb21L.png
file.js
import png from './path/to/file.png';
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[path][name].[ext]?[hash]',
},
},
],
},
],
},
};
结果:
# result
path/to/file.png?e43b20c069c4a01867c31e98cbce33c9
以上是官网的相关使用讲解,已经很详细了。但是我没有使用file-loader,我本人使用的url-loader。
因此来看看url-loader:
webpack的一个加载器,它将文件转换成base64 uri。
url-loader
works like file-loader
, but can return a DataURL if the file is smaller than a byte limit.
import img from './image.png'
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
}
]
}
}
And run webpack
via your preferred method.
Options
fallback
Type: String
Default: 'file-loader'
Specifies an alternative loader to use when a target file's size exceeds the limit set in the limit
option.
// webpack.config.js
{
loader: 'url-loader',
options: {
fallback: 'responsive-loader'
}
}
The fallback loader will receive the same configuration options as url-loader.
For example, to set the quality option of a responsive-loader above use:
{
loader: 'url-loader',
options: {
fallback: 'responsive-loader',
quality: 85
}
}
limit
Type: Number
Default: undefined
A Number
specifying the maximum size of a file in bytes. If the file is greater than the limit, file-loader
is used by default and all query parameters are passed to it. Using an alternative to file-loader
is enabled via the fallback
option.
The limit can be specified via loader options and defaults to no limit.
// webpack.config.js
{
loader: 'url-loader',
options: {
limit: 8192
}
}
mimetype
Type: String
Default: (file extension)
Sets the MIME type for the file to be transformed. If unspecified the file extensions will be used to lookup the MIME type.
// webpack.config.js
{
loader: 'url-loader',
options: {
mimetype: 'image/png'
}
}
以上是对url-loader官网讲解,但是这个没有解决我的问题。
之后查找相关资料,说有可能是webpack4 esm(ES Module)和cjs(CommonJS)的互操作性,在url-loader的options中添加如下属性解决:esModule:false,只是暂时解决,看能不能在从配置出发在进行解决。