前端模块化


typora-copy-images-to: images
typora-root-url: images

前端模块化 (Require.js)

为什么要用 前端模块化

早期,js代码量小, 所有Javascript代码可以都写在一个文件里面,只要加载一个js文件就够了。

但是后来,随着功能需求变多, 所有功能写在一个文件不好维护, 就拆分成了多个文件, 需要依次加载多个文件。如下:

  <script src="1.js"></script>
  <script src="2.js"></script>
  <script src="3.js"></script>
  <script src="4.js"></script>
  <script src="5.js"></script>
  <script src="6.js"></script>

这段代码依次加载多个js文件。

这样的写法有很大的缺点:

  1. 加载的时候,浏览器会停止网页渲染,加载文件越多,网页失去响应的时间就会越长

  2. 由于js文件之间存在依赖关系,因此必须严格保证加载顺序(比如上例的1.js要在2.js的前面),依赖性最大的模块一定要放到最后加载,当依赖关系很复杂的时候,代码的编写和维护都会变得困难。

为了解决这两个问题 :

  1. 解决命名冲突
  2. 便于依赖管理

所以,require.js诞生了

官网网址:http://requirejs.org/

/* ---
RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will improve the speed and quality of your code.
IE 6+ .......... compatible ✔
Firefox 2+ ..... compatible ✔
Safari 3.2+ .... compatible ✔
Chrome 3+ ...... compatible ✔
Opera 10+ ...... compatible ✔
Get started then check out the API.
--- */

模块化的标准

让模块拥有更好的通用性!

  • AMD : Async Module Definition 异步模块定义 require.js

requireJS主要解决两个问题 :

  1. 多个js文件可能有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器
  2. js加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应时间越长
  • CMD : Common Module Definition 通用模块定义 sea.js

依赖延迟: 在需要的时候才去加载依赖项.

requireJS的下载

npm的方式

npm  install requirejs

直接官网下载

https://requirejs.org/docs/download.html

模块化的实现(require.js)

下载后,把它放在目录下面,就可以加载了

 <script src="./node_modules/requirejs/require.js"></script>

定义模块

  • 在require.js中,每个模块也是分成单独的文件保存的

  • 每一个模块中都有自己单独的作用域!

  • 在定义模块的时候,需要使用requirejs提供的函数define() 进行定义

    语法:

        /**
         * 1. 定义模块
         *    (1) 每个模块都一般是一个单独的js文件
         *    (2) 每个模块都有自己独立的作用域
         *    语法: define( '模块名', ['依赖项1', '依赖项2'], function() {
         
         *            // 模块的主体, 该函数会在加载完依赖项后调用
         *          })
         *    导出项: 定义在模块中的方法或者对象, 希望从模块中导出, 给其他模块使用
         */
    
    

引用模块

  • 在require.js中,引用一个模块使用require.js提供的函数 require()

    语法: require(["模块文件的路径(不带.js后缀的)"], function(){
        //模块加载成功之后的回调函数
        //模块的加载是异步的,在模块加载完成之后,才能使用模块的相关功能
    })
    
案例1:无返回值

定义被引入模块modules/a.js

define([], function() {
    'use strict';
    console.log('我是a被包含了')
    
});

在html文件中进行引入

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="./node_modules/requirejs/require.js"></script>
</head>
<body>
    <script>
        require(['./model/a'],function(){
            console.log('引入成功了')
        });  
    

    </script>
</body>
</html>

模块的注意项

定义模块的时候,有导出项的情况

  • 如果有导出项,只需要把导出项通过return语句进行返回即可!

引用模块时,模块有导出项,怎么使用导出项

  • 要接收模块的返回值,那么就在回调函数中的形参里声明形参来接收
  • requiresjs 会自动为形参赋值
  • 引入多个模块时,形参的顺序和模块加载的顺序是一一对应的!!!
       require(['./modules/a', "./modules/b", "./modules/c"], function(ma, mb, mc){
            console.log(mb);
            console.log(mc);
       })

**注意:**在请求多个模块的时候,一般将没有返回值的模块放在后面,有返回值的放在前面,这样就可以避免要为没有返回值的模块写形参!

   require([ "./modules/b", "./modules/c",'./modules/a'], function(mb, mc){
       console.log(mb);
       console.log(mc);
   })
案例2:有返回值

定义model/b.js

define([],function(){
    console.log('我是b,被引入了');
    obj={
        name:'马爸爸',
        add:function(a,b){
            return a+b;
        }
    }
    // 有导出项直接return
    return obj;
});

在html文件中引入

    // 使用回调函数的参数接收导出项
    require(['./model/b'],function(fn){
        console.log('调用了B');
        console.log(fn.add(1,2));
    })
案例3:引入多个模块
    require(['b','c'],function(b,c){  // 返回值的顺序和引入模块的顺序一样
        console.log(b.add(1,2));
        c.desc('我真的狠辣');
    })

模块路径的查找方式

  在require.js中,模块路径的查找方式, 一共有三种:
  1. 不做任何配置,直接以当前文件的路径作为参照

    require([“./modules/a”])

  2. 如果设置了data-main属性,那么模块的查找,会以data-main指定的文件的路径作为基础(几乎不用)

    • data-main是一个属性,是引入require.js的script标签的属性
    • 这个属性可以用来指定一个文件,加载文件的路径会以这路径为基础, 指定的文件会在require.js加载完毕之后,通过异步的方式加载,并且执行里面的代码,
  <script src="require.js" data-main="./js/"></script>

3.如果通过require.config方法配置了基础路径,那么所有的模块查找都会以这个基础路径作为参照

//config方法是用来配置require的一些加载规则的!
    require.config({
      //baseUrl 指的就是查找模块时的基础路径,所有的模块的查找都会以这个为参照
      //baseUrl 一般都被设置为绝对路径
      baseUrl: "./modules",
      //设置具有模块名的,模块路径
      paths: {
        a: "a",  // 模块a  a.js
        b: 'b'
      }
    })

 // 使用
    require(['a', 'b'], function (undifined, mb) {
      console.log('成功了....');
      console.log(mb)
    })
 
//当引用模块的时候,模块的路径  baseUrl + 引用模块的路径
// require(["dianzuan"]);

注意: 第三种方式中 找文件的规则是: baseUrl + paths

案例4:

引入的模块有名称,需要设置paths

定义models/d.js文件

define('goods',[],function(){
    function fn(info){
        console.log(info)
    };
    return fn;
});

在html文件中引入

    require.config({
        baseUrl:'./modules/',
         paths:{
             goods:'d'
         }
    });
    require(['goods'],function(dd){
         dd('努力才幸运')
    });
        

总结:

要想使用require()引入模块
要知道被引入模块是否有define定义,以及模块的名称

第三方插件使用

步骤1: 引入jq包,注意先要查看jq的导出名称

步骤2: html文件中的写法引入jq包

  require.config({
       // 公共基础路径, 项目推荐使用绝对路径
       // 将来所有的路径, 都要以 baseUrl 为基准
      baseUrl: "/study/modules/",
       // 对于定义好了模块名的模块, 必须定义别名, 而且要和定义的模块名统一
      paths: {
        jquery: './lib/jquery/jquery'
      }
     });
     
     // 注意: 由于 jquery 在内部定义了模块名, 所以只能以模块名的方式加载
     //      才能获取导出项
     require(['jquery'], function( $ ) {
       console.log( $ );
       $('body').css('backgroundColor', 'pink');
     });

其他查看引入的文件是否使用define()定义

查看说明文档.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值