web-dev-qa-db-ja.com

Webpack:HTMLテンプレートから画像をロードする

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" />

問題#1app/に関連する画像を参照できるようにしたいと思います。現時点では、パスはテンプレートファイルに相対的である必要があり、これは非常に早くquicklyくなります(../../../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;

}

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

がんばろう

18
A_J

Webpack 2でHTMLテンプレートを使用している場合、ファイルローダーを使用することに加えて、HTMLを変更する必要があります。

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

これに

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

22
Luis Múzquiz

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

またはangularのようなもの:

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

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フォルダーからのすべての絶対 URLを解釈するよう/appに指示します。 app/templates/foo.htmlでは、次を使用できます...

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

次に、これはhtml-loaderに上記をpath.resolve(__dirname, 'app', 'images', 'foo.png')として見るように伝えます。その後、extract-loaderfile-loaderがあれば、すべてのパスが正しいはずです。

しばらくそれを打ちのめした後、なんとかこのソリューションを手に入れました。最大の混乱は、ローダースタックで/images/foo.pngが解釈される場所です。この場合、html-loaderプラグインで開始されます。その後のすべては、画像ファイルの公開方法に関するものです。

お役に立てば幸いです。

1
Guy Park