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/
に関連する画像を参照できるようにしたいと思います。現時点では、パスはテンプレートファイルに相対的である必要があり、これは非常に早く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;
}
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")%> />
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']
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-loader
やfile-loader
があれば、すべてのパスが正しいはずです。
しばらくそれを打ちのめした後、なんとかこのソリューションを手に入れました。最大の混乱は、ローダースタックで/images/foo.png
が解釈される場所です。この場合、html-loader
プラグインで開始されます。その後のすべては、画像ファイルの公開方法に関するものです。
お役に立てば幸いです。