【问题标题】:Webpack: Loading images from html templatesWebpack:从 html 模板加载图像
【发布时间】:2015-12-21 14:27:03
【问题描述】:

我正在尝试使用 Webpack 设置 Angular 项目,但我不知道如何从 html 模板中引用图像并将它们包含在构建中。

我的项目树如下:

package.json
app/
- images/
  - foo.png
- scripts/
- styles/
- templates/

我正在尝试将html-loaderurl-loaderfile-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;

}

【问题讨论】:

  • 你是如何解决问题 #1 的?

标签: javascript html angularjs webpack


【解决方案1】:

如果您在 Webpack 2 中使用 HTML 模板,除了使用文件加载器之外,您还需要在 HTML 中进行更改:

&lt;img src="../images/foo.png" /&gt;

到这里

&lt;img src=&lt;%=require("../images/foo.png")%&gt; /&gt;

【讨论】:

  • 如果我以前有 -m.png"/> 怎么办?如何动态导入?
  • 结果:&lt;img src="[object" module]="",或带引号的&lt;img src="[object Module]"
  • @ArthurShlain &lt;img src=&lt;%=require("../images/foo.png").default%&gt; /&gt; 引用 .default 到方法调用。见stackoverflow.com/questions/59070216/…
  • URIError: 无法解码参数'/%3C%=require(%22../assets/eotpeccy.png%22).default%'
【解决方案2】:
  1. 是的,您必须这样做才能从不同的路径加载图像。
  2. 我遇到了类似的问题,我使用file loader 解决了这个问题:

.

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"]
}
]

祝你好运

【讨论】:

  • 在使用加载器时不再允许省略'-loader'后缀。您需要指定“文件加载器”而不是“文件”。
  • 不确定这如何解决@syko 的问题,因为它看起来与他的设置相同。是否有任何file-loader 选项可以让 html 文件简单地引用一个公共参考点(即使@syko app 文件夹也是一个开始),所以可以做&lt;img src="./images/foo.png"&gt;,因为图像的目录结构不太可能改变比许多模板文件。 Luis 在下面的回答是最正确的,因为模块别名也可以使用,但是在 require 中添加看起来很难看,也不是很直观。
  • @GuyPark 如果您想要使用文件加载器与&lt;img src="./images/foo.png"&gt; 等效,您可以从 .js 文件中导入图像并通过原始 javascript 代码将其添加到模板中。
  • 一个不错的接触,但不幸的是这是一个从 [authenticated] API 服务加载的动态图像,所以它有点棘手,否则我会。 :)
【解决方案3】:

对于 Webpack 5,你必须这样写:

module: {
  rules: [
    // other stuff above.....
    {
      test: /\.html$/,
      use: [
        {
          loader: 'html-loader'
        }
      ]
    }
  ]
}

【讨论】:

【解决方案4】:

使用 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 和/或file-loader,那么所有的路径都应该是正确的。

经过一段时间的努力,设法得到了这个解决方案。最大的困惑是在加载程序堆栈中/images/foo.png 被解释的位置,在这种情况下,它从html-loader 插件开始。之后的一切,更多的是关于如何发布图像文件。

希望对您有所帮助。

【讨论】:

  • 除了以上url-loader需要通过选项esModule: false禁用es6模块
  • 知道什么是 webpack 5 的替代品吗?
  • 抱歉不能说。仅在使用它的旧项目(不再维护)上需要它。
【解决方案5】:

您可以使用file-loader 提取图像。然后使用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']
        }
    }
}

或者像这样的角度:

attrs: [':ng-src', ':ng-href']

【讨论】:

    猜你喜欢
    • 2018-12-26
    • 2017-03-23
    • 2019-05-04
    • 2016-05-25
    • 2017-08-15
    • 2023-03-19
    • 2020-11-24
    • 2015-04-07
    • 1970-01-01
    相关资源
    最近更新 更多