Ich versuche, ein Winkelprojekt mit Webpack einzurichten. Ich kann jedoch nicht herausfinden, wie Bilder aus HTML-Vorlagen referenziert werden und diese in den Build einbezogen werden.
Mein Projektbaum ist wie folgt:
package.json
app/
- images/
- foo.png
- scripts/
- styles/
- templates/
Ich versuche, html-loader
zusammen mit url-loader
und file-loader
zu verwenden, aber es passiert einfach nicht.
Dies ist eine Beispielvorlage: app/templates/foo.html
<img src="../images/foo.png" />
Problem # 1 : Ich möchte Bilder relativ zu app/
referenzieren können. Im Moment müssen die Pfade relativ zur Vorlagendatei sein, und dies wird sehr schnell hässlich (../../../images/foo.png
).
Problem # 2 : Auch wenn ich den relativen Pfad angegeben habe, wird das Projekt erfolgreich erstellt, aber nichts passiert wirklich. Die Pfade bleiben unverändert und es werden keine Bilder in dist/
angezeigt.
Hier ist meine Webpack-Konfiguration:
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
loader gelöst.
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"]
}
]
Viel Glück
Wenn Sie in Webpack 2 HTML-Vorlagen verwenden, müssen Sie zusätzlich zum Dateilader Folgendes in Ihrem HTML-Code ändern:
<img src="../images/foo.png" />
dazu
<img src=<%=require("../images/foo.png")%> />
Sie können File-Loader verwenden, um Bilder zu extrahieren. Anschließend können Sie mit html-loader über den Abfrageparameter attrs
angeben, welche Tag-Attribut-Kombination von diesem Loader verarbeitet werden soll.
Ich könnte es mit dieser Konfiguration funktionieren lassen:
{
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']
}
}
}
Oder im Winkel so etwas:
attrs: [':ng-src', ':ng-href']
Mit Webpack 4 konnte ich dieses Problem lösen, indem ich ein Update mit html-loader
Durchführte, um root
für meine Dateien anzugeben. So gegeben @ syko ursprüngliche Struktur; in 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')
}
}
]
}
]
}
Dies weist den html-loader
An, alle absoluten URLs aus dem Ordner /app
Zu interpretieren. In unserem app/templates/foo.html
Können Sie dann Folgendes verwenden ...
<img src="/images/foo.png" />
Dies weist dann html-loader
An, das Obige als path.resolve(__dirname, 'app', 'images', 'foo.png')
zu sehen. Wenn Sie dann extract-loader
Und/oder file-loader
Haben, sollten alle Pfade korrekt sein.
Schaffte es, diese Lösung zu bekommen, nachdem ich sie eine Weile weggehämmert hatte. Die größte Verwirrung ist, wo ungefähr im Loader-Stack der /images/foo.png
Interpretiert wird, in diesem Fall beginnt er beim html-loader
- Plugin. Alles andere danach dreht sich mehr darum, wie die Bilddateien veröffentlicht werden sollen.
Ich hoffe, das hilft.