diff --git a/src/compiler/bundle/app-data-plugin.ts b/src/compiler/bundle/app-data-plugin.ts index 977e015352a..78f05a3e81e 100644 --- a/src/compiler/bundle/app-data-plugin.ts +++ b/src/compiler/bundle/app-data-plugin.ts @@ -183,9 +183,11 @@ const appendGlobalScripts = (globalScripts: GlobalScript[], s: MagicString) => { }); s.append(`export const globalScripts = () => {\n`); + s.append(` return Promise.all([\n`); globalScripts.forEach((globalScript) => { - s.append(` ${globalScript.defaultName}();\n`); + s.append(` ${globalScript.defaultName}(),\n`); }); + s.append(` ]);\n`); s.append(`};\n`); } else { s.append(`export const globalScripts = () => {};\n`); diff --git a/src/compiler/output-targets/dist-lazy/lazy-output.ts b/src/compiler/output-targets/dist-lazy/lazy-output.ts index 1edc5969d8a..10ca11bf5ec 100644 --- a/src/compiler/output-targets/dist-lazy/lazy-output.ts +++ b/src/compiler/output-targets/dist-lazy/lazy-output.ts @@ -180,15 +180,15 @@ const getLazyEntry = (isBrowser: boolean): string => { if (isBrowser) { s.append(`import { patchBrowser } from '${STENCIL_INTERNAL_CLIENT_PATCH_BROWSER_ID}';\n`); s.append(`import { globalScripts } from '${STENCIL_APP_GLOBALS_ID}';\n`); - s.append(`patchBrowser().then(options => {\n`); - s.append(` globalScripts();\n`); + s.append(`patchBrowser().then(async (options) => {\n`); + s.append(` await globalScripts();\n`); s.append(` return bootstrapLazy([/*!__STENCIL_LAZY_DATA__*/], options);\n`); s.append(`});\n`); } else { s.append(`import { globalScripts } from '${STENCIL_APP_GLOBALS_ID}';\n`); - s.append(`export const defineCustomElements = (win, options) => {\n`); + s.append(`export const defineCustomElements = async (win, options) => {\n`); s.append(` if (typeof window === 'undefined') return undefined;\n`); - s.append(` globalScripts();\n`); + s.append(` await globalScripts();\n`); s.append(` return bootstrapLazy([/*!__STENCIL_LAZY_DATA__*/], options);\n`); s.append(`};\n`); } diff --git a/test/karma/package.json b/test/karma/package.json index fd7cd3de787..9912dacf0f1 100644 --- a/test/karma/package.json +++ b/test/karma/package.json @@ -7,13 +7,14 @@ "scripts": { "clean": "rm -rf test-output tmp-compiled-tests", "start": "node ../../bin/stencil build --dev --watch --serve --es5", - "build.all": "npm run clean && npm run build.sibling && npm run build.invisible-prehydration.false && npm run build.app && npm run build.custom-elements && npm run karma.webpack && npm run build.prerender", + "build.all": "npm run clean && npm run build.sibling && npm run build.globalScripts && npm run build.invisible-prehydration.false && npm run build.app && npm run build.custom-elements && npm run karma.webpack && npm run build.prerender", "build.app": "npm run compile.test-app && node ../../bin/stencil build --debug --es5", "compile.test-app": "node ../../node_modules/typescript/lib/tsc -p tsconfig.json", "build.custom-elements": "webpack-cli --config test-app/custom-elements-output-webpack/webpack.config.js && webpack-cli --config test-app/custom-elements-output-tag-class-different/webpack.config.js && webpack-cli --config test-app/custom-elements-delegates-focus/webpack.config.js", "build.invisible-prehydration.false": "node ../../bin/stencil build --config test-invisible-prehydration/stencil.invisiblePrehydrationFalse.config.ts --debug", "build.prerender": "node ../../bin/stencil build --config test-prerender/stencil.config-prerender.ts --prerender --debug && node test-prerender/no-script-build.js", "build.sibling": "node ../../bin/stencil build --config test-sibling/stencil.config.ts --debug", + "build.globalScripts": "node ../../bin/stencil build --config test-global-script/stencil.config.ts --debug", "karma": "karma start karma.config.js", "karma.prod": "npm run build.all && npm run karma", "karma.webpack": "webpack-cli --config test-app/esm-webpack/webpack.config.js", diff --git a/test/karma/test-app/global-script/index.html b/test/karma/test-app/global-script/index.html new file mode 100644 index 00000000000..240f07dd684 --- /dev/null +++ b/test/karma/test-app/global-script/index.html @@ -0,0 +1,6 @@ + + + + + + diff --git a/test/karma/test-app/global-script/karma.spec.ts b/test/karma/test-app/global-script/karma.spec.ts new file mode 100644 index 00000000000..38433ee0a59 --- /dev/null +++ b/test/karma/test-app/global-script/karma.spec.ts @@ -0,0 +1,20 @@ +import { setupDomTests } from '../util'; + +describe('global script', () => { + const env = setupDomTests(document); + + afterEach(() => { + env?.tearDownDom(); + }); + + it('supports async execution', async () => { + await env?.setupDom('/global-script/index.html'); + + const cmp = document.querySelector('test-cmp'); + expect(cmp).not.toBeNull(); + expect(typeof cmp?.textContent).toBe('string'); + + const renderedDelay = parseInt(cmp?.textContent?.slice('I am rendered after '.length)); + expect(renderedDelay).toBeGreaterThanOrEqual(1000); + }); +}); diff --git a/test/karma/test-global-script/package-lock.json b/test/karma/test-global-script/package-lock.json new file mode 100644 index 00000000000..9850f05baa2 --- /dev/null +++ b/test/karma/test-global-script/package-lock.json @@ -0,0 +1,10 @@ +{ + "name": "global-script", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "global-script" + } + } +} diff --git a/test/karma/test-global-script/package.json b/test/karma/test-global-script/package.json new file mode 100644 index 00000000000..a6ddaffc027 --- /dev/null +++ b/test/karma/test-global-script/package.json @@ -0,0 +1,10 @@ +{ + "name": "global-script", + "main": "dist/index.cjs.js", + "module": "dist/index.js", + "collection": "dist/collection/collection-manifest.json", + "types": "dist/types/components.d.ts", + "volta": { + "extends": "../package.json" + } +} diff --git a/test/karma/test-global-script/src/components.d.ts b/test/karma/test-global-script/src/components.d.ts new file mode 100644 index 00000000000..bb54c1e254b --- /dev/null +++ b/test/karma/test-global-script/src/components.d.ts @@ -0,0 +1,37 @@ +/* eslint-disable */ +/* tslint:disable */ +/** + * This is an autogenerated file created by the Stencil compiler. + * It contains typing information for all components that exist in this project. + */ +import { HTMLStencilElement, JSXBase } from "@stencil/core/internal"; +export namespace Components { + interface TestCmp { + } +} +declare global { + interface HTMLTestCmpElement extends Components.TestCmp, HTMLStencilElement { + } + var HTMLTestCmpElement: { + prototype: HTMLTestCmpElement; + new (): HTMLTestCmpElement; + }; + interface HTMLElementTagNameMap { + "test-cmp": HTMLTestCmpElement; + } +} +declare namespace LocalJSX { + interface TestCmp { + } + interface IntrinsicElements { + "test-cmp": TestCmp; + } +} +export { LocalJSX as JSX }; +declare module "@stencil/core" { + export namespace JSX { + interface IntrinsicElements { + "test-cmp": LocalJSX.TestCmp & JSXBase.HTMLAttributes; + } + } +} diff --git a/test/karma/test-global-script/src/global.ts b/test/karma/test-global-script/src/global.ts new file mode 100644 index 00000000000..fe805f946c9 --- /dev/null +++ b/test/karma/test-global-script/src/global.ts @@ -0,0 +1,10 @@ +declare global { + interface Window { + __testStart: number; + } +} + +export default async function () { + window.__testStart = Date.now(); + return new Promise((resolve) => setTimeout(() => resolve('done!'), 1000)); +} diff --git a/test/karma/test-global-script/src/test-cmp/test-cmp.tsx b/test/karma/test-global-script/src/test-cmp/test-cmp.tsx new file mode 100644 index 00000000000..9a4bdd670f4 --- /dev/null +++ b/test/karma/test-global-script/src/test-cmp/test-cmp.tsx @@ -0,0 +1,11 @@ +import { Component, h } from '@stencil/core'; + +@Component({ + tag: 'test-cmp', + scoped: true, +}) +export class SiblingRoot { + render() { + return
I am rendered after {Date.now() - window.__testStart}
; + } +} diff --git a/test/karma/test-global-script/stencil.config.ts b/test/karma/test-global-script/stencil.config.ts new file mode 100644 index 00000000000..cb220a146c3 --- /dev/null +++ b/test/karma/test-global-script/stencil.config.ts @@ -0,0 +1,14 @@ +import { Config } from '../../../dist/declarations'; +const { WWW_OUT_DIR } = require('../constants'); + +export const config: Config = { + namespace: 'TestGlobalScript', + tsconfig: 'tsconfig.json', + outputTargets: [ + { + type: 'www', + dir: `../${WWW_OUT_DIR}`, + }, + ], + globalScript: 'src/global.ts', +}; diff --git a/test/karma/test-global-script/tsconfig.json b/test/karma/test-global-script/tsconfig.json new file mode 100644 index 00000000000..298cfbea2a1 --- /dev/null +++ b/test/karma/test-global-script/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compilerOptions": { + "alwaysStrict": true, + "allowSyntheticDefaultImports": true, + "allowUnreachableCode": true, + "declaration": false, + "resolveJsonModule": true, + "experimentalDecorators": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react", + "jsxFactory": "h", + "lib": [ + "dom", + "es2017" + ], + "module": "esnext", + "moduleResolution": "node", + "noImplicitAny": false, + "noImplicitReturns": false, + "noUnusedLocals": false, + "noUnusedParameters": false, + "pretty": true, + "target": "es2017", + "useUnknownInCatchVariables": true, + "baseUrl": ".", + "paths": { + "@stencil/core": ["../../../internal"], + "@stencil/core/internal": ["../../../internal"], + "@stencil/core/testing": ["../../../testing"] + } + }, + "include": [ + "src" + ] +} diff --git a/test/karma/tsconfig.json b/test/karma/tsconfig.json index ae28f0ba711..5c35aaa5f27 100644 --- a/test/karma/tsconfig.json +++ b/test/karma/tsconfig.json @@ -41,6 +41,7 @@ ], "exclude": [ "test-prerender", - "test-sibling" + "test-sibling", + "test-global-script" ] }