Microsoft Bot framework is a popular framework used for creating bots.It provides a webchat interface to use as a user interface for web and mobile users.
It is developed in react,it comes with packages to be used directly in a webpage.But if you want to do some real customization,you have to use it in a react application.
This makes the package size of the deployed application bigger than usual.Which can be an issue if you are looking for better performance.
In this blog i will show you how we can build the webchat locally and do some modifications,so it can give us better performance
Assumptions
- I did not need the webchat speech ,so i have removed it,to make the package smaller
- I am using next js for my custom webchat application
First we will see with the default setup
to run webchat with react setup,we need to install botframework-webchat
npm install botframework-webchat
//import as a dynamic module so this will load only when it is needed
const ReactWebChat = dynamic(
() => {
return import('botframework-webchat');
},
{ ssr: false }
);
//the directline
let directLine = useMemo(() => createDirectLine({
secret: 'Mytoken',
domain: 'http://directline endpoint',
webSocket: true,
conversationId: 'conversationId',
pollingInterval: 2000
}), []);
//redux store
let store=useMemo(() => createStore({}, ({ dispatch }) => next => action => {
if (action.type === 'DIRECT_LINE/POST_ACTIVITY') {
//your code here
}
}), []);
<ReactWebChat directLine={directLine}
userID={userId}
username={userName}
locale='en-us'
sendTypingIndicator={true}
resize="detect"
bot={bot}
styleOptions={styleOptionsState}
store={store}
/>
With this setup we can run the chat app,for details you can check an example from Microsoft-Webchat
Next configuration
Install Dev Dependencies
- @next/bundle-analyzer - this we will use to analyse the bundles
- duplicate-package-checker-webpack-plugin - this we use to find out duplicate packages
- next-transpile-modules - transpile modules for IE11 support
- cross-env - to be used in windows
Analyse the app
to analyse the package footprint,we will use following in scripts of package.json
"analyse": "cross-env ANALYZE=true next build"
inside next.config
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
})
const config={
future: {
webpack5: true,
},
}
then run
npm run-script analyse
For my setup this is what i get
Check how botframework-webchat-api/lib is taking a lot of space for localisations.
and also how big the microsoft-cognitiveservices-speech-sdk distribution is taking,if we don't need speech then we can remove it too,so lets clean them up
Lets Make it small
Minimize botframework-webchat-api
- First we will copy the botframework-webchat-api folder from node_modules to our local directory
- Remove the locale references we dont need
from botframework-webchat-api\src\localization\getAllLocalizedStrings.ts ,remove all languages except what you need ,in my case only i need en_US
// Strings commented out are pending official translations
import enUS from './en-US.json';
import bundledOverrides from './overrides.json';
import LocalizedStrings from '../types/LocalizedStrings';
import mergeLocalizedStrings from './mergeLocalizedStrings';
let localizedStrings;
function getAllLocalizedStrings(): { [language: string]: LocalizedStrings } {
return (
localizedStrings ||
(localizedStrings = mergeLocalizedStrings(
{
'en-US': enUS,
},
bundledOverrides
))
);
}
export default getAllLocalizedStrings;
- Then from botframework-webchat-api\src\localization\overrides.json,just keep what you need,in my case it is en_US
{
"en-US": {
"COGNITIVE_SERVICES_SPEECH_TO_TEXT": true,
"COGNITIVE_SERVICES_TEXT_TO_SPEECH": "neural",
"GLOBALIZE_LANGUAGE": "en",
"SPEECH_LANGUAGE": "en-US"
}
}
- Build
npm i
npm run-script build
Remove microsoft-cognitiveservices-speech-sdk
- Copy the botframework-webchat folder from node_modules
- from webpack config remove
react: resolve(__dirname, '../isomorphic-react/dist/react.js'),
react-dom': resolve(__dirname, '../isomorphic-react-dom/dist/react-dom.js')
- from package.json remove
"isomorphic-react": "4.13.0",
"isomorphic-react-dom": "4.13.0",
"microsoft-cognitiveservices-speech-sdk": "1.15.1",
"botframework-directlinespeech-sdk": "4.13.0",
from src/index.ts
comment reference for createCognitiveServicesSpeechServicesPonyfillFactory,createDirectLineSpeechAdaptersBuild
npm i
npm run-script build
remove node_modules from botframework-webchat-api,botframework-webchat
in next config
config.resolve.alias['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'
),
config.resolve.alias['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'
),
config.resolve.alias['microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common/Exports']= resolve(
__dirname,
'node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common/Exports.js'
),
config.resolve.alias['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'
),
config.resolve.alias['microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/Exports']= resolve(
__dirname,
'node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/Exports.js'
),
config.resolve.alias['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.
config.resolve.alias['microsoft-cognitiveservices-speech-sdk']= resolve(
__dirname,
'node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/microsoft.cognitiveservices.speech.sdk.js'
),
config.resolve.alias['botframework-webchat-api'] = resolve(
__dirname,
'botframework-webchat-api'
)
config.resolve.alias['botframework-webchat'] = resolve(
__dirname,
'botframework-webchat'
)
Now lets run again
npm run-script analyse
This is what i get
Thats'it
We have decreased the size of our packages,
Bonus
For decreasing packages for lodash or moment you can use following
for moment inside next config
config.plugins.push(new webpack.IgnorePlugin({
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/,
}))
for lodash,use in your code like
import cloneDeep from 'lodash/cloneDeep';
import isEmpty from 'lodash/isEmpty';
To transpile for IE11
const withTM = require('next-transpile-modules')(['react-markdown', 'react-markdown/node_modules/is-plain-obj',
'postcss','sanitize-html','sanitize-html/node_modules/escape-string-regexp']);
let withAnalyzer = withBundleAnalyzer(config)
let final = withAnalyzer
if (!process.env.NODE_ENV || process.env.NODE_ENV === 'production') {
final = withTM(withAnalyzer)
}
To find duplicate packages
const DuplicatePackageCheckerPlugin = require('duplicate-package-checker-webpack-plugin')
config.plugins.push(new DuplicatePackageCheckerPlugin())
// then you can use for duplicate packages,to pickup only from default path
config.resolve.alias['core-js'] = resolve(
__dirname,
'node_modules',
'core-js'
)
To see errors in chrome console with proper source code use
config.optimization.minimize = false
Top comments (0)