• 模块化


    1、NODEJS的common.js规范

    1.1、module.exports

    module.exports是node的私有的一个全局变量属性,测试发现可以用require引用,也可以用import from来使用。

    //demo.js
    let a= "字符串";
    function func() {
        console.log("函数")
    }
    module.exports = {
        a,
        func
    }
    
    //module2
    import util from './demo'
    //let util=require('./demo')
    //import {a,func} from './demo'
    console.log(util)
    
    /**
    结果:
      {
        a:"字符串",
        func:function(){
          console.log("函数")
        }
      }
    */
    
    
    
    

    1.2、exports

    exports只是module.exports的全局引用 , 值得注意的是,你不能给exports赋值,这很重要,很重要,很重要。

    //demo.js
    // 错误写法
    // exports={a:"aa"}
    // 打印 {}
    
    
    // 正确写法
    exports.a = 10;
    exports.func=function() {
        console.log("lalala")
    }
    // 打印 {a:10,func:function}
    
    // 上面写了exports就不能写下面的module.exports,下面会覆盖上面的,因为exports指向module.exports
    // module.exports = {a:"aaa"}
    
    
    //main.js 引入,下面两种都可以
    //第一种
    import a from './demo'
    //第二种
    let a=require('./demo')
    

    2、es6 module

    2.1、export

    • 基本使用

    模块功能主要由两个命令构成:exportimportexport命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

    // demo.js 第一种写法
    export var firstName = 'Michael';
    export var lastName = 'Jackson';
    export var year = 1958;
    export function multiply(x, y) {
      return x * y;
    };
    
    //使用,需要哪个变量直接使用就好
    import {firstName,year} from './demo'
    console.log(firstName,year)
    
    //打印
    Michael 1958
    

    2.2、注意点

    2.2.1、import引入注意事项

    上面代码的import命令,用于加载demo中输入变量。import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(profile.js)对外接口的名称相同。

    注意,import命令具有提升效果,会提升到整个模块的头部,首先执行。

    如果想为输入的变量重新取一个名字,import命令要使用as关键字,将输入的变量重命名。

    import { lastName as surname } from './profile';
    

    像获取一个对象的形式获取

    
    //错误
    import utils from './demo' //utils为undefined
    //正确,util可以自己更改命名
    import * as util from './demo'
    
    

    由于import是静态执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构。

    // 报错
    import { 'f' + 'oo' } from 'my_module';
    
    // 报错
    let module = 'my_module';
    import { foo } from module;
    
    // 报错
    if (x === 1) {
      import { foo } from 'module1';
    } else {
      import { foo } from 'module2';
    }
    

    会执行,但不会有任何结果

    import 'lodash';
    
    2.2.2、export导出注意事项
    // 报错
    export 1;
    
    // 报错
    var m = 1;
    export m;
    
    
    // 正确写法一
    export var m = 1;
    
    // 正确写法二
    var m = 1;
    export {m};
    
    // 正确写法三
    var n = 1;
    export {n as m};
    
    // 报错
    function f() {}
    export f;
    
    // 正确
    export function f() {};
    
    // 正确
    function f() {}
    export {f};
    
    2.2.3、动态变化数值

    export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。

    会自动变化

    //demo.js
    export var foo = 'bar';
    setTimeout(() => foo = 'baz', 500);
    
    //main.js
    import {foo} from './demo'
    
    console.log(foo) //第一次打印为bar
    setTimeout(()=>{
       console.log(foo) //第二次打印为baz
    },1000)
    
    2.2.4、export出现位置

    export命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错,下一节的import命令也是如此。这是因为处于条件代码块之中,就没法做静态优化了,违背了ES6模块的设计初衷

    // 报错
    function foo() {
        export default 'bar' // SyntaxError
      }
      foo()
    
    //报错
    {
        export let a=10;
    }
    

    2.3、export default

    export default命令只能输出一个

    从前面的例子可以看出,使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。

    为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。

    // 第一组
    export default function suibian() { // 输出
      // ...
    }
    
    import crc32 from 'crc32'; // 输入
    
    // 第二组
    export function crc32() { // 输出
      // ...
    };
    
    import {crc32} from 'crc32'; // 输入
    

    3、webpack 之 require.context 用法

    最近项目中用到了vue-element-admin当作框架,当中有一个很好的例子:封装了一个svg的组件,其中就是用到了require.context

    3.1、基本语法

    require.context有三个参数:
        directory:说明需要检索的目录
        useSubdirectories:是否检索子目录
        regExp: 匹配文件的正则表达式
    require.context("./test", false, /.test.js$/);
    //(创建了)一个包含了 test 文件夹(不包含子目录)下面的、所有文件名以 `.test.js` 结尾的、能被 require 请求到的文件的上下文。
    require.context("../", true, /.stories.js$/);
    //(创建了)一个包含了父级文件夹(包含子目录)下面,所有文件名以 `.stories.js` 结尾的文件的上下文。
    

    封装svg里面用到的

    //第一种用法
    const requireAll = requireContext => requireContext.keys().map(requireContext)
    const req = require.context('./svg', false, /.svg$/)
    requireAll(req)
    
    //第二种用法
    const context = require.context("./svg", true, /.svg$/)
    context.keys().map(context)
    

    4、参考链接

    手摸手,带你优雅的使用 icon https://juejin.im/post/59bb864b5188257e7a427c09

  • 相关阅读:
    SocketChannel 例子(转)
    多态(Polymorphism)的实现机制(上)--C++篇
    多态(Polymorphism)的实现机制(下)--Java篇
    java volatitle 多线程问题
    线程BlockingQueue (转)
    java 多态,和方法覆盖分析(转)
    MFC 调试技巧
    strlen与sizeof区别(转载)
    杭电1048
    杭电2013
  • 原文地址:https://www.cnblogs.com/wlhappy92/p/12146576.html
Copyright © 2020-2023  润新知