script-ext-html-webpack-plugin
Advanced tools
Comparing version 1.0.1 to 1.1.0
99
index.js
@@ -5,2 +5,3 @@ 'use strict'; | ||
const ATTRIBUTE_PRIORITIES = [SYNC, 'async', 'defer']; | ||
const MODULE = 'module'; | ||
const DEFAULT_OPTIONS = { | ||
@@ -10,3 +11,4 @@ sync: [], | ||
defer: [], | ||
defaultAttribute: SYNC | ||
defaultAttribute: SYNC, | ||
module: [] | ||
}; | ||
@@ -16,59 +18,64 @@ const SCRIPT_PATTERN = new RegExp('(<script.*?><\/script>)', 'gi'); | ||
function setScriptAttributes (options, htmlPluginData, callback) { | ||
if (options.defaultAttribute === SYNC && | ||
options.async.length === 0 && | ||
options.defer.length === 0 && | ||
options.module === 0) { | ||
return callback(null, htmlPluginData); | ||
} | ||
if (ATTRIBUTE_PRIORITIES.indexOf(options.defaultAttribute) < 0) { | ||
throw new Error('ScriptExtHtmlWebpackPlugin: invalid default attribute'); | ||
} | ||
htmlPluginData.html = htmlPluginData.html.replace(SCRIPT_PATTERN, (scriptElement) => { | ||
const scriptName = SRC_PATTERN.exec(scriptElement)[1]; | ||
const attribute = generateScriptAttribute(options, scriptName); | ||
return '<script src="' + scriptName + '"' + attribute + '></script>'; | ||
}); | ||
callback(null, htmlPluginData); | ||
} | ||
function generateScriptAttribute (options, scriptName) { | ||
let scriptAttributes = null; | ||
ATTRIBUTE_PRIORITIES.forEach((attribute) => { | ||
if (scriptAttributes === null && matches(scriptName, options[attribute])) { | ||
scriptAttributes = attribute; | ||
} | ||
}); | ||
if (scriptAttributes === null) { | ||
scriptAttributes = options.defaultAttribute; | ||
} | ||
if (scriptAttributes === SYNC) { | ||
scriptAttributes = ''; | ||
} else { | ||
scriptAttributes = ' ' + scriptAttributes; | ||
} | ||
if (matches(scriptName, options[MODULE])) { | ||
scriptAttributes = scriptAttributes + ' type="module"'; | ||
} | ||
return scriptAttributes; | ||
} | ||
function matches (scriptName, patterns) { | ||
return patterns.some((pattern) => { | ||
if (pattern instanceof RegExp) { | ||
return pattern.test(scriptName); | ||
} else { | ||
return scriptName.indexOf(pattern) > -1; | ||
} | ||
}); | ||
} | ||
class ScriptExtHtmlWebpackPlugin { | ||
constructor (options) { | ||
this.options = Object.assign({}, DEFAULT_OPTIONS, options); | ||
} | ||
apply (compiler) { | ||
compiler.plugin('compilation', (compilation) => { | ||
compilation.plugin('html-webpack-plugin-after-html-processing', (htmlPluginData, callback) => { | ||
this.setScriptAttributes(htmlPluginData, callback); | ||
setScriptAttributes(this.options, htmlPluginData, callback); | ||
}); | ||
}); | ||
} | ||
setScriptAttributes (htmlPluginData, callback) { | ||
if (this.options.defaultAttribute === SYNC && | ||
this.options.async.length === 0 && | ||
this.options.defer.length === 0) { | ||
return callback(null, htmlPluginData); | ||
} | ||
if (ATTRIBUTE_PRIORITIES.indexOf(this.options.defaultAttribute) < 0) { | ||
throw new Error('ScriptExtHtmlWebpackPlugin: invalid default attribute'); | ||
} | ||
htmlPluginData.html = htmlPluginData.html.replace(SCRIPT_PATTERN, (scriptElement) => { | ||
const scriptName = SRC_PATTERN.exec(scriptElement)[1]; | ||
const attribute = this.generateScriptAttribute(scriptName); | ||
return '<script src="' + scriptName + '"' + attribute + '></script>'; | ||
}); | ||
callback(null, htmlPluginData); | ||
} | ||
generateScriptAttribute (scriptName) { | ||
let scriptAttribute = null; | ||
ATTRIBUTE_PRIORITIES.forEach((attribute) => { | ||
if (scriptAttribute === null && | ||
this.options[attribute].some((pattern) => { | ||
if (pattern instanceof RegExp) { | ||
return pattern.test(scriptName); | ||
} else { | ||
return scriptName.indexOf(pattern) > -1; | ||
} | ||
})) { | ||
scriptAttribute = attribute; | ||
} | ||
}); | ||
if (scriptAttribute === null) { | ||
scriptAttribute = this.options.defaultAttribute; | ||
} | ||
if (scriptAttribute === SYNC) { | ||
scriptAttribute = ''; | ||
} else { | ||
scriptAttribute = ' ' + scriptAttribute; | ||
} | ||
return scriptAttribute; | ||
} | ||
} | ||
module.exports = ScriptExtHtmlWebpackPlugin; |
{ | ||
"name": "script-ext-html-webpack-plugin", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"description": "Enhances html-webpack-plugin functionality with async and defer attributes for script elements", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -9,3 +9,3 @@ Script Extension for HTML Webpack Plugin | ||
Enhances [html-webpack-plugin](https://github.com/ampedandwired/html-webpack-plugin) | ||
functionality with `async` and `defer` attributes for `<script>` elements. | ||
functionality with `async`,`defer` and `type="module"` attributes for `<script>` elements. | ||
@@ -64,3 +64,5 @@ This is an extension plugin for the [webpack](http://webpack.github.io) plugin [html-webpack-plugin](https://github.com/ampedandwired/html-webpack-plugin) - a plugin that simplifies the creation of HTML files to serve your webpack bundles. | ||
- `defer`: array of `String`'s and/or `RegExp`'s defining script names that should have a `defer` attribute (default: `[]`); | ||
- `defaultAttribute`: `'sync' | 'async' | 'defer'` The default attribute to set - `'sync'` actually results in no attribute (default: `'sync'`). | ||
- `defaultAttribute`: `'sync' | 'async' | 'defer'` The default attribute to set - `'sync'` actually results in no attribute (default: `'sync'`); | ||
- `module`: array of `String`'s and/or `RegExp`'s defining script names that should have a | ||
`type="module"` attribute (default: `[]`). | ||
@@ -80,2 +82,4 @@ In the arrays a `String` value matches if it is a substring of the script name. | ||
The `module` attribute is independent of these rules. | ||
Some Examples: | ||
@@ -105,2 +109,13 @@ | ||
All scripts with 'mod' in their name are async and type 'module', all others are sync (no explicit setting for this as it is the default): | ||
```javascript | ||
plugins: [ | ||
new HtmlWebpackPlugin(), | ||
new ScriptExtHtmlWebpackPlugin({ | ||
async: ['mod'], | ||
module: ['mod'] | ||
}) | ||
] | ||
``` | ||
And so on, to craziness: | ||
@@ -113,2 +128,3 @@ ```javascript | ||
defer: ['slow', /big.*andslow/], | ||
module: [/^((?!sync).)*/, 'mod'] | ||
defaultAttribute: 'async' | ||
@@ -115,0 +131,0 @@ }) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
9711
72
132