Skip to content

Commit

Permalink
feat: Add meta tag option
Browse files Browse the repository at this point in the history
  • Loading branch information
jantimon committed Mar 27, 2018
1 parent 7b4eb7f commit a7d37ca
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 7 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ Allowed values are as follows
|**[`templateParameters`](#)**|`{Boolean\|Object\|Function}`|``| Allows to overwrite the parameters used in the template |
|**[`inject`](#)**|`{Boolean\|String}`|`true`|`true \|\| 'head' \|\| 'body' \|\| false` Inject all assets into the given `template` or `templateContent`. When passing `true` or `'body'` all javascript resources will be placed at the bottom of the body element. `'head'` will place the scripts in the head element|
|**[`favicon`](#)**|`{String}`|``|Adds the given favicon path to the output HTML|
|**[`meta`](#)**|`{Object}`|`{}`|Allows to inject `meta`-tags. E.g. `meta: {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'}`|
|**[`minify`](#)**|`{Boolean\|Object}`|`true`|Pass [html-minifier](https://github.com/kangax/html-minifier#options-quick-reference)'s options as object to minify the output|
|**[`hash`](#)**|`{Boolean}`|`false`|If `true` then append a unique `webpack` compilation hash to all included scripts and CSS files. This is useful for cache busting|
|**[`cache`](#)**|`{Boolean}`|`true`|Emit the file only if it was changed|
Expand Down
45 changes: 38 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class HtmlWebpackPlugin {
showErrors: true,
chunks: 'all',
excludeChunks: [],
meta: {},
title: 'Webpack App',
xhtml: false
}, options);
Expand Down Expand Up @@ -179,7 +180,7 @@ class HtmlWebpackPlugin {
const html = result.html;
const assets = result.assets;
// Prepare script and link tags
const assetTags = self.generateAssetTags(assets);
const assetTags = self.generateHtmlTags(assets);
const pluginArgs = {head: assetTags.head, body: assetTags.body, plugin: self, chunks: chunks, outputName: self.childCompilationOutputName};
// Allow plugins to change the assetTag definitions
return applyPluginsAsyncWaterfall('html-webpack-plugin-alter-asset-tags', true, pluginArgs)
Expand Down Expand Up @@ -482,15 +483,44 @@ class HtmlWebpackPlugin {
return assets;
}

/**
* Generate meta tags
*/
getMetaTags () {
if (this.options.meta === false) {
return [];
}
// Make tags self-closing in case of xhtml
// Turn { "viewport" : "width=500, initial-scale=1" } into
// [{ name:"viewport" content:"width=500, initial-scale=1" }]
const selfClosingTag = !!this.options.xhtml;
const metaTagAttributeObjects = Object.keys(this.options.meta).map((metaName) => {
const metaTagContent = this.options.meta[metaName];
return (typeof metaTagContent === 'object') ? metaTagContent : {
name: metaName,
content: metaTagContent
};
});
// Turn [{ name:"viewport" content:"width=500, initial-scale=1" }] into
// the html-webpack-plugin tag structure
return metaTagAttributeObjects.map((metaTagAttributes) => {
return {
tagName: 'meta',
voidTag: true,
selfClosingTag: selfClosingTag,
attributes: metaTagAttributes
};
});
}

/**
* Injects the assets into the given html string
*/
generateAssetTags (assets) {
generateHtmlTags (assets) {
// Turn script files into script tags
const scripts = assets.js.map(scriptPath => ({
tagName: 'script',
closeTag: true,

attributes: {
type: 'text/javascript',
src: scriptPath
Expand All @@ -502,21 +532,22 @@ class HtmlWebpackPlugin {
const styles = assets.css.map(stylePath => ({
tagName: 'link',
selfClosingTag: selfClosingTag,

voidTag: true,
attributes: {
href: stylePath,
rel: 'stylesheet'
}
}));
// Injection targets
let head = [];
let head = this.getMetaTags();
let body = [];

// If there is a favicon present, add it to the head
if (assets.favicon) {
head.push({
tagName: 'link',
selfClosingTag: selfClosingTag,
voidTag: true,
attributes: {
rel: 'shortcut icon',
href: assets.favicon
Expand All @@ -541,8 +572,8 @@ class HtmlWebpackPlugin {
const htmlRegExp = /(<html[^>]*>)/i;
const headRegExp = /(<\/head\s*>)/i;
const bodyRegExp = /(<\/body\s*>)/i;
const body = assetTags.body.map(this.createHtmlTag);
const head = assetTags.head.map(this.createHtmlTag);
const body = assetTags.body.map(this.createHtmlTag.bind(this));
const head = assetTags.head.map(this.createHtmlTag.bind(this));

if (body.length) {
if (bodyRegExp.test(html)) {
Expand Down
37 changes: 37 additions & 0 deletions spec/BasicSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1300,6 +1300,43 @@ describe('HtmlWebpackPlugin', function () {
}, [/<link rel="shortcut icon" href="[^"]+\.ico">/], null, done);
});

it('adds a meta tag', function (done) {
testHtmlPlugin({
entry: path.join(__dirname, 'fixtures/index.js'),
output: {
path: OUTPUT_DIR,
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
meta: {
'viewport': {
'name': 'viewport',
'content': 'width=device-width, initial-scale=1, shrink-to-fit=no'
}
}
})
]
}, [/<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">/], null, done);
});

it('adds a meta tag with short notation', function (done) {
testHtmlPlugin({
entry: path.join(__dirname, 'fixtures/index.js'),
output: {
path: OUTPUT_DIR,
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
meta: {
'viewport': 'width=device-width, initial-scale=1, shrink-to-fit=no'
}
})
]
}, [/<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">/], null, done);
});

it('adds a favicon with publicPath set to /some/', function (done) {
testHtmlPlugin({
entry: path.join(__dirname, 'fixtures/index.js'),
Expand Down

0 comments on commit a7d37ca

Please sign in to comment.