Pārlūkot izejas kodu

perf[Tinymce]: dynamic import tinymce(#2102)

花裤衩 5 gadi atpakaļ
vecāks
revīzija
6770963672

+ 0 - 4
public/index.html

@@ -9,10 +9,6 @@
     <title><%= webpackConfig.name %></title>
   </head>
   <body>
-    <!-- import cdn js -->
-    <% for(var js of htmlWebpackPlugin.options.cdn.js) { %>
-      <script src="<%=js%>"></script>
-    <% } %>
     <div id="app"></div>
     <!-- built files will be auto injected -->
   </body>

+ 39 - 0
src/components/Tinymce/dynamicLoadScript.js

@@ -0,0 +1,39 @@
+const dynamicLoadScript = (src, callback) => {
+  const existingScript = document.getElementById(src)
+  const cb = callback || function() {}
+
+  if (!existingScript) {
+    const script = document.createElement('script')
+    script.src = src // src url for the third-party library being loaded.
+    script.id = src
+    document.body.appendChild(script)
+
+    const onEnd = 'onload' in script ? stdOnEnd : ieOnEnd
+    onEnd(script, cb)
+  }
+
+  if (existingScript && cb) cb(null, existingScript)
+
+  function stdOnEnd(script, cb) {
+    script.onload = function() {
+      // this.onload = null here is necessary
+      // because even IE9 works not like others
+      this.onerror = this.onload = null
+      cb(null, script)
+    }
+    script.onerror = function() {
+      this.onerror = this.onload = null
+      cb(new Error('Failed to load ' + src), script)
+    }
+  }
+
+  function ieOnEnd(script, cb) {
+    script.onreadystatechange = function() {
+      if (this.readyState !== 'complete' && this.readyState !== 'loaded') return
+      this.onreadystatechange = null
+      cb(null, script) // there is no way to catch loading errors in IE8
+    }
+  }
+}
+
+export default dynamicLoadScript

+ 18 - 2
src/components/Tinymce/index.vue

@@ -15,6 +15,10 @@
 import editorImage from './components/EditorImage'
 import plugins from './plugins'
 import toolbar from './toolbar'
+import load from './dynamicLoadScript'
+
+// why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one
+const tinymceCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js'
 
 export default {
   name: 'Tinymce',
@@ -82,10 +86,12 @@ export default {
     }
   },
   mounted() {
-    this.initTinymce()
+    this.init()
   },
   activated() {
-    this.initTinymce()
+    if (window.tinymce) {
+      this.initTinymce()
+    }
   },
   deactivated() {
     this.destroyTinymce()
@@ -94,6 +100,16 @@ export default {
     this.destroyTinymce()
   },
   methods: {
+    init() {
+      // dynamic load tinymce from cdn
+      load(tinymceCDN, (err) => {
+        if (err) {
+          this.$message.error(err.message)
+          return
+        }
+        this.initTinymce()
+      })
+    },
     initTinymce() {
       const _this = this
       window.tinymce.init({

+ 0 - 10
vue.config.js

@@ -57,16 +57,6 @@ module.exports = {
     }
   },
   chainWebpack(config) {
-    const cdn = {
-      // inject tinymce into index.html
-      // why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one
-      js: ['https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js']
-    }
-    config.plugin('html')
-      .tap(args => {
-        args[0].cdn = cdn
-        return args
-      })
     config.plugins.delete('preload') // TODO: need test
     config.plugins.delete('prefetch') // TODO: need test