稍微修改 resourceRegExp 时 NormalModuleReplacementPlugin 不起作用
NormalModuleReplacementPlugin does not work when modifying resourceRegExp slightly
正如 CKEditor5 homepage 上的官方建议,我想替换几个插件预装的标准图标。
由于每个插件(例如 ckeditor5-core 或 ckeditor5-alignment)在 [PLUGIN_DIR]/theme/icons 中提供了自己的 .svg
集,因此建议的策略 - 用自己的修改替换它们 - 是可以理解的并清除:
(...) use webpack’s NormalModuleReplacementPlugin plugin
...
plugins: [
new webpack.NormalModuleReplacementPlugin(
/bold\.svg/,
'/absolute/path/to/my/icon.svg'
)
]
基于这段代码,我进行了实验并得到了以下结果:
...
plugins: [
new webpack.NormalModuleReplacementPlugin(
/\/theme\/icons\/[^/]+\.svg$/,
resource => {
console.log(resource.request);
resource.request = path.resolve(
THEME_PATH,
"../../icons/coffee-solid.svg"
);
}
),
]
导致以下 (wanted/expected) 变化:
before
after
部分控制台输出:
../../theme/icons/bold.svg
../../theme/icons/italic.svg
@ckeditor/ckeditor5-core/theme/icons/quote.svg
@ckeditor/ckeditor5-core/theme/icons/image.svg
../theme/icons/numberedlist.svg
../theme/icons/bulletedlist.svg
../theme/icons/align-justify.svg
../theme/icons/link.svg
(node:10394) DeprecationWarning: Chunk.mapModules: Use Array.from(chunk.modulesIterable, fn) instead
@ckeditor/ckeditor5-core/theme/icons/object-right.svg
@ckeditor/ckeditor5-core/theme/icons/object-center.svg
@ckeditor/ckeditor5-core/theme/icons/object-left.svg
@ckeditor/ckeditor5-core/theme/icons/object-full-width.svg
@ckeditor/ckeditor5-core/theme/icons/low-vision.svg
../theme/icons/drag-handler.svg
@ckeditor/ckeditor5-core/theme/icons/cancel.svg
../theme/icons/redo.svg
../../../theme/icons/next-arrow.svg
../../../theme/icons/previous-arrow.svg
../theme/icons/undo.svg
../../../theme/icons/dropdown-arrow.svg
@ckeditor/ckeditor5-core/theme/icons/cancel.svg
@ckeditor/ckeditor5-core/theme/icons/check.svg
@ckeditor/ckeditor5-core/theme/icons/check.svg
@ckeditor/ckeditor5-core/theme/icons/pencil.svg
../../theme/icons/unlink.svg
../../theme/icons/image_placeholder.svg
../theme/icons/align-center.svg
../theme/icons/align-right.svg
../theme/icons/align-left.svg
但是,当我想通过相应的正则表达式将文件夹限制为@ckeditor 时,会发生以下情况:
...
plugins: [
new webpack.NormalModuleReplacementPlugin(
/ckeditor5-[^/]+\/theme\/icons\/[^/]+\.svg$/,
resource => {
console.log(resource.request);
resource.request = path.resolve(
THEME_PATH,
"../../icons/coffee-solid.svg"
);
}
),
]
之前(见上文)
after
部分控制台输出(2):
@ckeditor/ckeditor5-core/theme/icons/quote.svg
@ckeditor/ckeditor5-core/theme/icons/image.svg
(node:10368) DeprecationWarning: Chunk.mapModules: Use Array.from(chunk.modulesIterable, fn) instead
@ckeditor/ckeditor5-core/theme/icons/object-right.svg
@ckeditor/ckeditor5-core/theme/icons/object-center.svg
@ckeditor/ckeditor5-core/theme/icons/object-left.svg
@ckeditor/ckeditor5-core/theme/icons/object-full-width.svg
@ckeditor/ckeditor5-core/theme/icons/low-vision.svg
@ckeditor/ckeditor5-core/theme/icons/pencil.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/bold.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/italic.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-list/theme/icons/numberedlist.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-list/theme/icons/bulletedlist.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-alignment/theme/icons/align-justify.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-link/theme/icons/link.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-widget/theme/icons/drag-handler.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-undo/theme/icons/redo.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-undo/theme/icons/undo.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-ui/theme/icons/next-arrow.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-ui/theme/icons/previous-arrow.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-ui/theme/icons/dropdown-arrow.svg
@ckeditor/ckeditor5-core/theme/icons/cancel.svg
@ckeditor/ckeditor5-core/theme/icons/check.svg
@ckeditor/ckeditor5-core/theme/icons/cancel.svg
@ckeditor/ckeditor5-core/theme/icons/check.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-link/theme/icons/unlink.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-alignment/theme/icons/align-center.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-alignment/theme/icons/align-right.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-alignment/theme/icons/align-left.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-image/theme/icons/image_placeholder.svg
为什么会这样?
注意:我必须使用带资源的语法(据我所知是唯一的其他选择),因为我想稍后动态加载图标。
正如我在 https://github.com/ckeditor/ckeditor5/issues/1831 中的回答:
正如您在 NormalModuleReplacementPlugin
的源代码中看到的那样,正则表达式被测试了两次,一次是在请求解析之前,一次是在资源解析之后。
正如您可能看到的那样,大多数时候您的函数在解析后被调用(因为请求与正则表达式不匹配)。加载程序增强了解析后的请求(这就是路径如此长且包含奇怪字符的原因),实际上,不再使用此选项。这就是为什么您应该更改 result.resource
而不是 result.request
.
例如尝试以下插件:
new webpack.NormalModuleReplacementPlugin(
/ckeditor5-[^/]+\/theme\/icons\/bold\.svg/,
result => {
if ( result.resource ) {
result.resource = result.resource.replace( 'bold', 'code' );
}
}
)
也许下面的片段对每个想要的人都有用
完全控制 CKEditor5 的外观。
/*
THEME_PATH := path to your theme folder (that contains /theme/theme.css)
-> see https://github.com/ckeditor/ckeditor5-theme-lark (use it as a template)
Both REPLACE_ICONS_REGEXP and replaceIcons should be use as described above
*/
const REPLACE_ICONS_REGEXP = /ckeditor5-[^/]+\/theme\/icons\/[^/]+\.svg$/;
function replaceIcons(resource) {
{
const [, ckeditorPlugin, svgFileToReplace] = resource.request.match(
/(ckeditor5-[^/]+)\/theme\/icons\/([^/]+\.svg)$/
);
const designatedSvgPath = path.resolve(
THEME_PATH,
`../../icons/${svgFileToReplace}`
);
try {
fs.accessSync(designatedSvgPath, fs.constants.F_OK);
resource.resource = designatedSvgPath; // as ma2ciek suggested
} catch (err) {
try {
// Create mock file to be replaced with themed svg
fs.writeFileSync(
path.resolve(THEME_PATH, `../../icons/_${svgFileToReplace}`),
""
);
} catch (err) {
err.message =
`Unable to create icon mock file for ${ckeditorPlugin}.\n` +
err.message;
throw err;
}
}
}
}
对于 ckeditor5 和 webpack5,我对自定义 ckeditor 图标的实现:
const customCKEditorIcons = ['bold', 'italic'];
new webpack.NormalModuleReplacementPlugin(/ckeditor5-[^/]+\/theme\/icons\/[^/]+\.svg$/, result => {
const resource = result.createData.resource;
if (resource) {
const iconNamePaths = resource.split('/');
const iconName = iconNamePaths[iconNamePaths.length - 1].split('.')[0];
if (customCKEditorIcons.includes(iconName)) {
result.createData.resource = path.resolve(
__dirname,
`path/to/${iconName}.svg`,
);
}
}
}),
正如 CKEditor5 homepage 上的官方建议,我想替换几个插件预装的标准图标。
由于每个插件(例如 ckeditor5-core 或 ckeditor5-alignment)在 [PLUGIN_DIR]/theme/icons 中提供了自己的 .svg
集,因此建议的策略 - 用自己的修改替换它们 - 是可以理解的并清除:
(...) use webpack’s NormalModuleReplacementPlugin plugin
...
plugins: [
new webpack.NormalModuleReplacementPlugin(
/bold\.svg/,
'/absolute/path/to/my/icon.svg'
)
]
基于这段代码,我进行了实验并得到了以下结果:
...
plugins: [
new webpack.NormalModuleReplacementPlugin(
/\/theme\/icons\/[^/]+\.svg$/,
resource => {
console.log(resource.request);
resource.request = path.resolve(
THEME_PATH,
"../../icons/coffee-solid.svg"
);
}
),
]
导致以下 (wanted/expected) 变化: before after
部分控制台输出:
../../theme/icons/bold.svg
../../theme/icons/italic.svg
@ckeditor/ckeditor5-core/theme/icons/quote.svg
@ckeditor/ckeditor5-core/theme/icons/image.svg
../theme/icons/numberedlist.svg
../theme/icons/bulletedlist.svg
../theme/icons/align-justify.svg
../theme/icons/link.svg
(node:10394) DeprecationWarning: Chunk.mapModules: Use Array.from(chunk.modulesIterable, fn) instead
@ckeditor/ckeditor5-core/theme/icons/object-right.svg
@ckeditor/ckeditor5-core/theme/icons/object-center.svg
@ckeditor/ckeditor5-core/theme/icons/object-left.svg
@ckeditor/ckeditor5-core/theme/icons/object-full-width.svg
@ckeditor/ckeditor5-core/theme/icons/low-vision.svg
../theme/icons/drag-handler.svg
@ckeditor/ckeditor5-core/theme/icons/cancel.svg
../theme/icons/redo.svg
../../../theme/icons/next-arrow.svg
../../../theme/icons/previous-arrow.svg
../theme/icons/undo.svg
../../../theme/icons/dropdown-arrow.svg
@ckeditor/ckeditor5-core/theme/icons/cancel.svg
@ckeditor/ckeditor5-core/theme/icons/check.svg
@ckeditor/ckeditor5-core/theme/icons/check.svg
@ckeditor/ckeditor5-core/theme/icons/pencil.svg
../../theme/icons/unlink.svg
../../theme/icons/image_placeholder.svg
../theme/icons/align-center.svg
../theme/icons/align-right.svg
../theme/icons/align-left.svg
但是,当我想通过相应的正则表达式将文件夹限制为@ckeditor 时,会发生以下情况:
...
plugins: [
new webpack.NormalModuleReplacementPlugin(
/ckeditor5-[^/]+\/theme\/icons\/[^/]+\.svg$/,
resource => {
console.log(resource.request);
resource.request = path.resolve(
THEME_PATH,
"../../icons/coffee-solid.svg"
);
}
),
]
之前(见上文)
after
部分控制台输出(2):
@ckeditor/ckeditor5-core/theme/icons/quote.svg
@ckeditor/ckeditor5-core/theme/icons/image.svg
(node:10368) DeprecationWarning: Chunk.mapModules: Use Array.from(chunk.modulesIterable, fn) instead
@ckeditor/ckeditor5-core/theme/icons/object-right.svg
@ckeditor/ckeditor5-core/theme/icons/object-center.svg
@ckeditor/ckeditor5-core/theme/icons/object-left.svg
@ckeditor/ckeditor5-core/theme/icons/object-full-width.svg
@ckeditor/ckeditor5-core/theme/icons/low-vision.svg
@ckeditor/ckeditor5-core/theme/icons/pencil.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/bold.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/italic.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-list/theme/icons/numberedlist.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-list/theme/icons/bulletedlist.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-alignment/theme/icons/align-justify.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-link/theme/icons/link.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-widget/theme/icons/drag-handler.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-undo/theme/icons/redo.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-undo/theme/icons/undo.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-ui/theme/icons/next-arrow.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-ui/theme/icons/previous-arrow.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-ui/theme/icons/dropdown-arrow.svg
@ckeditor/ckeditor5-core/theme/icons/cancel.svg
@ckeditor/ckeditor5-core/theme/icons/check.svg
@ckeditor/ckeditor5-core/theme/icons/cancel.svg
@ckeditor/ckeditor5-core/theme/icons/check.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-link/theme/icons/unlink.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-alignment/theme/icons/align-center.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-alignment/theme/icons/align-right.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-alignment/theme/icons/align-left.svg
[PATH_TO_WS]/workspace/my-cute-editor/node_modules/raw-loader/dist/cjs.js![PATH_TO_WS]/workspace/my-cute-editor/node_modules/@ckeditor/ckeditor5-image/theme/icons/image_placeholder.svg
为什么会这样?
注意:我必须使用带资源的语法(据我所知是唯一的其他选择),因为我想稍后动态加载图标。
正如我在 https://github.com/ckeditor/ckeditor5/issues/1831 中的回答:
正如您在 NormalModuleReplacementPlugin
的源代码中看到的那样,正则表达式被测试了两次,一次是在请求解析之前,一次是在资源解析之后。
正如您可能看到的那样,大多数时候您的函数在解析后被调用(因为请求与正则表达式不匹配)。加载程序增强了解析后的请求(这就是路径如此长且包含奇怪字符的原因),实际上,不再使用此选项。这就是为什么您应该更改 result.resource
而不是 result.request
.
例如尝试以下插件:
new webpack.NormalModuleReplacementPlugin(
/ckeditor5-[^/]+\/theme\/icons\/bold\.svg/,
result => {
if ( result.resource ) {
result.resource = result.resource.replace( 'bold', 'code' );
}
}
)
也许下面的片段对每个想要的人都有用 完全控制 CKEditor5 的外观。
/*
THEME_PATH := path to your theme folder (that contains /theme/theme.css)
-> see https://github.com/ckeditor/ckeditor5-theme-lark (use it as a template)
Both REPLACE_ICONS_REGEXP and replaceIcons should be use as described above
*/
const REPLACE_ICONS_REGEXP = /ckeditor5-[^/]+\/theme\/icons\/[^/]+\.svg$/;
function replaceIcons(resource) {
{
const [, ckeditorPlugin, svgFileToReplace] = resource.request.match(
/(ckeditor5-[^/]+)\/theme\/icons\/([^/]+\.svg)$/
);
const designatedSvgPath = path.resolve(
THEME_PATH,
`../../icons/${svgFileToReplace}`
);
try {
fs.accessSync(designatedSvgPath, fs.constants.F_OK);
resource.resource = designatedSvgPath; // as ma2ciek suggested
} catch (err) {
try {
// Create mock file to be replaced with themed svg
fs.writeFileSync(
path.resolve(THEME_PATH, `../../icons/_${svgFileToReplace}`),
""
);
} catch (err) {
err.message =
`Unable to create icon mock file for ${ckeditorPlugin}.\n` +
err.message;
throw err;
}
}
}
}
对于 ckeditor5 和 webpack5,我对自定义 ckeditor 图标的实现:
const customCKEditorIcons = ['bold', 'italic'];
new webpack.NormalModuleReplacementPlugin(/ckeditor5-[^/]+\/theme\/icons\/[^/]+\.svg$/, result => {
const resource = result.createData.resource;
if (resource) {
const iconNamePaths = resource.split('/');
const iconName = iconNamePaths[iconNamePaths.length - 1].split('.')[0];
if (customCKEditorIcons.includes(iconName)) {
result.createData.resource = path.resolve(
__dirname,
`path/to/${iconName}.svg`,
);
}
}
}),