diff --git a/packages/optimizer/README.md b/packages/optimizer/README.md index 7ba4d530f..f77f14b6f 100644 --- a/packages/optimizer/README.md +++ b/packages/optimizer/README.md @@ -193,6 +193,8 @@ It's possible to rewrite the AMP framework and component imports to a different **Notice:** The behavior of `ampUrlPrefix` when used in conjunction with `ampRuntimeVersion` changed beginning with version 1.1.2. Prior to 1.1.2, `rtv/{rtv}/` was automatically appended to `ampUrlPrefix` when `ampRuntimeVersion` was specified. Since version 1.1.2, `ampUrlPrefix` is not modified when `ampRuntimeVersion` is also specified. +- `rewriteDynamicComponents`: When used in conjunction with `ampUrlPrefix`, this option can be set to `false` to prevent [dynamic AMP components](https://github.com/ampproject/amphtml/blob/master/spec/amp-cache-guidelines.md#guidelines-adding-a-new-cache-to-the-amp-ecosystem) from having their URLs rewritten. + Examples: ``` const ampOptimizer = require('@ampproject/toolbox-optimizer'); @@ -204,14 +206,27 @@ const originalHtml = ` ... ` -// this will rewrite https://cdn.ampproject.org/v0.js to /amp/v0.js +// this will rewrite https://cdn.ampproject.org/v0.js to /amp/v0.js and will +// rewrite dynamic component https://cdn.ampproject.org/v0/amp-geo-0.1.js to +// /amp/v0/amp-geo-0.1.js const optimizedHtmlA = await ampOptimizer.transformHtml(originalHtml, { ampUrlPrefix: '/amp' }); -// this will rewrite https://cdn.ampproject.org/v0.js to /amp/v0.js +// this will rewrite https://cdn.ampproject.org/v0.js to /amp/v0.js and will +// not rewrite dynamic component https://cdn.ampproject.org/v0/amp-geo-0.1.js const optimizedHtmlB = await ampOptimizer.transformHtml(originalHtml, { + ampUrlPrefix: '/amp', + rewriteDynamicComponents: false +}); + +// this will rewrite https://cdn.ampproject.org/v0.js to +// /amp/001515617716922/v0.js and will rewrite dynamic component +// https://cdn.ampproject.org/v0/amp-geo-0.1.js to +// https://cdn.ampproject.org/v0/rtv/001515617716922/amp-geo-0.1.js +const optimizedHtmlC = await ampOptimizer.transformHtml(originalHtml, { ampRuntimeVersion: '001515617716922', - ampUrlPrefix: '/amp' + ampUrlPrefix: '/amp/001515617716922', + rewriteDynamicComponents: false }); ``` diff --git a/packages/optimizer/lib/AmpConstants.js b/packages/optimizer/lib/AmpConstants.js index bfcbde943..f2b6e2ca8 100644 --- a/packages/optimizer/lib/AmpConstants.js +++ b/packages/optimizer/lib/AmpConstants.js @@ -18,5 +18,11 @@ module.exports = { AMP_TAGS: ['amp', '⚡', '⚡4ads'], AMP_CACHE_HOST: 'https://cdn.ampproject.org', + // Should be kept up to date with dynamic components listed here: + // https://github.com/ampproject/amphtml/blob/master/spec/amp-cache-guidelines.md#guidelines-adding-a-new-cache-to-the-amp-ecosystem + AMP_DYNAMIC_COMPONENTS: { + 'custom-element': ['amp-geo'], + 'custom-template': [], + }, appendRuntimeVersion: (prefix, version) => prefix + '/rtv/' + version, }; diff --git a/packages/optimizer/lib/transformers/RewriteAmpUrls.js b/packages/optimizer/lib/transformers/RewriteAmpUrls.js index d7005f2cb..1b0d7e5a1 100644 --- a/packages/optimizer/lib/transformers/RewriteAmpUrls.js +++ b/packages/optimizer/lib/transformers/RewriteAmpUrls.js @@ -15,13 +15,17 @@ */ 'use strict'; -const {AMP_CACHE_HOST, appendRuntimeVersion} = require('../AmpConstants.js'); +const { + AMP_CACHE_HOST, + AMP_DYNAMIC_COMPONENTS, + appendRuntimeVersion, +} = require('../AmpConstants.js'); const {findMetaViewport} = require('../HtmlDomHelper'); /** * RewriteAmpUrls - rewrites AMP runtime URLs. * - * This transformer supports two parameters: + * This transformer supports several parameters: * * * `ampRuntimeVersion`: specifies a * [specific version](https://github.com/ampproject/amp-toolbox/tree/master/runtime-version") @@ -35,9 +39,14 @@ const {findMetaViewport} = require('../HtmlDomHelper'); * URLs being re-written from `https://cdn.ampproject.org/v0.js` to * `/amp/v0.js`. This option is experimental and not recommended. * - * Both parameters are optional. If no option is provided, runtime URLs won't be - * re-written. You can combine both parameters to rewrite AMP runtime URLs - * to versioned URLs on a different origin. + * * `rewriteDynamicComponents`: optionally disable rewriting of + * [dynamically generated components](https://github.com/ampproject/amphtml/blob/master/spec/amp-cache-guidelines.md#guidelines-adding-a-new-cache-to-the-amp-ecosystem). + * For example: `https://cdn.ampproject.org/v0/amp-geo-0.1.js` returns + * different content depending on the country from which the request was made. + * + * All parameters are optional. If no option is provided, runtime URLs won't be + * re-written. You can combine `ampRuntimeVersion` and `ampUrlPrefix` to rewrite + * AMP runtime URLs to versioned URLs on a different origin. * * This transformer also adds a preload header for the AMP runtime (v0.js) to trigger HTTP/2 * push for CDNs (see https://www.w3.org/TR/preload/#server-push-(http/2)). @@ -52,13 +61,22 @@ class RewriteAmpUrls { if (params.ampRuntimeVersion && !params.ampUrlPrefix) { ampUrlPrefix = appendRuntimeVersion(ampUrlPrefix, params.ampRuntimeVersion); } + let dynamicAmpUrlPrefix = ampUrlPrefix; + if (params.rewriteDynamicComponents === false) { + dynamicAmpUrlPrefix = AMP_CACHE_HOST; + if (params.ampRuntimeVersion) { + dynamicAmpUrlPrefix = appendRuntimeVersion(dynamicAmpUrlPrefix, params.ampRuntimeVersion); + } + } let node = head.firstChild; let referenceNode = findMetaViewport(head); while (node) { if (node.tagName === 'script' && this._usesAmpCacheUrl(node.attribs.src)) { - node.attribs.src = this._replaceUrl(node.attribs.src, ampUrlPrefix); + const isDynamicComponent = this._isDynamicComponent(node); + node.attribs.src = this._replaceUrl(node.attribs.src, + isDynamicComponent ? dynamicAmpUrlPrefix : ampUrlPrefix); referenceNode = this._addPreload(tree, head, referenceNode, node.attribs.src, 'script'); } else if (node.tagName === 'link' && node.attribs.rel === 'stylesheet' && @@ -94,6 +112,16 @@ class RewriteAmpUrls { parent.insertAfter(preload, node); return preload; } + + _isDynamicComponent(script) { + if (!script || !script.attribs || script.tagName !== 'script') { + return false; + } + + return Object.keys(AMP_DYNAMIC_COMPONENTS).some((type) => { + return script.attribs[type] && AMP_DYNAMIC_COMPONENTS[type].includes(script.attribs[type]); + }); + } } module.exports = RewriteAmpUrls; diff --git a/packages/optimizer/spec/transformers/experimental/RewriteAmpUrls/rewrites_host_but_not_dynamic_components_with_rtv/expected_output.html b/packages/optimizer/spec/transformers/experimental/RewriteAmpUrls/rewrites_host_but_not_dynamic_components_with_rtv/expected_output.html new file mode 100644 index 000000000..cd3914ec8 --- /dev/null +++ b/packages/optimizer/spec/transformers/experimental/RewriteAmpUrls/rewrites_host_but_not_dynamic_components_with_rtv/expected_output.html @@ -0,0 +1,14 @@ + + +
+ + + + + + + + + + + diff --git a/packages/optimizer/spec/transformers/experimental/RewriteAmpUrls/rewrites_host_but_not_dynamic_components_with_rtv/input.html b/packages/optimizer/spec/transformers/experimental/RewriteAmpUrls/rewrites_host_but_not_dynamic_components_with_rtv/input.html new file mode 100644 index 000000000..e0c2fcbf1 --- /dev/null +++ b/packages/optimizer/spec/transformers/experimental/RewriteAmpUrls/rewrites_host_but_not_dynamic_components_with_rtv/input.html @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/packages/optimizer/spec/transformers/experimental/RewriteAmpUrls/rewrites_host_but_not_dynamic_components_without_rtv/expected_output.html b/packages/optimizer/spec/transformers/experimental/RewriteAmpUrls/rewrites_host_but_not_dynamic_components_without_rtv/expected_output.html new file mode 100644 index 000000000..e9199e329 --- /dev/null +++ b/packages/optimizer/spec/transformers/experimental/RewriteAmpUrls/rewrites_host_but_not_dynamic_components_without_rtv/expected_output.html @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/packages/optimizer/spec/transformers/experimental/RewriteAmpUrls/rewrites_host_but_not_dynamic_components_without_rtv/input.html b/packages/optimizer/spec/transformers/experimental/RewriteAmpUrls/rewrites_host_but_not_dynamic_components_without_rtv/input.html new file mode 100644 index 000000000..df1e8b111 --- /dev/null +++ b/packages/optimizer/spec/transformers/experimental/RewriteAmpUrls/rewrites_host_but_not_dynamic_components_without_rtv/input.html @@ -0,0 +1,18 @@ + + + + + + + + + + + + +