diff --git a/examples/angular/sample-app/src/index.html b/examples/angular/sample-app/src/index.html index e8a0b3be54..a7f0a86d54 100644 --- a/examples/angular/sample-app/src/index.html +++ b/examples/angular/sample-app/src/index.html @@ -7,17 +7,37 @@ diff --git a/examples/integrations/Ninetailed/sample-apps/app-using-v3-cdn/public/index.html b/examples/integrations/Ninetailed/sample-apps/app-using-v3-cdn/public/index.html index ecd1f5ee4f..043c285c6c 100644 --- a/examples/integrations/Ninetailed/sample-apps/app-using-v3-cdn/public/index.html +++ b/examples/integrations/Ninetailed/sample-apps/app-using-v3-cdn/public/index.html @@ -26,22 +26,27 @@ --> React App diff --git a/examples/nextjs/hooks/sample-app/src/app/layout.tsx b/examples/nextjs/hooks/sample-app/src/app/layout.tsx index d4c5004496..bca118c26a 100644 --- a/examples/nextjs/hooks/sample-app/src/app/layout.tsx +++ b/examples/nextjs/hooks/sample-app/src/app/layout.tsx @@ -16,20 +16,40 @@ export default function RootLayout({ children }: { children: React.ReactNode }) {children} diff --git a/examples/nextjs/js/sample-app/src/app/layout.js b/examples/nextjs/js/sample-app/src/app/layout.js index 642852dba9..246bc19299 100644 --- a/examples/nextjs/js/sample-app/src/app/layout.js +++ b/examples/nextjs/js/sample-app/src/app/layout.js @@ -15,20 +15,40 @@ export default function RootLayout({ children }) { {children} diff --git a/examples/nextjs/page-router/sample-app/src/pages/_document.tsx b/examples/nextjs/page-router/sample-app/src/pages/_document.tsx index ae9cfb8cc2..adac8327f5 100644 --- a/examples/nextjs/page-router/sample-app/src/pages/_document.tsx +++ b/examples/nextjs/page-router/sample-app/src/pages/_document.tsx @@ -7,20 +7,40 @@ export default function Document() { diff --git a/examples/nextjs/ts/sample-app/src/app/layout.tsx b/examples/nextjs/ts/sample-app/src/app/layout.tsx index b2a6ca53c7..bca118c26a 100644 --- a/examples/nextjs/ts/sample-app/src/app/layout.tsx +++ b/examples/nextjs/ts/sample-app/src/app/layout.tsx @@ -16,34 +16,40 @@ export default function RootLayout({ children }: { children: React.ReactNode }) {children} diff --git a/examples/reactjs/hooks/sample-app/public/index.html b/examples/reactjs/hooks/sample-app/public/index.html index 6c8d748b95..1529b27531 100644 --- a/examples/reactjs/hooks/sample-app/public/index.html +++ b/examples/reactjs/hooks/sample-app/public/index.html @@ -26,18 +26,37 @@ --> React App diff --git a/examples/reactjs/js/sample-app/public/index.html b/examples/reactjs/js/sample-app/public/index.html index 115c24b270..1529b27531 100644 --- a/examples/reactjs/js/sample-app/public/index.html +++ b/examples/reactjs/js/sample-app/public/index.html @@ -26,31 +26,37 @@ --> React App diff --git a/examples/reactjs/ts/sample-app/public/index.html b/examples/reactjs/ts/sample-app/public/index.html index 115c24b270..1529b27531 100644 --- a/examples/reactjs/ts/sample-app/public/index.html +++ b/examples/reactjs/ts/sample-app/public/index.html @@ -26,31 +26,37 @@ --> React App diff --git a/examples/reactjs/vite/sample-app/index.html b/examples/reactjs/vite/sample-app/index.html index cefef9df63..96169faf2b 100644 --- a/examples/reactjs/vite/sample-app/index.html +++ b/examples/reactjs/vite/sample-app/index.html @@ -6,17 +6,37 @@ Vite + React + TS diff --git a/examples/v3-beacon/index.html b/examples/v3-beacon/index.html index d4209b14cd..a833f6db44 100644 --- a/examples/v3-beacon/index.html +++ b/examples/v3-beacon/index.html @@ -4,72 +4,95 @@ - RudderStack JS SDK v3 Beacon Example + RudderStack JS SDK v3 Example diff --git a/examples/v3-legacy-minimum-plugins/index.html b/examples/v3-legacy-minimum-plugins/index.html index 38ed1b1bdc..1aefa69c1c 100644 --- a/examples/v3-legacy-minimum-plugins/index.html +++ b/examples/v3-legacy-minimum-plugins/index.html @@ -8,68 +8,91 @@ diff --git a/examples/v3-legacy/index.html b/examples/v3-legacy/index.html index 394e5e5abb..09881a6bf5 100644 --- a/examples/v3-legacy/index.html +++ b/examples/v3-legacy/index.html @@ -8,64 +8,87 @@ diff --git a/examples/v3-minimum-plugins/index.html b/examples/v3-minimum-plugins/index.html index 32c4e9459b..43dc983e1d 100644 --- a/examples/v3-minimum-plugins/index.html +++ b/examples/v3-minimum-plugins/index.html @@ -8,68 +8,91 @@ diff --git a/examples/v3/index.html b/examples/v3/index.html index 172b5565a4..1937c00e2c 100644 --- a/examples/v3/index.html +++ b/examples/v3/index.html @@ -8,64 +8,87 @@ diff --git a/packages/analytics-js-common/src/services/ExternalSrcLoader/jsFileLoader.ts b/packages/analytics-js-common/src/services/ExternalSrcLoader/jsFileLoader.ts index 08d5e17b52..b25f87b9de 100644 --- a/packages/analytics-js-common/src/services/ExternalSrcLoader/jsFileLoader.ts +++ b/packages/analytics-js-common/src/services/ExternalSrcLoader/jsFileLoader.ts @@ -33,12 +33,13 @@ const createScriptElement = ( scriptElement.src = url; scriptElement.id = id; scriptElement.async = async; - scriptElement.setAttribute('data-append-origin', EXTERNAL_SOURCE_LOAD_ORIGIN); Object.keys(extraAttributes).forEach(attributeName => { scriptElement.setAttribute(attributeName, extraAttributes[attributeName] as string); }); + scriptElement.setAttribute('data-loader', EXTERNAL_SOURCE_LOAD_ORIGIN); + return scriptElement; }; diff --git a/packages/analytics-js/public/index-legacy-only.html b/packages/analytics-js/public/index-legacy-only.html deleted file mode 100644 index 72b527a2fb..0000000000 --- a/packages/analytics-js/public/index-legacy-only.html +++ /dev/null @@ -1,308 +0,0 @@ - - - - - - -

Test HTML file

-
- - - - - - - -

-

- - - - diff --git a/packages/analytics-js/public/index.html b/packages/analytics-js/public/index.html index f57a0d76cb..26a7f56dab 100644 --- a/packages/analytics-js/public/index.html +++ b/packages/analytics-js/public/index.html @@ -2,147 +2,152 @@ diff --git a/packages/loading-scripts/rollup.config.mjs b/packages/loading-scripts/rollup.config.mjs index 68d52d59c5..96e1c465c0 100644 --- a/packages/loading-scripts/rollup.config.mjs +++ b/packages/loading-scripts/rollup.config.mjs @@ -3,6 +3,9 @@ import replace from '@rollup/plugin-replace'; import terser from '@rollup/plugin-terser'; import typescript from 'rollup-plugin-typescript2'; import { DEFAULT_EXTENSIONS } from '@babel/core'; +import htmlTemplate from 'rollup-plugin-generate-html-template'; +import livereload from 'rollup-plugin-livereload'; +import serve from 'rollup-plugin-serve'; import * as dotenv from 'dotenv'; dotenv.config(); @@ -14,6 +17,7 @@ const shouldUglify = process.env.UGLIFY === 'true'; export function getDefaultConfig(distName) { const version = process.env.VERSION || 'dev-snapshot'; + const isLocalServerEnabled = process.env.DEV_SERVER; return { watch: { @@ -85,7 +89,25 @@ export function getDefaultConfig(distName) { toplevel: true, safari10: true, } : false, - }) + }), + isLocalServerEnabled && + htmlTemplate({ + template: process.env.TEST_FILE_PATH || 'public/index.html', + target: 'index.html', + addToHead: true + }), + isLocalServerEnabled && + serve({ + open: true, + openPage: `/index.html`, + contentBase: ['dist'], + host: 'localhost', + port: 3001, + headers: { + 'Access-Control-Allow-Origin': '*', + }, + }), + isLocalServerEnabled && livereload(), ], }; } diff --git a/packages/loading-scripts/src/index.ts b/packages/loading-scripts/src/index.ts index 859372a987..311e2ce017 100644 --- a/packages/loading-scripts/src/index.ts +++ b/packages/loading-scripts/src/index.ts @@ -1,10 +1,4 @@ -/* eslint-disable no-new */ -/* eslint-disable @typescript-eslint/no-implied-eval */ -/* eslint-disable unicorn/no-for-loop */ -/* eslint-disable func-names */ /* eslint-disable prefer-rest-params */ -/* eslint-disable unicorn/consistent-destructuring */ - /* Loading snippet start */ import type { PreloadedEventCall, @@ -13,94 +7,136 @@ import type { } from '@rudderstack/analytics-js'; window.RudderSnippetVersion = '__PACKAGE_VERSION__'; -const sdkBaseUrl = 'https://cdn.rudderlabs.com/v3'; -const sdkName = 'rsa.min.js'; -const asyncScript = true; -window.rudderAnalyticsBuildType = 'legacy'; - -(window.rudderanalytics as unknown as PreloadedEventCall[]) = []; -const methods: string[] = [ - 'setDefaultInstanceKey', - 'load', - 'ready', - 'page', - 'track', - 'identify', - 'alias', - 'group', - 'reset', - 'setAnonymousId', - 'startSession', - 'endSession', - 'consent', -]; - -for (let i = 0; i < methods.length; i++) { - const method = methods[i] as string; - (window.rudderanalytics as unknown as RudderAnalyticsPreloader)[method] = (methodName => - function () { - (window.rudderanalytics as unknown as PreloadedEventCall[]).push( - [methodName].concat(Array.prototype.slice.call(arguments) as PreloadedEventCall), - ); - })(method); +const identifier = 'rudderanalytics'; +if (!window[identifier]) { + window[identifier] = [] as any; } +const rudderanalytics = window[identifier]; -// Feature detection of dynamic imports -try { - new Function('return import("")'); - window.rudderAnalyticsBuildType = 'modern'; -} catch (e) { - // Do nothing -} +// Proceed to load the SDK only if it is not already loaded +if (Array.isArray(rudderanalytics)) { + if ((rudderanalytics as any).snippetExecuted === true && window.console && console.error) { + console.error('RudderStack JavaScript SDK snippet included more than once.'); + } else { + (rudderanalytics as any).snippetExecuted = true; + window.rudderAnalyticsBuildType = 'legacy'; -window.rudderAnalyticsMount = () => { - /* eslint-disable */ - // globalThis polyfill as polyfill-fastly.io one does not work in legacy safari - if (typeof globalThis === 'undefined') { - Object.defineProperty(Object.prototype, '__globalThis_magic__', { - get: function get() { - return this; - }, - configurable: true, - }); - // @ts-ignore - __globalThis_magic__.globalThis = __globalThis_magic__; - // @ts-ignore - delete Object.prototype.__globalThis_magic__; - } - /* eslint-disable */ + const sdkBaseUrl = 'https://cdn.rudderlabs.com/v3'; + const sdkName = 'rsa.min.js'; + const scriptLoadingMode = 'async'; // Options: 'async', 'defer', 'none'/'' (empty string) - const rudderAnalyticsScript = document.createElement('script'); - rudderAnalyticsScript.src = `${sdkBaseUrl}/${window.rudderAnalyticsBuildType}/${sdkName}`; - rudderAnalyticsScript.async = asyncScript; - if (document.head) { - document.head.appendChild(rudderAnalyticsScript); - } else { - document.body.appendChild(rudderAnalyticsScript); - } -}; - -if (typeof Promise === 'undefined' || typeof globalThis === 'undefined') { - const rudderAnalyticsPromisesScript = document.createElement('script'); - rudderAnalyticsPromisesScript.src = - 'https://polyfill-fastly.io/v3/polyfill.min.js?version=3.111.0&features=Symbol%2CPromise&callback=rudderAnalyticsMount'; - rudderAnalyticsPromisesScript.async = asyncScript; - if (document.head) { - document.head.appendChild(rudderAnalyticsPromisesScript); - } else { - document.body.appendChild(rudderAnalyticsPromisesScript); - } -} else { - window.rudderAnalyticsMount(); -} -/* Loading snippet end */ + const methods: string[] = [ + 'setDefaultInstanceKey', + 'load', + 'ready', + 'page', + 'track', + 'identify', + 'alias', + 'group', + 'reset', + 'setAnonymousId', + 'startSession', + 'endSession', + 'consent', + ]; + + // eslint-disable-next-line unicorn/no-for-loop + for (let i = 0; i < methods.length; i++) { + const method = methods[i] as string; + (rudderanalytics as unknown as RudderAnalyticsPreloader)[method] = (methodName => + // eslint-disable-next-line func-names + function () { + if (Array.isArray(window[identifier])) { + (rudderanalytics as unknown as PreloadedEventCall[]).push( + [methodName].concat(Array.prototype.slice.call(arguments) as PreloadedEventCall), + ); + } else { + (window[identifier] as any)[methodName]?.apply(window[identifier], arguments); + } + })(method); + } + + // Feature detection of dynamic imports + try { + // eslint-disable-next-line no-new, @typescript-eslint/no-implied-eval + new Function('return import("")'); + window.rudderAnalyticsBuildType = 'modern'; + } catch (e) { + // Do nothing + } -const loadOptions = { - // configure your load options here -}; + const head = document.head || document.getElementsByTagName('head')[0]; -(window.rudderanalytics as unknown as RudderAnalytics).load( - '', - '', - loadOptions, -); + // eslint-disable-next-line compat/compat + const body = document.body || document.getElementsByTagName('body')[0]; + + window.rudderAnalyticsAddScript = ( + url: string, + extraAttributeKey?: string, + extraAttributeVal?: string, + ) => { + const scriptTag = document.createElement('script'); + scriptTag.src = url; + scriptTag.setAttribute('data-loader', 'RS_JS_SDK'); + if (extraAttributeKey && extraAttributeVal) { + scriptTag.setAttribute(extraAttributeKey, extraAttributeVal); + } + + if (scriptLoadingMode === 'async') { + scriptTag.async = true; + } else if (scriptLoadingMode === 'defer') { + scriptTag.defer = true; + } + + if (head) { + head.insertBefore(scriptTag, head.firstChild); + } else { + body.insertBefore(scriptTag, body.firstChild); + } + }; + + window.rudderAnalyticsMount = () => { + /* eslint-disable */ + // globalThis polyfill as polyfill-fastly.io one does not work in legacy safari + if (typeof globalThis === 'undefined') { + Object.defineProperty(Object.prototype, '__globalThis_magic__', { + get: function get() { + return this; + }, + configurable: true, + }); + // @ts-ignore + __globalThis_magic__.globalThis = __globalThis_magic__; + // @ts-ignore + delete Object.prototype.__globalThis_magic__; + } + /* eslint-enable */ + + window.rudderAnalyticsAddScript( + `${sdkBaseUrl}/${window.rudderAnalyticsBuildType}/${sdkName}`, + 'data-rsa-write-key', + '__WRITE_KEY__', + ); + }; + + if (typeof Promise === 'undefined' || typeof globalThis === 'undefined') { + window.rudderAnalyticsAddScript( + 'https://polyfill-fastly.io/v3/polyfill.min.js?version=3.111.0&features=Symbol%2CPromise&callback=rudderAnalyticsMount', + ); + } else { + window.rudderAnalyticsMount(); + } + /* Loading snippet end */ + + const loadOptions = { + // configure your load options here + }; + + (rudderanalytics as unknown as RudderAnalytics).load( + '__WRITE_KEY__', + '__DATAPLANE_URL__', + loadOptions, + ); + } +} diff --git a/packages/loading-scripts/src/types/rudderanalytics.d.ts b/packages/loading-scripts/src/types/rudderanalytics.d.ts index 3d06353f2b..841e99d66a 100644 --- a/packages/loading-scripts/src/types/rudderanalytics.d.ts +++ b/packages/loading-scripts/src/types/rudderanalytics.d.ts @@ -10,5 +10,10 @@ declare global { rudderAnalyticsMount: () => void; rudderAnalyticsBuildType: 'legacy' | 'modern'; RudderSnippetVersion?: string; + rudderAnalyticsAddScript: ( + url: string, + extraAttributeKey?: string, + extraAttributeVal?: string, + ) => void; } } diff --git a/packages/sanity-suite/project.json b/packages/sanity-suite/project.json index f5574f3c9a..04f602e881 100644 --- a/packages/sanity-suite/project.json +++ b/packages/sanity-suite/project.json @@ -11,14 +11,14 @@ "options": { "jestConfig": "packages/sanity-suite/jest.config.mjs", "passWithNoTests": true, - "codeCoverage": true, + "codeCoverage": false, "watchAll": false, "forceExit": true }, "configurations": { "ci": { "ci": true, - "codeCoverage": true + "codeCoverage": false } } }, diff --git a/packages/sanity-suite/public/v3/index-cdn.html b/packages/sanity-suite/public/v3/index-cdn.html index be12d74d56..a238295e28 100644 --- a/packages/sanity-suite/public/v3/index-cdn.html +++ b/packages/sanity-suite/public/v3/index-cdn.html @@ -21,113 +21,121 @@ }, }; window.OnetrustActiveGroups = ',C0001,C0003,'; + - window.RudderSnippetVersion = '3.0.1'; - var sdkBaseUrl = 'https://cdn.rudderlabs.com/__CDN_VERSION_PATH__'; - var sdkName = 'rsa.min.js'; - var asyncScript = true; - window.rudderAnalyticsBuildType = 'legacy'; - window.rudderanalytics = []; - var methods = [ - 'setDefaultInstanceKey', - 'load', - 'ready', - 'page', - 'track', - 'identify', - 'alias', - 'group', - 'reset', - 'setAnonymousId', - 'startSession', - 'endSession', - 'consent', - ]; - for (var i = 0; i < methods.length; i++) { - var method = methods[i]; - window.rudderanalytics[method] = (function (methodName) { - return function () { - window.rudderanalytics.push([methodName].concat(Array.prototype.slice.call(arguments))); - }; - })(method); - } - try { - new Function('return import("")'); - window.rudderAnalyticsBuildType = 'modern'; - } catch (e) {} - window.rudderAnalyticsMount = function () { - if (typeof globalThis === 'undefined') { - Object.defineProperty(Object.prototype, '__globalThis_magic__', { - get: function get() { - return this; - }, - configurable: true, - }); - __globalThis_magic__.globalThis = __globalThis_magic__; - delete Object.prototype.__globalThis_magic__; - } - var rudderAnalyticsScript = document.createElement('script'); - rudderAnalyticsScript.src = '' - .concat(sdkBaseUrl, '/') - .concat(window.rudderAnalyticsBuildType, '/') - .concat(sdkName); - rudderAnalyticsScript.async = asyncScript; - if (document.head) { - document.head.appendChild(rudderAnalyticsScript); - } else { - document.body.appendChild(rudderAnalyticsScript); - } - }; - if (typeof Promise === 'undefined' || typeof globalThis === 'undefined') { - var rudderAnalyticsPromisesScript = document.createElement('script'); - rudderAnalyticsPromisesScript.src = - 'https://polyfill-fastly.io/v3/polyfill.min.js?version=3.111.0&features=Symbol%2CPromise&callback=rudderAnalyticsMount'; - rudderAnalyticsPromisesScript.async = asyncScript; - if (document.head) { - document.head.appendChild(rudderAnalyticsPromisesScript); - } else { - document.body.appendChild(rudderAnalyticsPromisesScript); + + + + + + crossorigin="anonymous" + > - + crossorigin="anonymous" + > + - window.RudderSnippetVersion = '3.0.1'; - var sdkBaseUrl = 'https://cdn.rudderlabs.com/__CDN_VERSION_PATH__'; - var sdkName = 'rsa.min.js'; - var asyncScript = true; - window.rudderAnalyticsBuildType = 'legacy'; - window.rudderanalytics = []; - var methods = [ - 'setDefaultInstanceKey', - 'load', - 'ready', - 'page', - 'track', - 'identify', - 'alias', - 'group', - 'reset', - 'setAnonymousId', - 'startSession', - 'endSession', - 'consent', - ]; - for (var i = 0; i < methods.length; i++) { - var method = methods[i]; - window.rudderanalytics[method] = (function (methodName) { - return function () { - window.rudderanalytics.push([methodName].concat(Array.prototype.slice.call(arguments))); - }; - })(method); - } - try { - new Function('return import("")'); - window.rudderAnalyticsBuildType = 'modern'; - } catch (e) {} - window.rudderAnalyticsMount = function () { - if (typeof globalThis === 'undefined') { - Object.defineProperty(Object.prototype, '__globalThis_magic__', { - get: function get() { - return this; - }, - configurable: true, - }); - __globalThis_magic__.globalThis = __globalThis_magic__; - delete Object.prototype.__globalThis_magic__; - } - var rudderAnalyticsScript = document.createElement('script'); - rudderAnalyticsScript.src = '' - .concat(sdkBaseUrl, '/') - .concat(window.rudderAnalyticsBuildType, '/') - .concat(sdkName); - rudderAnalyticsScript.async = asyncScript; - if (document.head) { - document.head.appendChild(rudderAnalyticsScript); - } else { - document.body.appendChild(rudderAnalyticsScript); + + + + + - window.RudderSnippetVersion = '3.0.1'; - var sdkBaseUrl = 'https://cdn.rudderlabs.com/__CDN_VERSION_PATH__'; - var sdkName = 'rsa.min.js'; - var asyncScript = true; - window.rudderAnalyticsBuildType = 'legacy'; - window.rudderanalytics = []; - var methods = [ - 'setDefaultInstanceKey', - 'load', - 'ready', - 'page', - 'track', - 'identify', - 'alias', - 'group', - 'reset', - 'setAnonymousId', - 'startSession', - 'endSession', - 'consent', - ]; - for (var i = 0; i < methods.length; i++) { - var method = methods[i]; - window.rudderanalytics[method] = (function (methodName) { - return function () { - window.rudderanalytics.push([methodName].concat(Array.prototype.slice.call(arguments))); - }; - })(method); - } - try { - new Function('return import("")'); - window.rudderAnalyticsBuildType = 'modern'; - } catch (e) {} - window.rudderAnalyticsMount = function () { - if (typeof globalThis === 'undefined') { - Object.defineProperty(Object.prototype, '__globalThis_magic__', { - get: function get() { - return this; - }, - configurable: true, - }); - __globalThis_magic__.globalThis = __globalThis_magic__; - delete Object.prototype.__globalThis_magic__; - } - var rudderAnalyticsScript = document.createElement('script'); - rudderAnalyticsScript.src = '' - .concat(sdkBaseUrl, '/') - .concat(window.rudderAnalyticsBuildType, '/') - .concat(sdkName); - rudderAnalyticsScript.async = asyncScript; - if (document.head) { - document.head.appendChild(rudderAnalyticsScript); - } else { - document.body.appendChild(rudderAnalyticsScript); + + + + + 0 ? attrs : []; return { -@@ -3491,7 +3492,7 @@ function htmlTemplate(options = {}) { +@@ -3482,16 +3484,24 @@ function htmlTemplate(options = {}) { + + let injected = tmpl; // Inject the style tags before the head close tag + +- const headCloseTag = injected.lastIndexOf(""); // Inject the script tags before the body close tag ++ if (addToHead) { ++ const headOpenTag = injected.indexOf(""); + +- injected = [injected.slice(0, headCloseTag), ...bundleKeys.filter(f => path.extname(f) === ".css").map(b => `\n`), injected.slice(headCloseTag, injected.length)].join(""); +- const bodyCloseTag = injected.lastIndexOf(""); // Inject the script tags before the body close tag ++ injected = [injected.slice(0, headOpenTag + 6), ...bundleKeys.filter(f => path.extname(f) === ".css").map(b => `\n`), injected.slice(headOpenTag + 6, injected.length)].join(""); + +- injected = [injected.slice(0, bodyCloseTag), ...bundleKeys.filter(f => path.extname(f) === ".js").map(b => `\n`), injected.slice(bodyCloseTag, injected.length)].join(""); // write the injected template to a file ++ injected = [injected.slice(0, headOpenTag + 6), ...bundleKeys.filter(f => path.extname(f) === ".js").map(b => `\n`), injected.slice(headOpenTag + 6, injected.length)].join(""); ++ } else { ++ const headCloseTag = injected.lastIndexOf(""); // Inject the script tags before the body close tag ++ ++ injected = [injected.slice(0, headCloseTag), ...bundleKeys.filter(f => path.extname(f) === ".css").map(b => `\n`), injected.slice(headCloseTag, injected.length)].join(""); ++ const bodyCloseTag = injected.lastIndexOf(""); // Inject the script tags before the body close tag ++ ++ injected = [injected.slice(0, bodyCloseTag), ...bundleKeys.filter(f => path.extname(f) === ".js").map(b => `\n`), injected.slice(bodyCloseTag, injected.length)].join(""); // write the injected template to a file ++ } const finalTarget = path.join(targetDir, targetFile); await lib.ensureFile(finalTarget); @@ -22,7 +44,7 @@ index 7935008..0155c14 100644 } catch (e) { reject(e); diff --git a/node_modules/rollup-plugin-generate-html-template/dist/rollup-plugin-generate-html-template.module.js b/node_modules/rollup-plugin-generate-html-template/dist/rollup-plugin-generate-html-template.module.js -index 81116b3..05878ac 100644 +index 81116b3..3461132 100644 --- a/node_modules/rollup-plugin-generate-html-template/dist/rollup-plugin-generate-html-template.module.js +++ b/node_modules/rollup-plugin-generate-html-template/dist/rollup-plugin-generate-html-template.module.js @@ -3437,7 +3437,8 @@ function htmlTemplate(options = {}) {