如何在webpack中填充tinymce?

时间:2015-05-29 06:47:09

标签: javascript node.js tinymce webpack shim

我试图通过webpack识别tinymce。它在tinymce上设置了一个名为window的属性,显然有一个选项是require()使用这样的语法(在webpack文档的EXPORTING section底部描述) :

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

但是在这个例子中,./file.js是如何解决的?我通过npm安装了tinymce,我无法弄清楚如何指定tinymce.js文件的正确路径。

无论如何,我宁愿在我的配置中处理此问题,并且如果可能的话只能require('tinymce'),所以我已经安装了exports-loader并在我的配置中添加了以下内容(基于在this discussion):

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

不幸的是,这不起作用。我的配置有什么问题?

6 个答案:

答案 0 :(得分:9)

npm上的tinymce模块不能直接使用,但包含4种不同的库分布。即:

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

为了能够在代码中执行require('tinymce'),您可以在webpack配置中添加an alias,以及为您选择的分发添加自定义加载程序。

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替换为您选择的分发。

答案 1 :(得分:8)

就像@cchamberlain一样,我最终使用脚本加载器来实现tinymce,但是为了加载默认情况下不需要的插件和其他资源,我使用了CopyWebpackPlugin而不是ES6来获得更多可配置的解决方案。

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

答案 2 :(得分:4)

我能够通过使用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'
            ]
        }]

要在webpack配置中使用copyWebpackPlugin,请将其导入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' }
    ])
]

此步骤确保您的webpack中还提供了(必需的)tinyMCE插件。

最后要在Angular 2组件文件中导入tinyMCE,添加

require('tinymce')

declare var tinymce: any;

到导入部分,tinyMCE即可使用。

答案 3 :(得分:3)

我的工作类似于我如何捆绑React以确保我不会在DOM中获得两个单独的实例。我有一些导入/导出/暴露加载器的问题,所以我使用了脚本加载器。

在我的设置中,我有一个公共块,我严格用于供应商(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/)。

我解决了第二个问题,通过映射表达静态服务这两条路径(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相同。

答案 4 :(得分:1)

作为this answer的补充(感谢Petri Ryhä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
});

有了这个,我的开发和生产版本都正常工作。

答案 5 :(得分:-1)

我们使用TinyMCE jQuery 4.1.6并且接受的答案对我们不起作用,因为window似乎在TinyMCE的其他位置使用(例如window.setTimeout)。另外,document未被填充似乎会导致问题。

这对我们有用:

alias: {
    'tinymce': 'tinymce/tinymce.jquery.js'
}

module: {
    loaders: [
        {
            test: /tinymce\/tinymce\.jquery\.js/,
            loader: 'imports?document=>window.document,this=>window!exports?window.tinymce'
        }
    ]
}

加载你的插件:

{
    test:  /tinymce\/plugins/,
    loader: 'imports?tinymce,this=>{tinymce:tinymce}'
}