模块化cmd,amd中动态加载资源问题

栏目: CSS · 发布时间: 5年前

内容简介:今天主要讨论一下cmd和amd中运用loadjs等方式动态加载资源遇到的问题。当然,amd和cmd是比较老的前端模块化技术了。类似我之前文章提到的requirejs,这种方式下运用loadjs中遇到的问题。我这里列举一下我平时用的比较多的loadjs和css等的函数吧上面是我常用的一些动态加载和删除资源的一些方式。但是这种方式在RequireJS等中运用有时候会有问题,例如加载swiper

前言

今天主要讨论一下cmd和amd中运用loadjs等方式动态加载资源遇到的问题。当然,amd和cmd是比较老的前端模块化技术了。类似我之前文章提到的requirejs,这种方式下运用loadjs中遇到的问题。

前端动态加载资源

我这里列举一下我平时用的比较多的loadjs和css等的函数吧

/*
desc:加载资源类库
auth:haorooms 博客
*/

// 加载CSS
export function LoadCss (id, content) {
  var newStyle = document.createElement('style')
  newStyle.type = 'text/css'
  newStyle.id = id
  if (typeof newStyle.styleSheet != 'undefined') {
    newStyle.styleSheet.cssText = content
  } else {
    newStyle.innerHTML = content
  }
  document.getElementsByTagName('head')[0].appendChild(newStyle)
}
// 加载JS
export function LoadJS (url, callback, errcallback) {
  var documentHeader = document.head || document.getElementsByTagName('head')[0]
  // 防止单页应用加载多次
  var addSign = true
  var scripts = document.getElementsByTagName('script')
  for (var i = 0; i < scripts.length; i++) {
    if (scripts[i] && scripts[i].src && scripts[i].src.indexOf(url) != -1) {
      addSign = false
    }
  }
  if (addSign) {
    var script = document.createElement('script')
    script.type = 'text/javascript'
    script.charset = 'utf-8'
    script.async = true
    script.src = url
    documentHeader.appendChild(script)
    script.onload = function () {
      callback && callback()
    }
    script.onerror = function () {
      errcallback && errcallback()
      documentHeader.removeChild(script)
    }
  } else {
    callback && callback()
  }
}

// 加载CSS引用
export function LoadLink (url) {
  // 防止单页应用加载多条
  var addSign = true
  var links = document.getElementsByTagName('link')
  for (var i = 0; i < links.length; i++) {
    if (links[i] && links[i].href && links[i].href.indexOf(url) != -1) {
      addSign = false
    }
  }
  if (addSign) {
    var link = document.createElement('link')
    link.type = 'text/css'
    link.rel = 'stylesheet'
    link.href = url
    document.getElementsByTagName('head')[0].appendChild(link)
  }
}

// js删除script
export function removeScript(src) {
  var scripts = document.getElementsByTagName('script')
  for (var i = 0; i < scripts.length; i++) {
    if (scripts[i] && scripts[i].src && scripts[i].src.indexOf(src) != -1) {
      scripts[i].parentNode.removeChild(scripts[i])
    }
  }
}

// js删除link文件
export function removelink(href) {
  var links = document.getElementsByTagName('link')
  for (var i = 0; i < links.length; i++) {
    if (links[i] && links[i].href && links[i].href.indexOf(href) != -1) {
      links[i].parentNode.removeChild(links[i])
    }
  }
}

上面是我常用的一些动态加载和删除资源的一些方式。但是这种方式在RequireJS等中运用有时候会有问题,例如加载swiper

例如如下:

require(["js/student", "js/class"], function(student, clz) { 
 LoadJS('./haorooms/swiper.min.js',function(){
   console.log(swiper)
  })
 });

这个时候会爆出swiper is not defined错误。

原因是因为

require是封闭的引用,loadjs是在头部添加标签,而swiper是umd及es的方式打包的。因此,在封闭的作用域下面获取不到值。

因此,loadjs方式引用的js必须是iife方式打包,或者是暴露全局作用域才可以。

解决方案:

下载swiper源码,用rollup重新打包,打包成iife的方式就可以了。

将swiper源码 script/build-js.js中的打包方式替换成iife,例如如下:

then(bundle => bundle.write({
    format: 'iife',
    name: 'Swiper',
    strict: true,
    sourcemap: env === 'development',
    sourcemapFile: `./${env === 'development' ? 'build' : 'dist'}/js/swiper.js.map`,
    banner,
    file: `./${env === 'development' ? 'build' : 'dist'}/js/swiper.js`,
  })).then(() => {
    if (env === 'development') {
      if (cb) cb();
      return;
    }

这样打包好了的swiper就可以用loadjs在amd和cmd等方式中引用了。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

零基础学PHP

零基础学PHP

马忠超 / 2008-3 / 56.00元

《零基础学PHP》主要内容:PHP是一种运行于服务器端并完全跨平台的嵌入式脚本编程语言,是目前开发各类Web应用的主流语言之一。PHP因其功能强大、易学易用、可扩展性强、运行速度快和良好的开放性,而成为网站开发者的首选工具,其较高的开发效率,也给开发人员在编写Web应用程序时带来极大的便利。一起来看看 《零基础学PHP》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具