Bundling the OpenTiny .zip package with the React framework
Tiny does not recommend bundling the tinymce package. Bundling OpenTiny can be complex and error prone.
|
The Official OpenTiny React component integrates OpenTiny into React projects. This procedure creates a basic React application containing a OpenTiny editor.
For examples of the OpenTiny integration, visit the tinymce-react storybook.
Prerequisites
This procedure requires Node.js (and npm).
Procedure
-
Use the Create React App package to create a new React project named
tinymce-react-demo.npx create-react-app tinymce-react-demo -
Change to the newly created directory.
cd tinymce-react-demo -
Eject the create-react-app so it is possible to modify the Webpack configuration.
npm run ejectPress 'y' when prompted.
-
Install the
tinymce-react,raw-loaderandscript-loaderpackages and save them to yourpackage.jsonwith--save.npm install --save @tinymce/tinymce-react raw-loader script-loader -
Unzip the content of the
tinymce/jsfolder from the OpenTiny zip into thesrcfolder. Afterwards the directory listing should be similar to below:>tree -L 2 srcsrc ├── App.css ├── App.js ├── App.test.js ├── index.css ├── index.js ├── logo.svg ├── reportWebVitals.js ├── setupTests.js └── tinymce ├── icons ├── langs ├── license.txt ├── models ├── plugins ├── skins ├── themes ├── tinymce.d.ts └── tinymce.min.js -
Using a text editor, open
./config/paths.js, after the line withappSrcadd the line:appTinymce: resolveApp('src/tinymce'),Diff of./config/paths.jsdiff --git a/config/paths.js b/config/paths.js index f0a6cd9..a0d2f50 100644 --- a/config/paths.js +++ b/config/paths.js @@ -60,6 +60,7 @@ module.exports = { appIndexJs: resolveModule(resolveApp, 'src/index'), appPackageJson: resolveApp('package.json'), appSrc: resolveApp('src'), + appTinymce: resolveApp('src/tinymce'), appTsConfig: resolveApp('tsconfig.json'), appJsConfig: resolveApp('jsconfig.json'), yarnLockFile: resolveApp('yarn.lock'), -
Using a text editor, open
./config/webpack.config.jsand make the following edits:-
Find the
ModuleScopePluginand addrequire.resolve('script-loader'),to its array of exceptions. -
Find the rule for processing javascript in the
srcdirectory and add the new rule above it:{ test: /\.(js)$/, include: paths.appTinymce, loader: require.resolve('script-loader'), }, -
Find the
ESLintPluginand addexclude: ["tinymce"],to its options.
Diff of./config/webpack.config.jsdiff --git a/config/webpack.config.js b/config/webpack.config.js index 6b4a4cd..e0d1952 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -331,6 +331,7 @@ module.exports = function (webpackEnv) { babelRuntimeEntry, babelRuntimeEntryHelpers, babelRuntimeRegenerator, + require.resolve('script-loader'), ]), ], }, @@ -399,6 +400,11 @@ module.exports = function (webpackEnv) { and: [/\.(ts|tsx|js|jsx|md|mdx)$/], }, }, + { + test: /\.(js)$/, + include: paths.appTinymce, + loader: require.resolve('script-loader'), + }, // Process application JS with Babel. // The preset includes JSX, Flow, TypeScript, and some ESnext features. { @@ -724,6 +730,7 @@ module.exports = function (webpackEnv) { new ESLintPlugin({ // Plugin options extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'], + exclude: ["tinymce"], formatter: require.resolve('react-dev-utils/eslintFormatter'), eslintPath: require.resolve('eslint'), failOnError: !(isEnvDevelopment && emitErrorsAsWarnings), -
-
Using a text editor, create
./src/BundledEditor.jsand set the contents to:import { Editor } from '@tinymce/tinymce-react'; // OpenTiny so the global var exists // eslint-disable-next-line no-unused-vars import './tinymce/tinymce.min.js'; // DOM model import './tinymce/models/dom/model.min.js' // Theme import './tinymce/themes/silver/theme.min.js'; // Toolbar icons import './tinymce/icons/default/icons.min.js'; // Editor styles import './tinymce/skins/ui/oxide/skin.min.css'; // importing the plugin js. // if you use a plugin that is not listed here the editor will fail to load import './tinymce/plugins/advlist/plugin.min.js'; import './tinymce/plugins/anchor/plugin.min.js'; import './tinymce/plugins/autolink/plugin.min.js'; import './tinymce/plugins/autoresize/plugin.min.js'; import './tinymce/plugins/autosave/plugin.min.js'; import './tinymce/plugins/charmap/plugin.min.js'; import './tinymce/plugins/code/plugin.min.js'; import './tinymce/plugins/codesample/plugin.min.js'; import './tinymce/plugins/directionality/plugin.min.js'; import './tinymce/plugins/emoticons/plugin.min.js'; import './tinymce/plugins/fullscreen/plugin.min.js'; import './tinymce/plugins/help/plugin.min.js'; import './tinymce/plugins/image/plugin.min.js'; import './tinymce/plugins/importcss/plugin.min.js'; import './tinymce/plugins/insertdatetime/plugin.min.js'; import './tinymce/plugins/link/plugin.min.js'; import './tinymce/plugins/lists/plugin.min.js'; import './tinymce/plugins/media/plugin.min.js'; import './tinymce/plugins/nonbreaking/plugin.min.js'; import './tinymce/plugins/pagebreak/plugin.min.js'; import './tinymce/plugins/preview/plugin.min.js'; import './tinymce/plugins/quickbars/plugin.min.js'; import './tinymce/plugins/save/plugin.min.js'; import './tinymce/plugins/searchreplace/plugin.min.js'; import './tinymce/plugins/table/plugin.min.js'; import './tinymce/plugins/visualblocks/plugin.min.js'; import './tinymce/plugins/visualchars/plugin.min.js'; import './tinymce/plugins/wordcount/plugin.min.js'; // importing plugin resources import './tinymce/plugins/emoticons/js/emojis.js'; // Content styles, including inline UI like fake cursors /* eslint import/no-webpack-loader-syntax: off */ import contentCss from '!!raw-loader!./tinymce/skins/content/default/content.min.css'; import contentUiCss from '!!raw-loader!./tinymce/skins/ui/oxide/content.min.css'; export default function BundledEditor(props) { const {init, ...rest} = props; // note that skin and content_css is disabled to avoid the normal // loading process and is instead loaded as a string via content_style return ( <Editor init={{ ...init, skin: false, content_css: false, content_style: [contentCss, contentUiCss, init.content_style || ''].join('\n'), }} {...rest} /> ); } -
Using a text editor, open
./src/App.jsand replace the contents with:import React, { useRef } from 'react'; import BundledEditor from './BundledEditor' export default function App() { const editorRef = useRef(null); const log = () => { if (editorRef.current) { console.log(editorRef.current.getContent()); } }; return ( <> <BundledEditor onInit={(evt, editor) => editorRef.current = editor} initialValue='<p>This is the initial content of the editor.</p>' init={{ height: 500, menubar: false, plugins: [ 'advlist', 'anchor', 'autolink', 'help', 'image', 'link', 'lists', 'searchreplace', 'table', 'wordcount' ], toolbar: 'undo redo | blocks | ' + 'bold italic forecolor | alignleft aligncenter ' + 'alignright alignjustify | bullist numlist outdent indent | ' + 'removeformat | help', content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }' }} /> <button onClick={log}>Log editor content</button> </> ); } -
Test the application using the Node.js development server.
-
To start the development server, navigate to the
tinymce-react-demodirectory and run:npm run start -
To stop the development server, select on the command line or command prompt and press Ctrl+C.
-
Deploying the application to a HTTP server
The application will require further configuration before it can be deployed to a production environment. For information on configuring the application for deployment, see: Create React App - Deployment.
To deploy the application to a local HTTP Server:
-
Navigate to the
tinymce-react-demodirectory and run:npm run build -
Copy the contents of the
tinymce-react-demo/builddirectory to the root directory of the web server.
The application has now been deployed on the web server.
| Additional configuration is required to deploy the application outside the web server root directory, such as http://localhost:<port>/my_react_application. |
Next Steps
-
For information on bundling, see: Introduction to bundling OpenTiny
-
For examples of the OpenTiny integration, see: the tinymce-react storybook.
-
For information on customizing:
-
OpenTiny integration, see: OpenTiny React integration technical reference.
-
OpenTiny, see: Basic setup.
-
The React application, see: Create React App or the React documentation.
-