Webpack:从 html 个模板加载图像
Webpack: Loading images from html templates
我正在尝试使用 Webpack 设置一个 angular 项目,但我不知道如何从 html 模板中引用图像并将它们包含在构建中。
我的项目树如下:
package.json
app/
- images/
- foo.png
- scripts/
- styles/
- templates/
我正在尝试将 html-loader
与 url-loader
和 file-loader
一起使用,但它没有发生。
这是一个示例模板:app/templates/foo.html
<img src="../images/foo.png" />
问题 #1:我希望能够参考与 app/
相关的图像。现在,路径需要相对于模板文件,这很快就会变得很丑陋 (../../../images/foo.png
)。
问题#2:即使我指定了相对路径,就像我在上面所做的那样,项目构建成功但实际上没有任何反应。路径保持原样,dist/
.
中没有图像出现
这是我的 webpack 配置:
var path = require('path');
var webpack = require('webpack');
var ngminPlugin = require('ngmin-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var ngAnnotatePlugin = require('ng-annotate-webpack-plugin');
module.exports = function(config, env) {
var appRoot = path.join(__dirname, 'app/')
if(!env) env = 'development';
var webpackConfig = {
cache: true,
debug: true,
contentBase: appRoot,
entry: {
app: path.join(appRoot, '/scripts/app.coffee')
},
output: {
path: path.join(__dirname, 'dist/),
publicPath: '/',
libraryTarget: 'var',
filename: 'scripts/[name].[hash].js',
chunkFilename: '[name].[chunkhash].js'
},
module: {
loaders: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader")
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader!sass-loader?outputStyle=expanded&includePaths[]=./node_modules/foundation/scss/')
},
{
test: /\.coffee$/,
loader: 'coffee-loader'
},
{
loader: 'ngtemplate?relativeTo=' + (path.resolve(__dirname, './app')) + '/!html'
},
{
test: /\.png$/, loader: "url-loader?limit=100000&mimetype=image/png&name=[path][name].[hash].[ext]"
},
{
test: /\.jpg$/, loader: "file-loader?name=[path][name].[hash].[ext]"
},
{
test: /\.(woff|woff2)(\?(.*))?$/,
loader: 'url?prefix=factorynts/&limit=5000&mimetype=application/font-woff'
},
{
test: /\.ttf(\?(.*))?$/,
loader: 'file?prefix=fonts/'
},
{
test: /\.eot(\?(.*))?$/,
loader: 'file?prefix=fonts/'
},
{
test: /\.svg(\?(.*))?$/,
loader: 'file?prefix=fonts/'
},
{
test: /\.json$/,
loader: 'json'
}
]
},
resolve: {
extensions: [
'',
'.js',
'.coffee',
'.scss',
'.css'
],
root: [appRoot],
},
singleRun: true,
plugins: [
new webpack.ContextReplacementPlugin(/.*$/, /a^/),
new webpack.ProvidePlugin({
'_': 'lodash'
}),
new ExtractTextPlugin("styles/[name].[chunkhash].css", {allChunks: true}),
new HtmlWebpackPlugin({
template: appRoot + '/app.html',
filename: 'app.html',
inject: 'body',
chunks: ['app']
})
],
devtool: 'eval'
}
if(env === 'production') {
webpackConfig.plugins = webpackConfig.plugins.concat(
new ngAnnotatePlugin(),
new webpack.optimize.UglifyJsPlugin(),
new webpack.DefinePlugin({
'process-env': {
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin()
);
webpackConfig.devtool = false;
webpackConfig.debug = false;
}
return webpackConfig;
}
- 是的,您必须这样做才能从不同路径加载图像。
- 我遇到了类似的问题,我使用
file
加载器解决了这个问题:
.
loaders: [{
// JS LOADER
test: /\.js$/,
loader: 'babel-loader?optional[]=runtime',
exclude: /node_modules/
}, {
// ASSET LOADER
test: /\.(woff|woff2|ttf|eot)$/,
loader: 'file-loader'
},
{
//IMAGE LOADER
test: /\.(jpe?g|png|gif|svg)$/i,
loader:'file-loader'
},
{
// HTML LOADER
test: /\.html$/,
loader: 'html-loader'
},
{
//SCSS LOADER
test: /\.scss$/,
loaders: ["style-loader", "css-loader", "sass-loader?indentedSyntax"]
}
]
祝你好运
如果您在 Webpack 2 中使用 HTML 模板,除了使用文件加载器之外,您还需要更改 HTML:
<img src="../images/foo.png" />
到这个
<img src=<%=require("../images/foo.png")%> />
使用 Webpack 4,我可以通过 html-loader
更新来为我的文件指定 root
来解决这个问题。所以考虑到@syko 的原始结构;在 webpack.config.js
...
module: {
rules: [
// other stuff above.....
{
test: /\.html$/,
use: [
// ...The other file-loader and extract-loader go here.
{
loader: 'html-loader'
options: {
// THIS will resolve relative URLs to reference from the app/ directory
root: path.resolve(__dirname, 'app')
}
}
]
}
]
}
这告诉 html-loader
解释来自 /app
文件夹的所有 绝对 url。所以在我们的app/templates/foo.html
中,你可以使用下面的...
<img src="/images/foo.png" />
然后这告诉 html-loader
将上面的内容视为 path.resolve(__dirname, 'app', 'images', 'foo.png')
。那么如果你有extract-loader
and/orfile-loader
,所有的路径应该都是正确的。
苦苦思索了一段时间,终于得到了这个解决方案。最大的困惑是 /images/foo.png
在加载程序堆栈中的什么地方被解释,在这种情况下它从 html-loader
插件开始。之后的一切,更多的是关于如何发布图像文件。
希望对您有所帮助。
您可以使用 file-loader to extract images. Then using html-loader 您可以通过查询参数 attrs
.
指定此加载程序应处理的标签属性组合
我可以让它与这个配置一起工作:
{
test: /\.(jpe?g|png|gif|svg|ico)$/i,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/'
}
}]
},
{
test: /\.(html)$/,
use: {
loader: 'html-loader',
options: {
attrs: ['img:src', 'link:href']
}
}
}
或者在 angular 中是这样的:
attrs: [':ng-src', ':ng-href']
对于 Webpack 5 你必须这样写:
module: {
rules: [
// other stuff above.....
{
test: /\.html$/,
use: [
{
loader: 'html-loader'
}
]
}
]
}
我正在尝试使用 Webpack 设置一个 angular 项目,但我不知道如何从 html 模板中引用图像并将它们包含在构建中。
我的项目树如下:
package.json
app/
- images/
- foo.png
- scripts/
- styles/
- templates/
我正在尝试将 html-loader
与 url-loader
和 file-loader
一起使用,但它没有发生。
这是一个示例模板:app/templates/foo.html
<img src="../images/foo.png" />
问题 #1:我希望能够参考与 app/
相关的图像。现在,路径需要相对于模板文件,这很快就会变得很丑陋 (../../../images/foo.png
)。
问题#2:即使我指定了相对路径,就像我在上面所做的那样,项目构建成功但实际上没有任何反应。路径保持原样,dist/
.
这是我的 webpack 配置:
var path = require('path');
var webpack = require('webpack');
var ngminPlugin = require('ngmin-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var ngAnnotatePlugin = require('ng-annotate-webpack-plugin');
module.exports = function(config, env) {
var appRoot = path.join(__dirname, 'app/')
if(!env) env = 'development';
var webpackConfig = {
cache: true,
debug: true,
contentBase: appRoot,
entry: {
app: path.join(appRoot, '/scripts/app.coffee')
},
output: {
path: path.join(__dirname, 'dist/),
publicPath: '/',
libraryTarget: 'var',
filename: 'scripts/[name].[hash].js',
chunkFilename: '[name].[chunkhash].js'
},
module: {
loaders: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader")
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader!sass-loader?outputStyle=expanded&includePaths[]=./node_modules/foundation/scss/')
},
{
test: /\.coffee$/,
loader: 'coffee-loader'
},
{
loader: 'ngtemplate?relativeTo=' + (path.resolve(__dirname, './app')) + '/!html'
},
{
test: /\.png$/, loader: "url-loader?limit=100000&mimetype=image/png&name=[path][name].[hash].[ext]"
},
{
test: /\.jpg$/, loader: "file-loader?name=[path][name].[hash].[ext]"
},
{
test: /\.(woff|woff2)(\?(.*))?$/,
loader: 'url?prefix=factorynts/&limit=5000&mimetype=application/font-woff'
},
{
test: /\.ttf(\?(.*))?$/,
loader: 'file?prefix=fonts/'
},
{
test: /\.eot(\?(.*))?$/,
loader: 'file?prefix=fonts/'
},
{
test: /\.svg(\?(.*))?$/,
loader: 'file?prefix=fonts/'
},
{
test: /\.json$/,
loader: 'json'
}
]
},
resolve: {
extensions: [
'',
'.js',
'.coffee',
'.scss',
'.css'
],
root: [appRoot],
},
singleRun: true,
plugins: [
new webpack.ContextReplacementPlugin(/.*$/, /a^/),
new webpack.ProvidePlugin({
'_': 'lodash'
}),
new ExtractTextPlugin("styles/[name].[chunkhash].css", {allChunks: true}),
new HtmlWebpackPlugin({
template: appRoot + '/app.html',
filename: 'app.html',
inject: 'body',
chunks: ['app']
})
],
devtool: 'eval'
}
if(env === 'production') {
webpackConfig.plugins = webpackConfig.plugins.concat(
new ngAnnotatePlugin(),
new webpack.optimize.UglifyJsPlugin(),
new webpack.DefinePlugin({
'process-env': {
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin()
);
webpackConfig.devtool = false;
webpackConfig.debug = false;
}
return webpackConfig;
}
- 是的,您必须这样做才能从不同路径加载图像。
- 我遇到了类似的问题,我使用
file
加载器解决了这个问题:
.
loaders: [{
// JS LOADER
test: /\.js$/,
loader: 'babel-loader?optional[]=runtime',
exclude: /node_modules/
}, {
// ASSET LOADER
test: /\.(woff|woff2|ttf|eot)$/,
loader: 'file-loader'
},
{
//IMAGE LOADER
test: /\.(jpe?g|png|gif|svg)$/i,
loader:'file-loader'
},
{
// HTML LOADER
test: /\.html$/,
loader: 'html-loader'
},
{
//SCSS LOADER
test: /\.scss$/,
loaders: ["style-loader", "css-loader", "sass-loader?indentedSyntax"]
}
]
祝你好运
如果您在 Webpack 2 中使用 HTML 模板,除了使用文件加载器之外,您还需要更改 HTML:
<img src="../images/foo.png" />
到这个
<img src=<%=require("../images/foo.png")%> />
使用 Webpack 4,我可以通过 html-loader
更新来为我的文件指定 root
来解决这个问题。所以考虑到@syko 的原始结构;在 webpack.config.js
...
module: {
rules: [
// other stuff above.....
{
test: /\.html$/,
use: [
// ...The other file-loader and extract-loader go here.
{
loader: 'html-loader'
options: {
// THIS will resolve relative URLs to reference from the app/ directory
root: path.resolve(__dirname, 'app')
}
}
]
}
]
}
这告诉 html-loader
解释来自 /app
文件夹的所有 绝对 url。所以在我们的app/templates/foo.html
中,你可以使用下面的...
<img src="/images/foo.png" />
然后这告诉 html-loader
将上面的内容视为 path.resolve(__dirname, 'app', 'images', 'foo.png')
。那么如果你有extract-loader
and/orfile-loader
,所有的路径应该都是正确的。
苦苦思索了一段时间,终于得到了这个解决方案。最大的困惑是 /images/foo.png
在加载程序堆栈中的什么地方被解释,在这种情况下它从 html-loader
插件开始。之后的一切,更多的是关于如何发布图像文件。
希望对您有所帮助。
您可以使用 file-loader to extract images. Then using html-loader 您可以通过查询参数 attrs
.
我可以让它与这个配置一起工作:
{
test: /\.(jpe?g|png|gif|svg|ico)$/i,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/'
}
}]
},
{
test: /\.(html)$/,
use: {
loader: 'html-loader',
options: {
attrs: ['img:src', 'link:href']
}
}
}
或者在 angular 中是这样的:
attrs: [':ng-src', ':ng-href']
对于 Webpack 5 你必须这样写:
module: {
rules: [
// other stuff above.....
{
test: /\.html$/,
use: [
{
loader: 'html-loader'
}
]
}
]
}