/

ckeditor富文本应用(npm打包)(二)

这篇主要记录npm方式打包,我希望可以把ckeditor打包成一个js文件,然后在打开当前页面的时候才引入打包的js,这样对项目侵入较少。我还可以在项目中进行配置。
npm打包方式 我在上面的方法上做了简单修改。

package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
"scripts": { "build": "webpack --mode development", "build:prod": "webpack --mode production" }, "dependencies": { "@ckeditor/ckeditor5-adapter-ckfinder": "^38.1.0", "@ckeditor/ckeditor5-alignment": "^38.1.0", "@ckeditor/ckeditor5-autoformat": "^38.1.0", "@ckeditor/ckeditor5-autosave": "^38.1.0", "@ckeditor/ckeditor5-basic-styles": "^38.1.0", "@ckeditor/ckeditor5-block-quote": "^38.1.0", "@ckeditor/ckeditor5-build-decoupled-document": "^38.1.0", "@ckeditor/ckeditor5-core": "^38.1.0", "@ckeditor/ckeditor5-dev-utils": "^38.1.1", "@ckeditor/ckeditor5-editor-decoupled": "^38.1.0", "@ckeditor/ckeditor5-essentials": "^38.1.0", "@ckeditor/ckeditor5-font": "^38.1.0", "@ckeditor/ckeditor5-heading": "^38.1.0", "@ckeditor/ckeditor5-image": "^38.1.0", "@ckeditor/ckeditor5-indent": "^38.1.0", "@ckeditor/ckeditor5-inspector": "^4.1.0", "@ckeditor/ckeditor5-link": "^38.1.0", "@ckeditor/ckeditor5-list": "^38.1.0", "@ckeditor/ckeditor5-media-embed": "^38.1.0", "@ckeditor/ckeditor5-paragraph": "^38.1.0", "@ckeditor/ckeditor5-paste-from-office": "^38.1.0", "@ckeditor/ckeditor5-remove-format": "^38.1.0", "@ckeditor/ckeditor5-restricted-editing": "^38.1.0", "@ckeditor/ckeditor5-table": "^38.1.0", "@ckeditor/ckeditor5-theme-lark": "^38.1.0", "@ckeditor/ckeditor5-typing": "^38.1.0", "@ckeditor/ckeditor5-ui": "^38.1.0", "@ckeditor/ckeditor5-utils": "^38.1.0", "@ckeditor/ckeditor5-widget": "^38.1.0", "css-loader": "^6.8.1", "postcss-loader": "^7.3.3", "raw-loader": "^4.0.2", "webpack": "^5.88.1", "webpack-cli": "^5.1.4" }

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
'use strict'; const path = require( 'path' ); const { styles } = require( '@ckeditor/ckeditor5-dev-utils' ); module.exports = { entry: './app.js', output: { path: path.resolve( __dirname, 'dist' ), filename: 'bundle.js', library: '$editor', window.$editor这样的方式使用 libraryTarget: 'umd' }, module: { rules: [ { test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/, use: [ 'raw-loader' ] }, { test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/, use: [ { loader: 'style-loader', options: { injectType: 'singletonStyleTag', attributes: { 'data-cke': true } } }, 'css-loader', { loader: 'postcss-loader', options: { postcssOptions: styles.getPostCssConfig( { themeImporter: { themePath: require.resolve( '@ckeditor/ckeditor5-theme-lark' ) }, minify: true } ) } } ] }, ] }, devtool: 'source-map', performance: { hints: false } };

app.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
export { DecoupledEditor, Essentials, UploadAdapter, Autosave, Paragraph, Heading, Bold, Italic,Underline, Strikethrough, Code, Subscript, Superscript, Alignment, Autoformat, BlockQuote, ListProperties , TodoList, Link, MediaEmbed, PasteFromOffice, Table, TableToolbar, TextTransformation, Indent, RestrictedEditingMode, StandardEditingMode, Font, RemoveFormat, Image, ImageToolbar, ImageCaption, ImageStyle, ImageResizeEditing, ImageResizeHandles,ImageResizeButtons, ImageInsert,AutoImage, }

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<div id="toolbar-container"></div> <div id="editor"></div> <script src="dist/bundle.js"></script> <script> window.$editor.DecoupledEditor .create(document.querySelector('#editor'), { plugins: [ window.$editor.Essentials, window.$editor.UploadAdapter, window.$editor.Autosave, window.$editor.Paragraph, window.$editor.Heading, window.$editor.Bold, window.$editor.Italic, window.$editor.Underline, window.$editor.Strikethrough, window.$editor.Code, window.$editor.Subscript, window.$editor.Superscript, window.$editor.Alignment, window.$editor.Autoformat, window.$editor.BlockQuote, window.$editor.ListProperties, window.$editor.TodoList, window.$editor.Link, window.$editor.MediaEmbed, window.$editor.PasteFromOffice, window.$editor.Table, window.$editor.TableToolbar, window.$editor.TextTransformation, window.$editor.Indent, window.$editor.Font, window.$editor.RemoveFormat, // window.$editor.RestrictedEditingMode, // window.$editor.StandardEditingMode, window.$editor.Image, window.$editor.ImageToolbar, window.$editor.ImageCaption, window.$editor.ImageStyle, window.$editor.ImageInsert, window.$editor.ImageResizeEditing, window.$editor.ImageResizeHandles, window.$editor.ImageResizeButtons, window.$editor.AutoImage, ], toolbar: { items: [ 'undo', 'redo', 'heading', '|', 'bold', 'italic', 'underline', 'strikethrough', 'code', 'subscript', 'superscript', 'removeFormat', '|', 'fontFamily', 'fontSize', 'fontColor', 'fontBackgroundColor', '|', 'alignment', 'link', 'bulletedList', 'numberedList', 'todoList', '|', // 'restrictedEditing','restrictedEditingException', '|', 'outdent', 'indent', '|', 'insertImage', 'resizeImage', 'blockQuote', 'insertTable', 'mediaEmbed', 'simpleBox' ], shouldNotGroupWhenFull: true }, image: { resizeOptions: [ { name: 'resizeImage:original', value: null, icon: 'original' }, { name: 'resizeImage:50', value: '50', icon: 'medium' }, { name: 'resizeImage:75', value: '75', icon: 'large' } ], toolbar: [ 'imageStyle:inline', 'imageStyle:block', 'imageStyle:side', '|', 'toggleImageCaption', 'imageTextAlternative', '|', 'resizeImage', ] }, autosave: { save(editor) { return new AutoSaveData().save(editor.getData()) }, waitingTime: 2000 }, language: 'cn', placeholder: 'Type the content here!', extraPlugins: [MyCustomUploadAdapterPlugin], updateSourceElementOnDestroy: true }) .then(editor => { // eslint-disable-next-line no-console console.log(Array.from(editor.ui.componentFactory.names())) // CKEditorInspector.attach(editor) const toolbarContainer = document.getElementById('toolbar-container') const toolbarElement = editor.ui.view.toolbar.element; toolbarContainer.appendChild(toolbarElement) // 启用只读模式 editor.on('change:isReadOnly', (evt, propertyName, isReadOnly) => { if (isReadOnly) { toolbarElement.style.display = 'none'; } else { toolbarElement.style.display = 'flex'; } }); this.editor = editor }) .catch(error => { console.error(error.stack) }) </script>

文件上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
class MyUploadAdapter { constructor(loader) { this.loader = loader } upload() { return this.loader.file .then(file => new Promise((resolve, reject) => { this._initRequest(); this._initListeners(resolve, reject, file); this._sendRequest(file); })); } abort() { if (this.xhr) { this.xhr.abort(); } } _initRequest() { const xhr = this.xhr = new XMLHttpRequest(); xhr.open('POST', 'http://example.com/image/upload/path', true); xhr.responseType = 'json'; } _initListeners(resolve, reject, file) { const xhr = this.xhr; const loader = this.loader; const genericErrorText = `上传失败: ${file.name}.`; xhr.addEventListener('error', () => reject(genericErrorText)); xhr.addEventListener('abort', () => reject()); xhr.addEventListener('load', () => { const response = xhr.response; if (!response || response.error) { return reject(response && response.error ? response.error.message : genericErrorText); } resolve({ default: response.url }); }); if (xhr.upload) { xhr.upload.addEventListener('progress', evt => { if (evt.lengthComputable) { loader.uploadTotal = evt.total; loader.uploaded = evt.loaded; } }); } } _sendRequest(file) { const data = new FormData(); data.append('upload', file); this.xhr.send(data); } } export default function MyCustomUploadAdapterPlugin(editor) { editor.plugins.get('FileRepository').createUploadAdapter = (loader) => { return new MyUploadAdapter(loader); }; }
作者:liuk123标签:js分类:javascript

本文是原创文章,采用 CC BY-NC-ND 4.0 协议, 完整转载请注明来自 liuk123