如何在 webpack 中填充 tinymce?
How to shim tinymce in webpack?
我正在尝试获取 Webpack 文档的 tinymce recognized by webpack. It sets a property named tinymce
on window
, so evidently one option is to require()
it using syntax like this (described at the bottom of the 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'
}
]
}
不幸的是,这不起作用。我的配置有什么问题?
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
替换为您选择的发行版。
我们使用 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}'
}
我使它的工作方式类似于我捆绑 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 public 路径 /assets/
)。
我通过映射 express 静态地为这两条路由提供服务解决了第二个问题 (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 相同。
就像@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' }
])
]
};
我能够通过使用 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-section 中:
loaders: [
{
test: require.resolve('tinymce/tinymce'),
loaders: [
'imports?this=>window',
'exports?window.tinymce'
]
},
{
test: /tinymce\/(themes|plugins)\//,
loaders: [
'imports?this=>window'
]
}]
要使 copyWebpackPlugin 在您的 webpack 配置中可用,请将其导入 webpack 配置文件的 header 部分:
var copyWebpackPlugin = require('copy-webpack-plugin');
并且,正如 Petri Ryhänen 评论的那样,将以下条目添加到您的 webpack 配置的 plugins-section 中:
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 的(必需)插件在您的 webpack 中也可用。
最后要在 Angular 2 组件文件中导入 tinyMCE,添加
require('tinymce')
declare var tinymce: any;
到导入部分,tinyMCE 就可以使用了。
作为对 (thanks to Petri Ryhänen) 的补充,我想添加我的 copyWebpackPlugin
和 tinymce.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
});
有了这个,我的开发和生产构建都正常工作。
我正在尝试获取 Webpack 文档的 tinymce recognized by webpack. It sets a property named tinymce
on window
, so evidently one option is to require()
it using syntax like this (described at the bottom of the 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'
}
]
}
不幸的是,这不起作用。我的配置有什么问题?
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
替换为您选择的发行版。
我们使用 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}'
}
我使它的工作方式类似于我捆绑 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 public 路径 /assets/
)。
我通过映射 express 静态地为这两条路由提供服务解决了第二个问题 (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 相同。
就像@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' }
])
]
};
我能够通过使用 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-section 中:
loaders: [
{
test: require.resolve('tinymce/tinymce'),
loaders: [
'imports?this=>window',
'exports?window.tinymce'
]
},
{
test: /tinymce\/(themes|plugins)\//,
loaders: [
'imports?this=>window'
]
}]
要使 copyWebpackPlugin 在您的 webpack 配置中可用,请将其导入 webpack 配置文件的 header 部分:
var copyWebpackPlugin = require('copy-webpack-plugin');
并且,正如 Petri Ryhänen 评论的那样,将以下条目添加到您的 webpack 配置的 plugins-section 中:
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 的(必需)插件在您的 webpack 中也可用。
最后要在 Angular 2 组件文件中导入 tinyMCE,添加
require('tinymce')
declare var tinymce: any;
到导入部分,tinyMCE 就可以使用了。
作为对 copyWebpackPlugin
和 tinymce.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
});
有了这个,我的开发和生产构建都正常工作。