From 8d6c7d822592596636dc799118affea05ffbebc4 Mon Sep 17 00:00:00 2001 From: Eugene Date: Tue, 22 Oct 2024 19:16:40 +0000 Subject: [PATCH] Build: add entry points without top level side-effects --- package-lock.json | 262 +----------------- packages/bundle/package.json | 11 +- .../{addVersion.js => bundle/addVersion.ts} | 22 +- packages/bundle/src/bundle/index-es5.ts | 21 ++ packages/bundle/src/bundle/index-minimal.ts | 18 ++ packages/bundle/src/bundle/index.ts | 19 ++ packages/bundle/src/{ => bundle}/polyfill.ts | 0 packages/bundle/src/index-es5.ts | 40 --- packages/bundle/src/index.ts | 126 --------- packages/bundle/src/module/exports-es5.ts | 7 + .../exports-minimal.ts} | 56 ++-- packages/bundle/src/module/exports.ts | 119 ++++++++ packages/bundle/tsup.config.ts | 32 ++- packages/bundle/webpack.config.js | 140 ---------- .../ActivityTree/ActivityTreeComposer.tsx | 12 +- 15 files changed, 260 insertions(+), 625 deletions(-) rename packages/bundle/src/{addVersion.js => bundle/addVersion.ts} (72%) create mode 100644 packages/bundle/src/bundle/index-es5.ts create mode 100644 packages/bundle/src/bundle/index-minimal.ts create mode 100644 packages/bundle/src/bundle/index.ts rename packages/bundle/src/{ => bundle}/polyfill.ts (100%) delete mode 100644 packages/bundle/src/index-es5.ts delete mode 100644 packages/bundle/src/index.ts create mode 100644 packages/bundle/src/module/exports-es5.ts rename packages/bundle/src/{index-minimal.ts => module/exports-minimal.ts} (64%) create mode 100644 packages/bundle/src/module/exports.ts delete mode 100644 packages/bundle/webpack.config.js diff --git a/package-lock.json b/package-lock.json index 7016ddf20f..0d19c4341d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5598,48 +5598,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, "node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -6229,24 +6187,6 @@ "node": ">=8" } }, - "node_modules/babel-loader": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", - "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0", - "webpack": ">=5" - } - }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", @@ -7583,13 +7523,6 @@ "node": ">= 12.0.0" } }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", - "dev": true, - "license": "ISC" - }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -10478,13 +10411,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fast-uri": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", - "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", - "dev": true, - "license": "MIT" - }, "node_modules/fast-url-parser": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", @@ -10606,23 +10532,6 @@ "dev": true, "license": "MIT" }, - "node_modules/find-cache-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", - "dev": true, - "license": "MIT", - "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -17863,110 +17772,6 @@ "node": ">=12.13.0" } }, - "node_modules/pkg-dir": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^6.3.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/pkg-dir/node_modules/yocto-queue": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", - "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/plur": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", @@ -19784,63 +19589,6 @@ "object-assign": "^4.1.1" } }, - "node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/schema-utils/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/schema-utils/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/schema-utils/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, "node_modules/selenium-webdriver": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.25.0.tgz", @@ -24035,7 +23783,6 @@ "@types/node": "^20.12.11", "@types/react": "^16.14.60", "@types/uuid": "^10.0.0", - "babel-loader": "^9.1.3", "babel-plugin-istanbul": "^6.1.1", "babel-plugin-transform-inline-environment-variables": "^0.4.4", "botframework-webchat-base": "0.0.0-0", @@ -24044,14 +23791,9 @@ "esbuild": "^0.21.1", "isomorphic-react": "^0.0.0-0", "isomorphic-react-dom": "^0.0.0-0", - "source-map-loader": "^5.0.0", - "terser-webpack-plugin": "^5.3.10", "tsd": "^0.31.0", "type-fest": "^4.18.2", - "typescript": "^5.4.5", - "webpack": "^5.91.0", - "webpack-cli": "^5.1.4", - "webpack-stats-plugin": "^1.1.3" + "typescript": "^5.4.5" }, "peerDependencies": { "react": ">= 16.8.6", @@ -25467,6 +25209,7 @@ "@types/math-random": "^1.0.2", "@types/node": "^20.12.11", "@types/react": "^16.14.60", + "botframework-webchat-base": "0.0.0-0", "botframework-webchat-styles": "0.0.0-0", "tsup": "^8.0.2", "typescript": "^5.4.5" @@ -25517,6 +25260,7 @@ "@jridgewell/sourcemap-codec": "^1.4.15", "@tsconfig/strictest": "^2.0.5", "@types/node": "^20.10.3", + "botframework-webchat-base": "0.0.0-0", "cross-env": "^7.0.3", "type-fest": "^4.14.0", "typescript": "^5.3.2" diff --git a/packages/bundle/package.json b/packages/bundle/package.json index 97a33758ee..d2e28ce291 100644 --- a/packages/bundle/package.json +++ b/packages/bundle/package.json @@ -45,9 +45,8 @@ } }, "scripts": { - "build": "npm run build:tsup && npm run build:webpack", + "build": "npm run build:tsup", "build:tsup": "tsup --config ./tsup.config.ts", - "build:webpack": "webpack-cli", "bump": "npm run bump:prod && npm run bump:dev && (npm audit fix || exit 0)", "bump:dev": "PACKAGES_TO_BUMP=$(cat package.json | jq -r '(.pinDependencies // {}) as $P | (.localDependencies // {} | keys) as $L | (.devDependencies // {}) | to_entries | map(select(.key as $K | $L | contains([$K]) | not)) | map(.key + \"@\" + ($P[.key] // [\"latest\"])[0]) | join(\" \")') && [ ! -z \"$PACKAGES_TO_BUMP\" ] && npm install $PACKAGES_TO_BUMP || true", "bump:prod": "PACKAGES_TO_BUMP=$(cat package.json | jq -r '(.pinDependencies // {}) as $P | (.localDependencies // {} | keys) as $L | (.dependencies // {}) | to_entries | map(select(.key as $K | $L | contains([$K]) | not)) | map(.key + \"@\" + ($P[.key] // [\"latest\"])[0]) | join(\" \")') && [ ! -z \"$PACKAGES_TO_BUMP\" ] && npm install --save-exact $PACKAGES_TO_BUMP || true", @@ -163,7 +162,6 @@ "@types/node": "^20.12.11", "@types/react": "^16.14.60", "@types/uuid": "^10.0.0", - "babel-loader": "^9.1.3", "babel-plugin-istanbul": "^6.1.1", "babel-plugin-transform-inline-environment-variables": "^0.4.4", "botframework-webchat-base": "0.0.0-0", @@ -172,14 +170,9 @@ "esbuild": "^0.21.1", "isomorphic-react": "^0.0.0-0", "isomorphic-react-dom": "^0.0.0-0", - "source-map-loader": "^5.0.0", - "terser-webpack-plugin": "^5.3.10", "tsd": "^0.31.0", "type-fest": "^4.18.2", - "typescript": "^5.4.5", - "webpack": "^5.91.0", - "webpack-cli": "^5.1.4", - "webpack-stats-plugin": "^1.1.3" + "typescript": "^5.4.5" }, "peerDependencies": { "react": ">= 16.8.6", diff --git a/packages/bundle/src/addVersion.js b/packages/bundle/src/bundle/addVersion.ts similarity index 72% rename from packages/bundle/src/addVersion.js rename to packages/bundle/src/bundle/addVersion.ts index e6bb3f3663..b70b4221d9 100644 --- a/packages/bundle/src/addVersion.js +++ b/packages/bundle/src/bundle/addVersion.ts @@ -1,13 +1,10 @@ -/* global globalThis:readonly, process:readonly */ +/* global globalThis:readonly */ /* eslint no-empty: ["error", { "allowEmptyCatch": true }] */ - import { buildInfo as apiBuildInfo } from 'botframework-webchat-api'; import { buildInfo as componentBuildInfo } from 'botframework-webchat-component'; import { buildInfo as coreBuildInfo } from 'botframework-webchat-core'; -const bundleVersion = process.env.npm_package_version; - -function setMetaTag(name, content) { +function setMetaTag(name: string, content: string) { try { const { document } = globalThis; @@ -22,14 +19,21 @@ function setMetaTag(name, content) { } catch (err) {} } -export default function addVersion(variant) { +type BuildMeta = Readonly<{ + version: string; + variant: string; + buildTool: string; + moduleFormat: string; +}>; + +export default function addVersion(buildInfo: BuildMeta) { setMetaTag( 'botframework-webchat:api', `version=${apiBuildInfo.version}; build-tool=${apiBuildInfo.buildTool}; module-format=${apiBuildInfo.moduleFormat}` ); setMetaTag( 'botframework-webchat:bundle', - `version=${bundleVersion}; variant=${variant}; build-tool=${process.env.build_tool}; module-format=${process.env.module_format}` + `version=${buildInfo.version}; variant=${buildInfo.variant}; build-tool=${buildInfo.buildTool}; module-format=${buildInfo.moduleFormat}` ); setMetaTag( 'botframework-webchat:component', @@ -40,8 +44,8 @@ export default function addVersion(variant) { `version=${coreBuildInfo.version}; build-tool=${coreBuildInfo.buildTool}; module-format=${coreBuildInfo.moduleFormat}` ); - setMetaTag('botframework-webchat:bundle:variant', variant); - setMetaTag('botframework-webchat:bundle:version', process.env.npm_package_version); + setMetaTag('botframework-webchat:bundle:variant', buildInfo.variant); + setMetaTag('botframework-webchat:bundle:version', buildInfo.version); setMetaTag('botframework-webchat:core:version', coreBuildInfo.version); setMetaTag('botframework-webchat:ui:version', componentBuildInfo.version); } diff --git a/packages/bundle/src/bundle/index-es5.ts b/packages/bundle/src/bundle/index-es5.ts new file mode 100644 index 0000000000..3f6b3235cc --- /dev/null +++ b/packages/bundle/src/bundle/index-es5.ts @@ -0,0 +1,21 @@ +// Importing polyfills required for IE11/ES5. +import './polyfill'; + +import addVersion from './addVersion'; +import * as es5 from '../module/exports-es5'; + +const buildInfo = Object.freeze({ + ...es5.buildInfo, + moduleFormat: 'iife' +}); + +// Until we have a development-specific bundle, we are not shipping createStoreWithDevTools in bundle. +const { createStoreWithDevTools: _createStoreWithDevTools, ...finalES5 } = es5; + +window['WebChat'] = Object.freeze({ + ...window['WebChat'], + ...finalES5, + buildInfo +}); + +addVersion(buildInfo); diff --git a/packages/bundle/src/bundle/index-minimal.ts b/packages/bundle/src/bundle/index-minimal.ts new file mode 100644 index 0000000000..46a588286d --- /dev/null +++ b/packages/bundle/src/bundle/index-minimal.ts @@ -0,0 +1,18 @@ +import addVersion from './addVersion'; +import * as minimal from '../module/exports-minimal.js'; + +const buildInfo = Object.freeze({ + ...minimal.buildInfo, + moduleFormat: 'iife' +}); + +// Until we have a development-specific bundle, we are not shipping createStoreWithDevTools in bundle. +const { createStoreWithDevTools: _createStoreWithDevTools, ...finalMinimal } = minimal; + +window['WebChat'] = Object.freeze({ + ...window['WebChat'], + ...finalMinimal, + buildInfo +}); + +addVersion(buildInfo); diff --git a/packages/bundle/src/bundle/index.ts b/packages/bundle/src/bundle/index.ts new file mode 100644 index 0000000000..df8c256db3 --- /dev/null +++ b/packages/bundle/src/bundle/index.ts @@ -0,0 +1,19 @@ +import addVersion from './addVersion'; +import * as full from '../module/exports'; + +const buildInfo = Object.freeze({ + ...full.buildInfo, + buildTool: 'tsup/webpack', + moduleFormat: 'iife' +}); + +// Until we have a development-specific bundle, we are not shipping createStoreWithDevTools in bundle. +const { createStoreWithDevTools: _createStoreWithDevTools, ...finalFull } = full; + +window['WebChat'] = Object.freeze({ + ...window['WebChat'], + ...finalFull, + buildInfo +}); + +addVersion(buildInfo); diff --git a/packages/bundle/src/polyfill.ts b/packages/bundle/src/bundle/polyfill.ts similarity index 100% rename from packages/bundle/src/polyfill.ts rename to packages/bundle/src/bundle/polyfill.ts diff --git a/packages/bundle/src/index-es5.ts b/packages/bundle/src/index-es5.ts deleted file mode 100644 index b1ab935f8d..0000000000 --- a/packages/bundle/src/index-es5.ts +++ /dev/null @@ -1,40 +0,0 @@ -// Importing polyfills required for IE11/ES5. -import './polyfill'; - -import addVersion from './addVersion'; -import defaultCreateDirectLine from './createDirectLine'; -import defaultCreateDirectLineAppServiceExtension from './createDirectLineAppServiceExtension'; -import { buildInfo as minimalBuildInfo, version } from './index-minimal'; - -const buildInfo = { ...minimalBuildInfo, variant: 'full-es5' }; - -export * from './index'; - -export const createDirectLine = options => { - options.botAgent && - console.warn( - 'Web Chat: Developers are not currently allowed to set botAgent in the createDirectLine function. See https://github.com/microsoft/BotFramework-WebChat/issues/2119 for more details.' - ); - - return defaultCreateDirectLine({ ...options, botAgent: `WebChat/${version} (ES5)` }); -}; - -export const createDirectLineAppServiceExtension = options => { - options.botAgent && - console.warn( - 'Web Chat: Developers are not currently allowed to set botAgent in the createDirectLine function. See https://github.com/microsoft/BotFramework-WebChat/issues/2119 for more details.' - ); - - return defaultCreateDirectLineAppServiceExtension({ ...options, botAgent: `WebChat/${version} (ES5)` }); -}; - -export { buildInfo }; - -window['WebChat'] = { - ...window['WebChat'], - buildInfo, - createDirectLine, - createDirectLineAppServiceExtension -}; - -addVersion('full-es5'); diff --git a/packages/bundle/src/index.ts b/packages/bundle/src/index.ts deleted file mode 100644 index 7018624e6b..0000000000 --- a/packages/bundle/src/index.ts +++ /dev/null @@ -1,126 +0,0 @@ -export * from './index-minimal'; - -import FullComposer from './FullComposer'; -import ReactWebChat from './FullReactWebChat'; -import AdaptiveCardContent from './adaptiveCards/Attachment/AdaptiveCardContent'; -import AnimationCardContent from './adaptiveCards/Attachment/AnimationCardContent'; -import AudioCardContent from './adaptiveCards/Attachment/AudioCardContent'; -import HeroCardContent from './adaptiveCards/Attachment/HeroCardContent'; -import OAuthCardContent from './adaptiveCards/Attachment/OAuthCardContent'; -import ReceiptCardContent from './adaptiveCards/Attachment/ReceiptCardContent'; -import SignInCardContent from './adaptiveCards/Attachment/SignInCardContent'; -import ThumbnailCardContent from './adaptiveCards/Attachment/ThumbnailCardContent'; -import VideoCardContent from './adaptiveCards/Attachment/VideoCardContent'; -import createAdaptiveCardsAttachmentForScreenReaderMiddleware from './adaptiveCards/createAdaptiveCardsAttachmentForScreenReaderMiddleware'; -import createAdaptiveCardsAttachmentMiddleware from './adaptiveCards/createAdaptiveCardsAttachmentMiddleware'; -import useAdaptiveCardsHostConfig from './adaptiveCards/hooks/useAdaptiveCardsHostConfig'; -import useAdaptiveCardsPackage from './adaptiveCards/hooks/useAdaptiveCardsPackage'; -import addVersion from './addVersion'; -import createCognitiveServicesSpeechServicesPonyfillFactory from './createCognitiveServicesSpeechServicesPonyfillFactory'; -import defaultCreateDirectLine from './createDirectLine'; -import defaultCreateDirectLineAppServiceExtension from './createDirectLineAppServiceExtension'; -import createDirectLineSpeechAdapters from './createDirectLineSpeechAdapters'; -import createStyleSet from './createFullStyleSet'; -import useStyleOptions from './hooks/useStyleOptions'; -import useStyleSet from './hooks/useStyleSet'; -import { - Components as MinimalComponents, - hooks, - buildInfo as minimalBuildInfo, - version, - withEmoji -} from './index-minimal'; -import renderMarkdown from './markdown/renderMarkdown'; -import coreRenderWebChat from './renderWebChat'; -import { type AdaptiveCardsPackage } from './types/AdaptiveCardsPackage'; -import FullBundleStyleOptions, { StrictFullBundleStyleOptions } from './types/FullBundleStyleOptions'; - -const renderWebChat = coreRenderWebChat.bind(null, ReactWebChat); -const buildInfo = { ...minimalBuildInfo, variant: 'full' }; - -export const createDirectLine = (options: Omit[0], 'botAgent'>) => { - (options as any).botAgent && - console.warn( - 'Web Chat: Developers are not currently allowed to set botAgent. See https://github.com/microsoft/BotFramework-WebChat/issues/2119 for more details.' - ); - - return defaultCreateDirectLine({ ...options, botAgent: `WebChat/${version} (Full)` }); -}; - -export const createDirectLineAppServiceExtension = ( - options: Omit[0], 'botAgent'> -) => { - (options as any).botAgent && - console.warn( - 'Web Chat: Developers are not currently allowed to set botAgent. See https://github.com/microsoft/BotFramework-WebChat/issues/2119 for more details.' - ); - - return defaultCreateDirectLineAppServiceExtension({ ...options, botAgent: `WebChat/${version} (Full)` }); -}; - -const patchedHooks = { - ...hooks, - useAdaptiveCardsHostConfig, - useAdaptiveCardsPackage, - useStyleOptions, - useStyleSet -}; - -const AdditionalComponents = { - AdaptiveCardContent, - AnimationCardContent, - AudioCardContent, - Composer: FullComposer, - HeroCardContent, - OAuthCardContent, - ReceiptCardContent, - SignInCardContent, - ThumbnailCardContent, - VideoCardContent -}; - -const Components: typeof MinimalComponents & typeof AdditionalComponents = { - ...MinimalComponents, - ...AdditionalComponents -}; - -type StyleOptions = FullBundleStyleOptions; -type StrictStyleOptions = StrictFullBundleStyleOptions; - -export default ReactWebChat; - -export { - Components, - buildInfo, - createAdaptiveCardsAttachmentForScreenReaderMiddleware, - createAdaptiveCardsAttachmentMiddleware, - createCognitiveServicesSpeechServicesPonyfillFactory, - createDirectLineSpeechAdapters, - createStyleSet, - patchedHooks as hooks, - renderMarkdown, - renderWebChat, - withEmoji -}; - -export type { AdaptiveCardsPackage, StrictStyleOptions, StyleOptions }; - -window['WebChat'] = { - ...window['WebChat'], - buildInfo, - Components, - createAdaptiveCardsAttachmentMiddleware, - createAdaptiveCardsAttachmentForScreenReaderMiddleware, - createCognitiveServicesSpeechServicesPonyfillFactory, - createDirectLine, - createDirectLineAppServiceExtension, - createDirectLineSpeechAdapters, - createStyleSet, - hooks: patchedHooks, - ReactWebChat, - renderMarkdown, - renderWebChat, - withEmoji -}; - -addVersion('full'); diff --git a/packages/bundle/src/module/exports-es5.ts b/packages/bundle/src/module/exports-es5.ts new file mode 100644 index 0000000000..6c7d69c756 --- /dev/null +++ b/packages/bundle/src/module/exports-es5.ts @@ -0,0 +1,7 @@ +import { buildInfo as minimalBuildInfo } from './exports-minimal'; + +export * from './exports'; + +const buildInfo = Object.freeze({ ...minimalBuildInfo, variant: 'full-es5' }); + +export { buildInfo }; diff --git a/packages/bundle/src/index-minimal.ts b/packages/bundle/src/module/exports-minimal.ts similarity index 64% rename from packages/bundle/src/index-minimal.ts rename to packages/bundle/src/module/exports-minimal.ts index 1a36fd213e..1b727e3f86 100644 --- a/packages/bundle/src/index-minimal.ts +++ b/packages/bundle/src/module/exports-minimal.ts @@ -1,5 +1,5 @@ import { StrictStyleOptions, StyleOptions } from 'botframework-webchat-api'; -import * as decorator from 'botframework-webchat-api/decorator'; +import * as apiDecorator from 'botframework-webchat-api/decorator'; import { WebChatDecorator } from 'botframework-webchat-component/decorator'; import { Constants, createStore, createStoreWithDevTools, createStoreWithOptions } from 'botframework-webchat-core'; import * as internal from 'botframework-webchat-component/internal'; @@ -13,11 +13,10 @@ import ReactWebChat, { withEmoji } from 'botframework-webchat-component'; -import addVersion from './addVersion'; -import createBrowserWebSpeechPonyfillFactory from './createBrowserWebSpeechPonyfillFactory'; -import defaultCreateDirectLine from './createDirectLine'; -import defaultCreateDirectLineAppServiceExtension from './createDirectLineAppServiceExtension'; -import coreRenderWebChat from './renderWebChat'; +import createBrowserWebSpeechPonyfillFactory from '../createBrowserWebSpeechPonyfillFactory'; +import defaultCreateDirectLine from '../createDirectLine'; +import defaultCreateDirectLineAppServiceExtension from '../createDirectLineAppServiceExtension'; +import coreRenderWebChat from '../renderWebChat'; const renderWebChat = coreRenderWebChat.bind(null, ReactWebChat); @@ -25,7 +24,12 @@ const buildTool = process.env.build_tool; const moduleFormat = process.env.module_format; const version = process.env.npm_package_version; -const buildInfo = { buildTool, moduleFormat, variant: 'minimal', version }; +const buildInfo = Object.freeze({ + buildTool, + moduleFormat, + variant: 'minimal', + version +}); export const createDirectLine = options => { options.botAgent && @@ -47,6 +51,11 @@ export const createDirectLineAppServiceExtension = options => { export default ReactWebChat; +const decorator = Object.freeze({ + ...apiDecorator, + WebChatDecorator +}); + export { buildInfo, Components, @@ -57,39 +66,14 @@ export { createStoreWithDevTools, createStoreWithOptions, createStyleSet, - internal, + decorator, hooks, - renderWebChat, - version, - withEmoji -}; - -export type { StrictStyleOptions, StyleOptions }; - -// Until we have a development-specific bundle, we are not shipping createStoreWithDevTools in bundle. -window['WebChat'] = { - ...window['WebChat'], - concatMiddleware, - Constants, - createBrowserWebSpeechPonyfillFactory, - createDirectLine, - createDirectLineAppServiceExtension, - createStore, - createStoreWithOptions, - createStyleSet, - decorator: { - ...decorator, - WebChatDecorator - }, internal, - hooks, ReactWebChat, renderWebChat, - testIds: { - ...(window['WebChat']?.testIds || {}), - ...testIds - }, + testIds, + version, withEmoji }; -addVersion('minimal'); +export type { StrictStyleOptions, StyleOptions }; diff --git a/packages/bundle/src/module/exports.ts b/packages/bundle/src/module/exports.ts new file mode 100644 index 0000000000..4ceb9625f9 --- /dev/null +++ b/packages/bundle/src/module/exports.ts @@ -0,0 +1,119 @@ +import Composer from '../FullComposer'; +import ReactWebChat from '../FullReactWebChat'; +import AdaptiveCardContent from '../adaptiveCards/Attachment/AdaptiveCardContent'; +import AnimationCardContent from '../adaptiveCards/Attachment/AnimationCardContent'; +import AudioCardContent from '../adaptiveCards/Attachment/AudioCardContent'; +import HeroCardContent from '../adaptiveCards/Attachment/HeroCardContent'; +import OAuthCardContent from '../adaptiveCards/Attachment/OAuthCardContent'; +import ReceiptCardContent from '../adaptiveCards/Attachment/ReceiptCardContent'; +import SignInCardContent from '../adaptiveCards/Attachment/SignInCardContent'; +import ThumbnailCardContent from '../adaptiveCards/Attachment/ThumbnailCardContent'; +import VideoCardContent from '../adaptiveCards/Attachment/VideoCardContent'; +import createAdaptiveCardsAttachmentForScreenReaderMiddleware from '../adaptiveCards/createAdaptiveCardsAttachmentForScreenReaderMiddleware'; +import createAdaptiveCardsAttachmentMiddleware from '../adaptiveCards/createAdaptiveCardsAttachmentMiddleware'; +import useAdaptiveCardsHostConfig from '../adaptiveCards/hooks/useAdaptiveCardsHostConfig'; +import useAdaptiveCardsPackage from '../adaptiveCards/hooks/useAdaptiveCardsPackage'; +import createCognitiveServicesSpeechServicesPonyfillFactory from '../createCognitiveServicesSpeechServicesPonyfillFactory'; +import defaultCreateDirectLine from '../createDirectLine'; +import defaultCreateDirectLineAppServiceExtension from '../createDirectLineAppServiceExtension'; +import createDirectLineSpeechAdapters from '../createDirectLineSpeechAdapters'; +import createStyleSet from '../createFullStyleSet'; +import useStyleOptions from '../hooks/useStyleOptions'; +import useStyleSet from '../hooks/useStyleSet'; +import { + Components as MinimalComponents, + hooks, + buildInfo as minimalBuildInfo, + version, + withEmoji +} from './exports-minimal'; +import renderMarkdown from '../markdown/renderMarkdown'; +import coreRenderWebChat from '../renderWebChat'; +import { type AdaptiveCardsPackage } from '../types/AdaptiveCardsPackage'; +import FullBundleStyleOptions, { StrictFullBundleStyleOptions } from '../types/FullBundleStyleOptions'; + +const renderWebChat = coreRenderWebChat.bind(null, ReactWebChat); + +const buildInfo = Object.freeze({ ...minimalBuildInfo, variant: 'full' }); + +export { + concatMiddleware, + Constants, + createBrowserWebSpeechPonyfillFactory, + createStore, + createStoreWithDevTools, + createStoreWithOptions, + decorator, + internal, + testIds, + version +} from './exports-minimal'; + +export const createDirectLine = (options: Omit[0], 'botAgent'>) => { + (options as any).botAgent && + console.warn( + 'Web Chat: Developers are not currently allowed to set botAgent. See https://github.com/microsoft/BotFramework-WebChat/issues/2119 for more details.' + ); + + return defaultCreateDirectLine({ ...options, botAgent: `WebChat/${version} (Full)` }); +}; + +export const createDirectLineAppServiceExtension = ( + options: Omit[0], 'botAgent'> +) => { + (options as any).botAgent && + console.warn( + 'Web Chat: Developers are not currently allowed to set botAgent. See https://github.com/microsoft/BotFramework-WebChat/issues/2119 for more details.' + ); + + return defaultCreateDirectLineAppServiceExtension({ ...options, botAgent: `WebChat/${version} (Full)` }); +}; + +const patchedHooks = Object.freeze({ + ...hooks, + useAdaptiveCardsHostConfig, + useAdaptiveCardsPackage, + useStyleOptions, + useStyleSet +}); + +const AdditionalComponents = Object.freeze({ + AdaptiveCardContent, + AnimationCardContent, + AudioCardContent, + Composer, + ReactWebChat, + HeroCardContent, + OAuthCardContent, + ReceiptCardContent, + SignInCardContent, + ThumbnailCardContent, + VideoCardContent +}); + +const Components: Readonly = Object.freeze({ + ...MinimalComponents, + ...AdditionalComponents +}); + +type StyleOptions = FullBundleStyleOptions; +type StrictStyleOptions = StrictFullBundleStyleOptions; + +export default ReactWebChat; + +export { + buildInfo, + Components, + createAdaptiveCardsAttachmentForScreenReaderMiddleware, + createAdaptiveCardsAttachmentMiddleware, + createCognitiveServicesSpeechServicesPonyfillFactory, + createDirectLineSpeechAdapters, + createStyleSet, + patchedHooks as hooks, + ReactWebChat, + renderMarkdown, + renderWebChat, + withEmoji +}; + +export type { AdaptiveCardsPackage, StrictStyleOptions, StyleOptions }; diff --git a/packages/bundle/tsup.config.ts b/packages/bundle/tsup.config.ts index ad95fd81c7..d5828b936a 100644 --- a/packages/bundle/tsup.config.ts +++ b/packages/bundle/tsup.config.ts @@ -13,12 +13,22 @@ const resolveCognitiveServicesToES2015 = { } }; +// Redirect import paths for "react" and "react-dom" +const resolveReact = { + name: 'isomorphic-react', + setup(build) { + build.onResolve({ filter: /^(react|react-dom)$/u }, ({ path: pkgNamne }) => ({ + path: path.join(process.cwd(), '../../node_modules', `isomorphic-${pkgNamne}/dist/${pkgNamne}.js`) + })); + } +}; + const config: typeof baseConfig = { ...baseConfig, entry: { - 'botframework-webchat': './src/index.ts', - 'botframework-webchat.es5': './src/index-es5.ts', - 'botframework-webchat.minimal': './src/index-minimal.ts' + 'botframework-webchat': './src/module/exports.ts', + 'botframework-webchat.es5': './src/module/exports-es5.ts', + 'botframework-webchat.minimal': './src/module/exports-minimal.ts' }, env: { ...baseConfig.env, @@ -46,5 +56,21 @@ export default defineConfig([ ...config, format: 'cjs', target: [...config.target, 'es2019'] + }, + { + ...config, + dts: false, + entry: { + webchat: './src/bundle/index.ts', + 'webchat-es5': './src/bundle/index-es5.ts', + 'webchat-minimal': './src/bundle/index-minimal.ts' + }, + esbuildPlugins: [...config.esbuildPlugins, resolveReact], + format: 'iife', + outExtension() { + return { js: '.js' }; + }, + platform: 'browser', + target: [...config.target, 'es2019'] } ]); diff --git a/packages/bundle/webpack.config.js b/packages/bundle/webpack.config.js deleted file mode 100644 index 9185579d63..0000000000 --- a/packages/bundle/webpack.config.js +++ /dev/null @@ -1,140 +0,0 @@ -/* eslint @typescript-eslint/no-var-requires: "off" */ -/* eslint no-magic-numbers: ["error", { "ignore": [2] }] */ -/* global __dirname, module, process */ - -const { join } = require('path'); -const { resolve } = require('path'); -const { StatsWriterPlugin } = require('webpack-stats-plugin'); -const TerserPlugin = require('terser-webpack-plugin'); - -let config = { - entry: { - webchat: './dist/botframework-webchat.mjs', - 'webchat-es5': './dist/botframework-webchat.es5.mjs', - 'webchat-minimal': './dist/botframework-webchat.minimal.mjs' - }, - mode: 'production', - module: { - rules: [ - { - // To speed up bundling, we are limiting Babel to a number of packages which does not publish ES5 bits. - test: /\/node_modules\/(bent|botframework-streaming|buffer|nanoid|postcss|punycode|sanitize-html)\//iu, - use: { - loader: 'babel-loader', - options: { - presets: [ - [ - '@babel/preset-env', - { - modules: 'commonjs' - } - ] - ] - } - } - } - ] - }, - optimization: { - minimizer: [ - // Webpack use terser for minification - // https://webpack.js.org/configuration/mode#usage - // https://webpack.js.org/plugins/terser-webpack-plugin/#terseroptions - new TerserPlugin({ - terserOptions: { - // https://github.com/terser-js/terser#minify-options - output: { - ascii_only: true - } - } - }) - ] - }, - output: { - libraryTarget: 'umd' - }, - plugins: [ - new StatsWriterPlugin({ - filename: 'stats.json', - transform: (_, opts) => JSON.stringify(opts.compiler.getStats().toJson({ chunkModules: true }), null, 2) - }) - ], - resolve: { - alias: { - // TODO: [P1] #3914 It is smaller to use /lib/ instead of /es2015/ with Webpack. - // Verifies if /es2015/ is better when moving to esbuild. - 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.browser/Exports': resolve( - __dirname, - '../../node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.browser/Exports.js' - ), - 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.speech/Exports': resolve( - __dirname, - '../../node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.speech/Exports.js' - ), - 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common/Exports': resolve( - __dirname, - '../../node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common/Exports.js' - ), - 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/Audio/AudioStreamFormat': resolve( - __dirname, - '../../node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/Audio/AudioStreamFormat.js' - ), - 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/Exports': resolve( - __dirname, - '../../node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/Exports.js' - ), - 'microsoft-cognitiveservices-speech-sdk/distrib/lib/microsoft.cognitiveservices.speech.sdk': resolve( - __dirname, - '../../node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/microsoft.cognitiveservices.speech.sdk.js' - ), - - // This line must be placed after other specific imports. - 'microsoft-cognitiveservices-speech-sdk': resolve( - __dirname, - '../../node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/microsoft.cognitiveservices.speech.sdk.js' - ), - react: resolve(__dirname, '../../node_modules/isomorphic-react/dist/react.js'), - 'react-dom': resolve(__dirname, '../../node_modules/isomorphic-react-dom/dist/react-dom.js') - } - }, - target: ['web', 'es5'] -}; - -// VSTS always emits uppercase environment variables. -const node_env = process.env.node_env || process.env.NODE_ENV; - -// Source maps are only added to development bits because of being slow to load in the browser. -// - "eval-source-map" took 1.6s to load in browser, 1.5s to rebuild -// - "source-map" took 500ms to load, 5s to rebuild -// - No source map took 300ms to load -// "Cheap modules" does not have column information, thus, breakpoint does not work correctly. -if (node_env !== 'production' && node_env !== 'test') { - config = { - ...config, - devtool: 'eval-source-map', - mode: 'development', - module: { - ...config.module, - rules: [ - ...((config.module || {}).rules || []), - { - enforce: 'pre', - include: [ - join(__dirname, './dist'), - join(__dirname, '../component/dist'), - join(__dirname, '../core/dist'), - join(__dirname, '../directlinespeech/dist') - ], - test: /\.js$/iu, - use: ['source-map-loader'] - } - ] - }, - output: { - ...config.output, - devtoolNamespace: 'botframework-webchat' - } - }; -} - -module.exports = config; diff --git a/packages/component/src/providers/ActivityTree/ActivityTreeComposer.tsx b/packages/component/src/providers/ActivityTree/ActivityTreeComposer.tsx index 09daea67b2..d5569b92ce 100644 --- a/packages/component/src/providers/ActivityTree/ActivityTreeComposer.tsx +++ b/packages/component/src/providers/ActivityTree/ActivityTreeComposer.tsx @@ -13,7 +13,7 @@ import type { ActivityTreeContextType } from './private/Context'; type ActivityTreeComposerProps = Readonly<{ children?: ReactNode | undefined }>; -const { useActivities, useCreateActivityRenderer, useGetActivitiesByKey, useGetKeyByActivity } = hooks; +const { useActivities, useActivityKeys, useCreateActivityRenderer, useGetActivitiesByKey, useGetKeyByActivity } = hooks; const ActivityTreeComposer = ({ children }: ActivityTreeComposerProps) => { const existingContext = useActivityTreeContext(false); @@ -25,10 +25,15 @@ const ActivityTreeComposer = ({ children }: ActivityTreeComposerProps) => { const [rawActivities] = useActivities(); const getActivitiesByKey = useGetActivitiesByKey(); const getKeyByActivity = useGetKeyByActivity(); + const activityKeys = useActivityKeys(); const activities = useMemo(() => { const activities: WebChatActivity[] = []; + if (!activityKeys) { + return rawActivities; + } + for (const activity of rawActivities) { // If an activity has multiple revisions, display the latest revision only at the position of the first revision. @@ -36,11 +41,12 @@ const ActivityTreeComposer = ({ children }: ActivityTreeComposerProps) => { const activitiesWithSameKey = getActivitiesByKey(getKeyByActivity(activity)); // TODO: We may want to send all revisions of activity to the middleware so they can render UI to see previous revisions. - activitiesWithSameKey[0] === activity && activities.push(activitiesWithSameKey[activitiesWithSameKey.length - 1]); + activitiesWithSameKey?.[0] === activity && + activities.push(activitiesWithSameKey[activitiesWithSameKey.length - 1]); } return Object.freeze(activities); - }, [getActivitiesByKey, getKeyByActivity, rawActivities]); + }, [activityKeys, getActivitiesByKey, getKeyByActivity, rawActivities]); const createActivityRenderer: ActivityComponentFactory = useCreateActivityRenderer();