web-dev-qa-db-ja.com

Webpackでtinymceをシムする方法は?

tinymce をwebpackに認識させようとしています。 tinymceという名前のプロパティをwindowに設定するので、明らかに1つのオプションは、このような構文を使用してrequire()することです( (EXPORTINGセクション のwebpackドキュメント):

_require("imports?window=>{}!exports?window.XModule!./file.js_

しかし、この例では、_./file.js_はどのように解決されますか? npm経由でtinymceをインストールしましたが、_tinymce.js_ファイルへの正しいパスを指定する方法がわかりません。

とにかく、構成でこれを処理し、可能であればrequire('tinymce')できるようにするため、_exports-loader_をインストールし、構成に以下を追加しました( に基づいて)この議論 ):

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

残念ながら、これは機能していません。私の構成の何が問題になっていますか?

13
Rob Johansen

Npmのtinymceモジュールは直接必要ではありませんが、ライブラリの4つの異なるディストリビューションが含まれています。すなわち:

  • _tinymce/tinymce.js_
  • _tinymce/tinymce.min.js_
  • _tinymce/tinymce.jquery.js_
  • _tinymce/tinymce.jquery.min.js_

コードでrequire('tinymce')を実行できるようにするには、webpack構成に エイリアス を追加し、選択したディストリビューション用のカスタムローダーを追加します。

_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',
    },
  ],
},
_

_tinymce/tinymce_を選択したディストリビューションに置き換えることができる場所。

10

@cchamberlainと同じように、tinymceにはスクリプトローダーを使用しましたが、デフォルトでは不要なプラグインやその他のリソースをロードするために、ES6ではなくCopyWebpackPluginを使用して構成可能なソリューションを作成しました。

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' }
    ])
  ]
};
8
Petri Ryhänen

Imports-loaderとexports-loaderおよびcopy-webpack-pluginを使用して、tinyMCEをAngular 2/TypeScriptベースのプロジェクトに統合できました。

まず、必要な依存関係が利用可能であり、プロジェクトのpackages.jsonファイルの一部であることを確認します。

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

次に、必要なローダーをwebpack構成のローダーセクションに追加します。

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

CopyWebpackPluginをWebpack構成で使用可能にするには、webpack構成ファイルのヘッダー部分にインポートします。

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

また、PetriRyhänenがコメントしたように、webpack構成のpluginsセクションに次のエントリを追加します。

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

この手順により、tinyMCEの(必須の)アドオンもWebパックで使用できるようになります。

最後に、tinyMCEをAngular 2コンポーネントファイルにインポートするには、

require('tinymce')

declare var tinymce: any;

インポートセクションにtinyMCEを使用する準備が整いました。

4
Florian Cremer

DOMで2つの個別のインスタンスを取得しないように、Reactとバンドルする方法と同様に動作するようになりました。インポート/エクスポート/ローダーの公開に問題があったため、代わりにスクリプトローダ。

私の設定では、ベンダーに限定して使用しているコモンズチャンクがあります(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'
                        ]
          }

これは、CDNのスクリプトを含めるのと同じように機能しますが、node_modulesの場所からテーマ/プラグイン/スキンパスを見つけることができなかったため、エラーが発生しました。パス/assets/plugins/assets/themes/assets/skins(webpackパブリックパス/assets/を使用)でそれらを探していました。

Expressをマッピングしてこれら2つのルートを静的に提供することで2番目の問題を解決しました(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))

これを実行すると、window.tinymce/window.tinyMCEの両方が定義され、CDNと同じ機能になります。

3
cchamberlain

この回答PetriRyhänen に感謝)の追加として、copyWebpackPlugintinymce.init()の構成調整を追加します。

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

この構成では、{output}/tinymce/skinフォルダー。

次に、このようにtinymceを初期化できます。

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
});

これにより、開発ビルドと実動ビルドの両方が正常に機能します。

1
Ruslan Zhomir