Skip to content

Commit

Permalink
feat: better html-webpack-plugin interop in extract mode
Browse files Browse the repository at this point in the history
Now html-webpack-plugin's template context contains htmlWebpackPlugin.files.sprites property (Object<filename:string, content:string>). It can be used to inline extracted sprite content directly in page markup.
See test/fixtures/html-webpack-plugin/template.ejs for example.

ISSUES CLOSED: #194
  • Loading branch information
kisenka committed Oct 19, 2017
1 parent 06bf968 commit 8a2d63e
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 15 deletions.
20 changes: 17 additions & 3 deletions lib/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,14 @@ class SVGSpritePlugin {
loaderContext[NAMESPACE] = plugin;
});

// Replace placeholders with real URL to symbol (in modules processed by sprite-loader)
// Replace placeholders with real URL to symbol (in modules processed by svg-sprite-loader)
compilation.plugin('after-optimize-chunks', function replacePlaceholdersInModules() {
const map = new MappedList(symbols, this);
const replacements = map.groupItemsBySymbolFile((acc, item) => acc[item.resource] = item.useUrl);
map.items.forEach(item => replaceInModuleSource(item.module, replacements));
});

// Hook into extract-text-webpack-plugin event to replace placeholders with real URL to symbol
// Hook into extract-text-webpack-plugin to replace placeholders with real URL to symbol
compilation.plugin('optimize-extracted-chunks', function replacePlaceholdersInExtractedChunks(chunks) {
const map = new MappedList(symbols, this);
const replacements = map.groupItemsBySymbolFile((acc, item) => acc[item.resource] = item.useUrl);
Expand All @@ -82,7 +82,21 @@ class SVGSpritePlugin {
});
});

// Hook into html-webpack-plugin event to replace placeholders with real URL to symbol
// Hook into html-webpack-plugin to add `sprites` variable into template context
compilation.plugin('html-webpack-plugin-before-html-generation', function htmlPluginHook(htmlPluginData, done) {
const { assets } = this;
const map = new MappedList(symbols, this);
const itemsBySprite = map.groupItemsBySpriteFilename();
const sprites = Object.keys(itemsBySprite).reduce((acc, filename) => {
acc[filename] = assets[filename].source();
return acc;
}, {});

htmlPluginData.assets.sprites = sprites;
done(null, htmlPluginData);
});

// Hook into html-webpack-plugin to replace placeholders with real URL to symbol
compilation.plugin('html-webpack-plugin-before-html-processing', function htmlPluginHook(htmlPluginData, done) {
const map = new MappedList(symbols, this);
const replacements = map.groupItemsBySymbolFile((acc, item) => acc[item.resource] = item.useUrl);
Expand Down
16 changes: 16 additions & 0 deletions test/fixtures/html-webpack-plugin/template.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<% if (htmlWebpackPlugin.files.sprites) { %>
<% for (var spriteFileName in htmlWebpackPlugin.files.sprites) { %>
<%= htmlWebpackPlugin.files.sprites[spriteFileName] %>
<% } %>
<% } %>

<img src="../img/image.svg" alt="">
</body>
</html>
10 changes: 0 additions & 10 deletions test/fixtures/html-webpack-plugin/template.html

This file was deleted.

4 changes: 2 additions & 2 deletions test/loader.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,15 +258,15 @@ describe('loader and plugin', () => {
module: rules(
svgRule({ extract: true }),
rule({
test: /\.html$/,
test: /template\.ejs$/,
loader: 'html-loader'
})
),
plugins: [
new SpritePlugin(),
new HtmlPlugin({
filename: 'index.html',
template: path.resolve(fixturesPath, 'html-webpack-plugin/template.html')
template: path.resolve(fixturesPath, 'html-webpack-plugin/template.ejs')
})
]
});
Expand Down

0 comments on commit 8a2d63e

Please sign in to comment.