diff --git a/README.md b/README.md index a3c66f8..1533034 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,23 @@ plugins: [ ] ``` +All scripts are preloaded with a ```crossorigin``` attribute set to enable CDN's: +```javascript +plugins: [ + new HtmlWebpackPlugin(), + new ScriptExtHtmlWebpackPlugin({ + custom { + test: /\.js$/, + attribute: 'crossorigin' + value: 'anonymous' + } + preload: { + test: /\.js$/ + } + }) +] +``` + All asynchronous scripts are added as `preload` resource hints. All other scripts are `async`: ```javascript plugins: [ @@ -285,6 +302,7 @@ Possibly a more compelling use case is to preload/prefetch dynamically loaded sc Notes: +- custom attributes will be added to resource hints with the same *script matching pattern*. This is useful for adding such attributes as ```crossorigin="anonymous"``` - see the Configuration Examples above; - for more on resource hints, see the [`w3c`](https://www.w3.org/TR/resource-hints) definition; - for a more complete solution that allows the preloading\fetching of assets other than scripts, see the [resource-hints-webpack-plugin](https://github.com/jantimon/resource-hints-webpack-plugin). @@ -293,6 +311,9 @@ Notes: Change History -------------- +v2.1.x +* custom attributes now added to resource hints too (see [pull request 53](https://github.com/numical/script-ext-html-webpack-plugin/pull/53) for discussion) + v2.0.x * support html-webpack-plugin 4.x - huge thanks to [@snadn](https://github.com/snadn) * support webpack 4.x - huge thanks to [@sherlock1982](https://github.com/sherlock1982) diff --git a/lib/common.js b/lib/common.js index cfea95c..8be364a 100644 --- a/lib/common.js +++ b/lib/common.js @@ -5,9 +5,27 @@ const separator = '/'; const isScript = (tag) => tag.tagName === 'script'; -const hasScriptName = tag => tag.attributes && tag.attributes.src; +const isResourceLink = (tag) => tag.tagName === 'link' && tag.attributes && tag.attributes.as === 'script'; -const getRawScriptName = tag => (tag.attributes && tag.attributes.src) || ''; +const hasScriptName = tag => { + if (isScript(tag)) { + return tag.attributes && tag.attributes.src; + } else if (isResourceLink(tag)) { + return tag.attributes && tag.attributes.href; + } else { + return false; + } +}; + +const getRawScriptName = tag => { + if (isScript(tag)) { + return (tag.attributes && tag.attributes.src) || ''; + } else if (isResourceLink(tag)) { + return (tag.attributes && tag.attributes.href) || ''; + } else { + return ''; + } +}; const getPublicPath = options => { const output = options.compilationOptions.output; @@ -47,6 +65,7 @@ module.exports = { getRawScriptName, getScriptName, hasScriptName, + isResourceLink, isScript, matches }; diff --git a/lib/custom-attributes.js b/lib/custom-attributes.js index 86f72c0..6459edf 100644 --- a/lib/custom-attributes.js +++ b/lib/custom-attributes.js @@ -5,6 +5,7 @@ const CONSTANTS = require('./constants.js'); const common = require('./common.js'); const debug = common.debug; const getScriptName = common.getScriptName; +const isResourceLink = common.isResourceLink; const isScript = common.isScript; const matches = common.matches; @@ -18,7 +19,7 @@ const add = (options, tags) => { }; const updateElement = (options, tag) => { - return (isScript(tag)) + return (isScript(tag) || isResourceLink(tag)) ? updateScriptElement(options, tag) : tag; }; diff --git a/lib/elements.js b/lib/elements.js index e32ce4f..90a3b58 100644 --- a/lib/elements.js +++ b/lib/elements.js @@ -6,6 +6,7 @@ const ATTRIBUTE_PRIORITIES = [SYNC, 'async', 'defer']; const common = require('./common.js'); const debug = common.debug; +const isScript = common.isScript; const matches = common.matches; const getScriptName = common.getScriptName; @@ -31,8 +32,6 @@ const updateElement = (assets, options, tag) => { : tag; }; -const isScript = (tag) => tag.tagName === 'script'; - const updateScriptElement = (assets, options, tag) => { debug(`${CONSTANTS.EVENT}: processing