web-dev-qa-db-fra.com

Comment shim tinymce dans webpack?

J'essaie d'obtenir tinymce reconnu par webpack. Il définit une propriété nommée tinymce sur window. Il est donc évident que l'une des options consiste à require() en utilisant une syntaxe semblable à celle-ci (décrite au bas de la section EXPORTING des documents du webpack):

require("imports?window=>{}!exports?window.XModule!./file.js

Mais dans cet exemple, comment ./file.js est-il résolu? J'ai installé tinymce via npm et je ne vois pas comment spécifier le bon chemin d'accès au fichier tinymce.js.

Quoi qu'il en soit, je préférerais gérer cela dans ma configuration et pouvoir simplement utiliser require('tinymce') si possible. J'ai donc installé exports-loader et ajouté les éléments suivants à ma configuration (sur la base de this discussion ):

module: {
    loaders: [
        {
            test: /[\/]tinymce\.js$/,
            loader: 'exports?tinymce'
        }
    ]
}

Malheureusement cela ne fonctionne pas. Quel est le problème avec ma configuration?

12
Rob Johansen

Le module tinymce sur npm ne peut pas être requis directement, mais contient 4 distributions différentes de la bibliothèque. À savoir:

  • tinymce/tinymce.js
  • tinymce/tinymce.min.js
  • tinymce/tinymce.jquery.js
  • tinymce/tinymce.jquery.min.js

Pour pouvoir utiliser require('tinymce') dans votre code, vous pouvez ajouter un alias dans votre configuration de pack Web, ainsi qu'un chargeur personnalisé pour la distribution de votre choix.

resolve: {
  alias: {
    // require('tinymce') will do require('tinymce/tinymce') 
    tinymce: 'tinymce/tinymce',
  },
},
module: {
  loaders: [
    {
      // Only apply on tinymce/tinymce
      include: require.resolve('tinymce/tinymce'),
      // Export window.tinymce
      loader: 'exports?window.tinymce',
    },
  ],
},

Où vous pouvez remplacer tinymce/tinymce par la distribution de votre choix.

9

Tout comme @cchamberlain, j'ai fini par utiliser le chargeur de script pour tinymce, mais pour charger les plugins et autres ressources non requises par défaut, j'ai utilisé CopyWebpackPlugin au lieu de ES6 pour une solution plus configurable.

var copyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
//...
  plugins: [
    new copyWebpackPlugin([
      { from: './node_modules/tinymce/plugins', to: './plugins' },
      { from: './node_modules/tinymce/themes', to: './themes' },
      { from: './node_modules/tinymce/skins', to: './skins' }
    ])
  ]
};
7
Petri Ryhänen

J'ai été capable d'intégrer tinyMCE dans mon projet basé sur Angular 2/TypeScript en utilisant imports-loader et exports-loader et le plugin copy-webpack.

Premièrement, assurez-vous que les dépendances nécessaires sont disponibles et font partie du fichier packages.json de votre projet:

npm i tinymce --save
npm i exports-loader --save-dev
npm i imports-loader --save-dev    
npm i copy-webpack-plugin --save-dev

Ajoutez ensuite le chargeur requis à la section loaders de la configuration de votre pack Web:

    loaders: [          
        {
            test: require.resolve('tinymce/tinymce'),
            loaders: [
                'imports?this=>window',
                'exports?window.tinymce'
            ]
        },
        {
            test: /tinymce\/(themes|plugins)\//,
            loaders: [
                'imports?this=>window'
            ]
        }]

Pour que copyWebpackPlugin soit disponible dans la configuration de votre pack Web, importez-le dans l'en-tête du fichier de configuration du pack Web:

var copyWebpackPlugin = require('copy-webpack-plugin');

Et, comme l'a commenté Petri Ryhänen, ajoutez l'entrée suivante à la section plugins de la configuration de votre pack Web:

plugins: [
    new copyWebpackPlugin([
        { from: './node_modules/tinymce/plugins', to: './plugins' },
        { from: './node_modules/tinymce/themes', to: './themes' },
        { from: './node_modules/tinymce/skins', to: './skins' }
    ])
]

Cette étape garantit que les addons (obligatoires) de tinyMCE sont également disponibles dans votre pack Web.

Enfin, pour importer tinyMCE dans votre fichier de composant Angular 2, ajoutez 

require('tinymce')

declare var tinymce: any;

dans la section d'importation et tinyMCE est prêt à être utilisé.

4
Florian Cremer

Cela fonctionne de la même manière que je regroupe React pour m'assurer de ne pas obtenir deux instances distinctes dans DOM. J'ai eu quelques problèmes avec les chargeurs imports/exports/expose donc j'ai donc utilisé script-loader.

Dans ma configuration, j'ai un bloc commun que j'utilise strictement pour les vendeurs (React/tinymce).

   entry: { 'loading': '../src/app/entry/loading'
          , 'app':  '../src/app/entry/app'
          , 'timeout': '../src/app/entry/timeout'
          , 'commons':  [ 'expose?React!react'
                        , 'expose?ReactDOM!react-dom'
                        , 'script!tinymce/tinymce.min.js'
                        ]
          }

Cela fonctionne pour moi de la même manière que l'inclusion du script de CDN fonctionnerait, mais j'avais des erreurs car il ne pouvait pas trouver mes chemins themes/plugins/skins depuis mon emplacement node_modules. Il les cherchait dans les chemins /assets/plugins, /assets/themes, /assets/skins (j'utilise webpack chemin public /assets/).

J'ai résolu le second problème en mappant express pour desservir ces deux routes de manière statique comme ceci (es6):

  const NODE_MODULES_ROOT = path.resolve(__dirname, 'node_modules')
  const TINYMCE_PLUGINS_ROOT = path.join(NODE_MODULES_ROOT, 'tinymce/plugins')
  const TINYMCE_THEMES_ROOT = path.join(NODE_MODULES_ROOT, 'tinymce/themes')
  const TINYMCE_SKINS_ROOT = path.join(NODE_MODULES_ROOT, 'tinymce/skins')

  router.use('/assets/plugins', express.static(TINYMCE_PLUGINS_ROOT))
  router.use('/assets/themes', express.static(TINYMCE_THEMES_ROOT))
  router.use('/assets/skins', express.static(TINYMCE_SKINS_ROOT))

Cela fait, window.tinymce/window.tinyMCE sont définis et fonctionnent de la même manière que CDN.

3
cchamberlain

En complément de cette réponse (grâce à Petri Ryhänen ), je souhaite ajouter les réglages de configuration copyWebpackPlugin et tinymce.init() .

new copyWebpackPlugin([{
  context: './node_modules/tinymce/skins/lightgray',
  from: './**/*',
  to: './tinymce/skin',
}]),

Avec cette configuration, vous obtiendrez tous les fichiers de skin dans le dossier {output}/tinymce/skin.

Ensuite, vous pouvez initialiser tinymce comme ceci:

import tinymce from 'tinymce/tinymce';

// A theme is also required
import 'tinymce/themes/modern/theme';  // you may change to 'inlite' theme

// Any plugins you want to use has to be imported
import 'tinymce/plugins/advlist/plugin';
// ... possibly other plugins

// Then anywhere in this file you can:
tinymce.init({
  // ... possibly other options
  skin_url: '/tinymce/skin',  // <-- !!! here we tell tinymce where
                              //         to load skin files from
  // ... possibly other options
});

Avec cela, les versions de développement et de production fonctionnent normalement.

1
Ruslan Zhomir