require.js 笔记

1.前言

随着网站功能逐渐丰富,网页中的js也变得越来越复杂和臃肿,原有通过script标签来导入一个个的js文件这种方式已经不能满足现在互联网开发模式,我们需要团队协作、模块复用、单元测试等等一系列复杂的需求。
通过script标签来导入众多的js文件有几个缺点:

  • 文件的引入路径难以书写,一大串路径字符串难以记忆,也不直观
  • 无法清晰的表明各种库之间的依赖关系,一旦引入顺序出错就不能正常执行
  • 所有的js都处在同一个作用域下,容易造成全局变量污染

require.js做到了这一点,它是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一。

相关代码笔记简易demo

2.基本使用

  • 引入require.js,并指定主模块的路径
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- 引入require.js 并指定主模块的路径 -->
    <script src="/assets/libs/require/require.js" data-main="/assets/js/require-backend.js"></script>
    <title>主页</title>
</head>
<body>
    
</body>
</html>
  • 主模块:相关路径配置,依赖配置,引入公共模块,引入页面js
//定义相关配置
require.config({
    baseUrl : "/assets", //基础路径 只针对 paths 下的字段生效
    //模块路径配置
    paths:{
        'vue':['libs/vue/vue.min', 'https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min'], //1.数组中可设多个路径  2.无需.js后缀
        'ELEMENT': 'libs/element-ui/index.min',
    },
    map: {
        '*': {
            //引入require-css,使其支持加载css
            'css': '/assets/libs/require-css/css.min.js'
        }
    },
    shim: { //声明模块依赖
        'ELEMENT': ['css!/assets/libs/element-ui/index.min.css'],//如果引入了ELEMENT模块,则自动引入这个css文件
    }
})

//vue和element-ui每个页面都会用到,所以作为公共模块引入
//每个页面都有其对应的js模块,需要为其配置相应的规则,使其根据页面路径自动引入

//引入页面公共模块和页面js模块
require(['vue','ELEMENT'],function(Vue,ELEMENT){
    //安装element-ui
    Vue.use(ELEMENT)
    //将Vue渲染至全局
    window.Vue = Vue

    //设定js基本路径
    var baseJsPath = "/assets/js"

    //获取当前页面路径
    var page_path = window.location.pathname

    //判断路径是否以 .html 结束
    if(page_path.lastIndexOf('.html') > -1 && (page_path.length - 5) == page_path.lastIndexOf('.html')){
        //页面路径完整(需去除.html后缀 再拼接)
        var jsPath = baseJsPath + page_path.slice(0,-5) + '.js'
    }else if(page_path.lastIndexOf('/') > -1 && (page_path.length - 1) == page_path.lastIndexOf('/')){//判断是否已 / 结尾
        //页面路径不完整(需要拼接 index.js)
        var jsPath = baseJsPath + page_path + 'index.js'
    }else{
        //页面路径不完整(说明无需去除.html后缀 直接拼接)
        var jsPath = baseJsPath + page_path + '.js'
    }

    //引入页面的js文件
    require([jsPath],function(){
        
    })
})
  • 页面js
define([],function(utils){
    new Vue({
        el:"#app",
        data(){
            return {
                
            }
        }
    })
})

3.封装自定义模块

模块定义使用define()方法,他有3个参数:

参数 类型 说明
参数一 String 可选,当前模块名称,一旦设定,在配置模块路径(paths)是就必须使用该名称
参数二 Array 可选,依赖的模块
参数三 Function 模块的定义,需要return一个数据作为当前模块的暴漏值
define('name_utils',[],function () {
    return {}
})

某些库就是使用这种方式定义的,所以引入是名称必须固定,例如jquery和elementui

像上面的依赖,elementui的源码已经指明依赖vue,一旦页面引入了elementui,即使没有引入vue,则require.js会自动引入vue,但是在回调中无法拿到Vue这个类,导致页面无法使用vue渲染,也无法安装elementui,所以还是得手动引入vue,require.js会自动忽略重复的请求

4.加载css

  • 加载css需要用到require-css插件,在主模块中引入这个插件,确保后面所有的模块都可正常加载css
require.config({
    map: { //map告诉RequireJS在任何模块之前,都先载入这个css模块
        '*': {
            css: 'https://cdn.bootcdn.net/ajax/libs/require-css/0.1.9/css.js'
        }
    }
})
  • 例1:element-ui依赖其配套的css,我们在shim字段中为element-ui声明他所需要的依赖。
require.config({
    map: { //map告诉RequireJS在任何模块之前,都先载入这个css模块
        '*': {
            css: 'https://cdn.bootcdn.net/ajax/libs/require-css/0.1.9/css.js'
        }
    },
    shim: { //声明模块依赖
        'ELEMENT':{
            "deps":['css!https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.2/theme-chalk/index.css'], //声明 'ELEMENT' 的依赖
        }
    }
})
  • 例2:引入页面的css文件,在引入时添加前缀 "css!" 后面跟css文件路径即可

当然,页面的js和css可以集中主模块中进行引入

//引入页面js映射模块
require([],function(){
    //加载页面对应的js和css (部分代码省略)
    require([jsPath, 'css!'+cssPath],function(){
        
    })
})

5.加载非规范的模块

  • require.js的模块使用define()方法进行定义,在回调中return一个数据,其他模块引入他的时候,就能够接收到这个模块,参考上面的封装自定义模块

  • 但是如果在define()的参数回调中,没有return任何数据,或者编写js模块时,未使用模块化的写法,,则无法接收,显示undefined

  • 上面的js定义了不止一个数据,我们可以指定其中的一个作为模块进行引入

require.config({
    //模块路径配置
    paths:{
        'utils':"js/utils"
    },
    shim: { //声明模块依赖
        'utils':{
            exports:"utils",//本例中可以sayHello和utils二选一
        }
    }
})

posted @ 2021-06-08 11:08  ---空白---  阅读(233)  评论(0编辑  收藏  举报