Javascript Webpack:从 html 模板加载图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32753650/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:10:28  来源:igfitidea点击:

Webpack: Loading images from html templates

javascripthtmlangularjswebpack

提问by syko

I'm trying to set up an angular project using Webpack but I can't figure out how to reference images from within html templates and have them included in the build.

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

My project tree is as follows:

我的项目树如下:

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

I'm trying to use html-loaderalong with url-loaderand file-loaderbut it's just not happening.

我正在尝试使用html-loaderwith url-loaderfile-loader但它没有发生。

This is an example template: app/templates/foo.html

这是一个示例模板: app/templates/foo.html

<img src="../images/foo.png" />

Problem #1: I would like to be able to reference images relative to app/. Right now, the paths need to be relative to the template file and this will get ugly very quickly (../../../images/foo.png).

问题 #1:我希望能够引用相对于app/. 现在,路径需要相对于模板文件,这会很快变得难看 ( ../../../images/foo.png)。

Problem #2: Even if I specify the relative path, as I have done above, the project builds successfully but nothing really happens. The paths are left as-is and no images appear in dist/.

问题#2:即使我指定了相对路径,正如我上面所做的那样,项目构建成功,但实际上什么也没发生。路径保持原样,中没有图像dist/

Here is my webpack config:

这是我的 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;

}

}

采纳答案by A_J

  1. Yes, you will have to do so for loading images from different path.
  2. I had similar issue and I resolved this using fileloader:
  1. 是的,您必须这样做才能从不同路径加载图像。
  2. 我有类似的问题,我使用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"]
}
]

Good Luck

祝你好运

回答by Luis Múzquiz

If you are using HTML templates in Webpack 2, in addition to use the file-loader you need to change in your HTML:

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

<img src="../images/foo.png" />

<img src="../images/foo.png" />

to this

对此

<img src=<%=require("../images/foo.png")%> />

<img src=<%=require("../images/foo.png")%> />

回答by UsmanZ

You can use file-loaderto extract images. Then using html-loaderyou can specify which tag-attribute combination should be processed by this loader via the query parameter attrs.

您可以使用文件加载器来提取图像。然后使用html-loader您可以通过查询参数指定此加载程序应处理哪个标签-属性组合attrs

I could make it work with this configuration:

我可以使用此配置使其工作:

{
    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']
        }
    }
}

Or in angular something like this:

或者像这样的角度:

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

回答by Guy Park

With Webpack 4, I was able to solve this problem by updating by html-loaderto specify the rootfor my files. So given @syko's original structure; in webpack.config.js...

使用 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')
          }
        }
      ]
    }
  ]
}

This tells the html-loaderto interpret all absoluteurls from the /appfolder. So in our app/templates/foo.html, you can then use the following...

这告诉html-loader解释文件夹中的所有绝对url /app。因此,在我们的 中app/templates/foo.html,您可以使用以下...

<img src="/images/foo.png" />

This then tells html-loaderto see the above as path.resolve(__dirname, 'app', 'images', 'foo.png'). Then if you have extract-loaderand/or file-loader, all the paths should be correct.

这然后告诉html-loader将上述内容视为path.resolve(__dirname, 'app', 'images', 'foo.png'). 那么如果你有extract-loader和/或file-loader,所有的路径都应该是正确的。

Managed to get this solution after hammering away at it for a while. The biggest confusion is where about in the loader stack the /images/foo.pngis interpreted, in this case it starts at the html-loaderplugin. Everything else after that, is more about how the image files are to be published.

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

Hope that helps.

希望有帮助。