项目优化:动态引入JS文件

2023-02-15  本文已影响0人  不愿透露姓名的董师傅

在使用AWS SDK的时候,使用npm安装并引入,发现会导致打包过大,这里使用动态按需加载的方式引入SDK解决该问题。

原来的引入方式

import AWS from 'aws-sdk'
// ...

优化后

import load from '@/utils/load-cdn-js'
const awsCDN = 'https://sdk.amazonaws.com/js/aws-sdk-2.1072.0.min.js'
export defaulat {
    // ...
    created() {
        this.init()
    },
    methods: {
        init() {
            load(awsCDN, (err) => {
                if (err) {
                    this.$message.error(err.message)
                    return
                }
                this.initS3Upload()
            }, 'AWS')
        },
    }
}

load-cdn-js.js

let callbacksObj = {}

function loadJS(name) {
    // to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2144
    // check is successfully downloaded script
    return window[name]
}

const dynamicLoadScript = (src, callback, name) => {
    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)
        callbacksObj[name] = []
        callbacksObj[name].push(cb)
        const onEnd = 'onload' in script ? stdOnEnd : ieOnEnd
        onEnd(script)
    }

    if (existingScript && cb) {
        if (loadJS(name)) {
            cb(null, existingScript)
        } else {
            callbacksObj[name].push(cb)
        }
    }

    function stdOnEnd(script) {
        script.onload = function () {
            // this.onload = null here is necessary
            // because even IE9 works not like others
            this.onerror = this.onload = null
            for (const cb of callbacksObj[name]) {
                cb(null, script)
            }
            callbacksObj[name] = null
        }
        script.onerror = function () {
            this.onerror = this.onload = null
            cb(new Error('Failed to load ' + src), script)
        }
    }

    function ieOnEnd(script) {
        script.onreadystatechange = function () {
            if (this.readyState !== 'complete' && this.readyState !== 'loaded') return
            this.onreadystatechange = null
            for (const cb of callbacksObj[name]) {
                cb(null, script) // there is no way to catch loading errors in IE8
            }
            callbacksObj[name] = null
        }
    }
}

export default dynamicLoadScript

上一篇下一篇

猜你喜欢

热点阅读