Skip to content

Commit

Permalink
Ensures CJS/ESM bundle is compatible with Alpha (sonic), pagesJS (vit…
Browse files Browse the repository at this point in the history
…e), and CRA (webpack) (#38)

**Investigation:**
This PR attempts to fix the following error in alpha/sonic:
![Screenshot 2023-08-31 at 4 40 11 PM](https://github.com/yext/chat-ui-react/assets/36055303/5ec087ff-9e94-4637-9939-96a90cec9221)
This was a result of adding `"type": "module"` to our esm bundle for our library to be compatible with vite/pagesJS.
Vite, and bundlers such as webpack, follow node's module resolution algorithm. and NodeJS have certain rules on how it recognize files as ES modules (https://nodejs.org/api/packages.html#determining-module-system) -- which include adding `"type": "module"` as an option.

The fix is to update all of our paths to be explicit in order to include the mjs/js extensions, including  (e.g. `./components` to `./components/index.js` and `../icons/DualSync` to `../icons/DualSync.js`).

This currently can't be done by typescript compiler (tsc) as it's strictly a nodejs behavior and they don't want to support that ([long issue thread here](microsoft/TypeScript#18442 (comment))), which is frustrating. So we would have to do it manually or have a script to update import/export paths in the final bundle generated by tsc. This is not ideal and can be error prone.

**Solution:**
I decided to **replace tsc with rollup to bundle our library and append .mjs extension to our final esm bundle**. Using `mjs` extension instead of `.js`  also remove the need to do `"type": "module"` in our esm package.json, which previously introduce unnecessary caveats and one-off script to inject it into our esm bundle.

NOTE: the default **interop** behavior for rollup is not compatible with alpha/sonic. As such, the rollup config in this PR uses `auto` to follow Typescript's `esModuleInterop` behavior in how it transpile named, default, and dynamic imports of external deps (the issue with alpha is related to how react-textarea-autosize was imported into ChatInput)

NOTE: updated `tsconfig.json` to use `"jsx": "react"` instead of `"jsx": "react-jsx"` because of the way jsx-runtime is backported to react 16/17 without explicit exports field ([React github issue here](facebook/react#20235 (comment))). We would either need to export two separate bundles for latest and legacy versions in order to continue outputting the JSX syntactic sugar OR we could just output `React.createElement` directly. This is common for many React libraries that support older versions like React 16. (e.g. [ant design](https://github.com/ant-design/ant-design/blob/master/tsconfig.json#L15), [blueprint UI](https://github.com/palantir/blueprint/blob/develop/config/tsconfig.base.json#L9), [evergreen UI](https://github.com/segmentio/evergreen/blob/master/tsconfig.json#L6))

J=CLIP-520
TEST=manual

see that the new build works with:
- the local test-site of the component lib repo 
- pagejs/vite (released v0.6.0-alpha.38.6 to install and test)
- sonic/alpha (released v0.6.0-alpha.38.6 to install and test)
  • Loading branch information
yen-tt authored Sep 12, 2023
1 parent 3639309 commit ae1c856
Show file tree
Hide file tree
Showing 39 changed files with 330 additions and 285 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ do not use Tailwind, a css bundle is exported as part of this package. To use it
the file `@yext/chat-ui-react/bundle.css` into your normal CSS flow.

Example for Yext Pages:

```css
/* index.css */
@import "@yext/chat-ui-react/bundle.css";
```

The CSS bundle is scoped to the target class `.yext-chat`, which is automatically included as a wrapper div in both
`ChatPanel` and `ChatPopUp`.

Expand Down
18 changes: 9 additions & 9 deletions THIRD-PARTY-NOTICES
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ MIT License

The following npm package may be included in this product:

- @yext/analytics@0.6.2
- @yext/analytics@0.6.4

This package contains the following license and notice below:

Expand Down Expand Up @@ -173,9 +173,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The following npm packages may be included in this product:

- @yext/chat-core@0.5.3
- @yext/chat-headless-react@0.5.6
- @yext/chat-headless@0.5.6
- @yext/chat-core@0.7.0
- @yext/chat-headless-react@0.6.1
- @yext/chat-headless@0.7.1

These packages each contain the following license and notice below:

Expand Down Expand Up @@ -830,7 +830,7 @@ THE SOFTWARE.

The following npm package may be included in this product:

- layerr@2.0.0
- layerr@2.0.1

This package contains the following license and notice below:

Expand Down Expand Up @@ -1299,8 +1299,8 @@ SOFTWARE.

The following npm packages may be included in this product:

- react-redux@8.1.1
- redux-thunk@2.4.2
- react-redux@8.1.2
- redux@4.2.1

These packages each contain the following license and notice below:

Expand Down Expand Up @@ -1359,7 +1359,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

The following npm package may be included in this product:

- redux@4.2.1
- redux-thunk@2.4.2

This package contains the following license and notice below:

Expand Down Expand Up @@ -1786,7 +1786,7 @@ THE SOFTWARE.

The following npm package may be included in this product:

- ulidx@2.0.0
- ulidx@2.1.0

This package contains the following license and notice below:

Expand Down
2 changes: 1 addition & 1 deletion api-extractor.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<projectFolder>/tsconfig.json"
*/
"tsconfigFilePath": "<projectFolder>/tsconfig.esm.json"
"tsconfigFilePath": "<projectFolder>/tsconfig.json"
/**
* Provides a compiler configuration that will be used instead of reading the tsconfig.json file from disk.
* The object must conform to the TypeScript tsconfig schema:
Expand Down
4 changes: 2 additions & 2 deletions docs/chat-ui-react.chatheader.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A component that renders the header of a chat bot panel, including the title and
**Signature:**

```typescript
export declare function ChatHeader({ title, showRestartButton, restartButtonIcon, showCloseButton, closeButtonIcon, onClose, customCssClasses, }: ChatHeaderProps): import("react/jsx-runtime").JSX.Element;
export declare function ChatHeader({ title, showRestartButton, restartButtonIcon, showCloseButton, closeButtonIcon, onClose, customCssClasses, }: ChatHeaderProps): React.JSX.Element;
```

## Parameters
Expand All @@ -20,5 +20,5 @@ export declare function ChatHeader({ title, showRestartButton, restartButtonIcon

**Returns:**

import("react/jsx-runtime").JSX.Element
React.JSX.Element

4 changes: 2 additions & 2 deletions docs/chat-ui-react.chatinput.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A component that allows user to input message and send to Chat API.
**Signature:**

```typescript
export declare function ChatInput({ placeholder, stream, inputAutoFocus, handleError, sendButtonIcon, customCssClasses, }: ChatInputProps): import("react/jsx-runtime").JSX.Element;
export declare function ChatInput({ placeholder, stream, inputAutoFocus, handleError, sendButtonIcon, customCssClasses, }: ChatInputProps): React.JSX.Element;
```

## Parameters
Expand All @@ -20,7 +20,7 @@ export declare function ChatInput({ placeholder, stream, inputAutoFocus, handleE

**Returns:**

import("react/jsx-runtime").JSX.Element
React.JSX.Element

## Remarks

Expand Down
4 changes: 2 additions & 2 deletions docs/chat-ui-react.chatpanel.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A component that renders a full panel for chat bot interactions. This includes t
**Signature:**

```typescript
export declare function ChatPanel(props: ChatPanelProps): import("react/jsx-runtime").JSX.Element;
export declare function ChatPanel(props: ChatPanelProps): React.JSX.Element;
```

## Parameters
Expand All @@ -20,5 +20,5 @@ export declare function ChatPanel(props: ChatPanelProps): import("react/jsx-runt

**Returns:**

import("react/jsx-runtime").JSX.Element
React.JSX.Element

4 changes: 2 additions & 2 deletions docs/chat-ui-react.chatpopup.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A component that renders a popup button that displays and hides a panel for chat
**Signature:**

```typescript
export declare function ChatPopUp(props: ChatPopUpProps): import("react/jsx-runtime").JSX.Element;
export declare function ChatPopUp(props: ChatPopUpProps): React.JSX.Element;
```

## Parameters
Expand All @@ -20,5 +20,5 @@ export declare function ChatPopUp(props: ChatPopUpProps): import("react/jsx-runt

**Returns:**

import("react/jsx-runtime").JSX.Element
React.JSX.Element

4 changes: 2 additions & 2 deletions docs/chat-ui-react.messagebubble.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A component that displays the provided message.
**Signature:**

```typescript
export declare function MessageBubble({ message, showFeedbackButtons, showTimestamp, customCssClasses, formatTimestamp, }: MessageBubbleProps): import("react/jsx-runtime").JSX.Element;
export declare function MessageBubble({ message, showFeedbackButtons, showTimestamp, customCssClasses, formatTimestamp, }: MessageBubbleProps): React.JSX.Element;
```

## Parameters
Expand All @@ -20,5 +20,5 @@ export declare function MessageBubble({ message, showFeedbackButtons, showTimest

**Returns:**

import("react/jsx-runtime").JSX.Element
React.JSX.Element

14 changes: 6 additions & 8 deletions etc/chat-ui-react.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@
```ts

/// <reference types="react" />

import { JSX as JSX_2 } from 'react/jsx-runtime';
import { Message } from '@yext/chat-headless-react';
import { default as React_2 } from 'react';

// @public
export function ChatHeader({ title, showRestartButton, restartButtonIcon, showCloseButton, closeButtonIcon, onClose, customCssClasses, }: ChatHeaderProps): JSX_2.Element;
export function ChatHeader({ title, showRestartButton, restartButtonIcon, showCloseButton, closeButtonIcon, onClose, customCssClasses, }: ChatHeaderProps): React_2.JSX.Element;

// @public
export interface ChatHeaderCssClasses {
Expand Down Expand Up @@ -40,7 +38,7 @@ export interface ChatHeaderProps {
}

// @public
export function ChatInput({ placeholder, stream, inputAutoFocus, handleError, sendButtonIcon, customCssClasses, }: ChatInputProps): JSX_2.Element;
export function ChatInput({ placeholder, stream, inputAutoFocus, handleError, sendButtonIcon, customCssClasses, }: ChatInputProps): React_2.JSX.Element;

// @public
export interface ChatInputCssClasses {
Expand All @@ -63,7 +61,7 @@ export interface ChatInputProps {
}

// @public
export function ChatPanel(props: ChatPanelProps): JSX_2.Element;
export function ChatPanel(props: ChatPanelProps): React_2.JSX.Element;

// @public
export interface ChatPanelCssClasses {
Expand All @@ -88,7 +86,7 @@ export interface ChatPanelProps extends Omit<MessageBubbleProps, "customCssClass
}

// @public
export function ChatPopUp(props: ChatPopUpProps): JSX_2.Element;
export function ChatPopUp(props: ChatPopUpProps): React_2.JSX.Element;

// @public
export interface ChatPopUpCssClasses {
Expand Down Expand Up @@ -139,7 +137,7 @@ export interface FeedbackButtonsCssClasses {
}

// @public
export function MessageBubble({ message, showFeedbackButtons, showTimestamp, customCssClasses, formatTimestamp, }: MessageBubbleProps): JSX_2.Element;
export function MessageBubble({ message, showFeedbackButtons, showTimestamp, customCssClasses, formatTimestamp, }: MessageBubbleProps): React_2.JSX.Element;

// @public
export interface MessageBubbleCssClasses {
Expand Down
Loading

0 comments on commit ae1c856

Please sign in to comment.