• JS模块化


    模块化规范

    1.CommonJS规范#

    ​ 在node中,默认支持的模块化规范叫做CommonJS,

    ​ 在CommonJS中,一个js文件就是一个模块

    • CommonJS规范

      • 引入模块

        • 使用require('模块的路径')函数来引入模块

        • 引入自定义模块时

          • 模块名要以 ./ 或 ../ 开头
          • 扩展名可以省略
            • 在CommonJS中,如果省略的js文件的扩展名,node会自动不全扩展名
              • 如果没有改js文件,会找名字相同的文件进行引入
        • 引入核心模块时

          • 直接写核心模块的名字即可
          • 也可以在核心模块前添加node:可以加快查询效率
      //引入自定义模块
      const m1 = require("./m1")
      //按需引入
      const name = require('./m1').name
      const {name,age,gender} = require('./m1')
      //引入核心模块
       const path = require("path")
       const path = require("node:path")
      

      在定义模块时,模块中的内容默认是不能被外部看到的

      ​ 可以通过exports来设置要向外部暴露的内容

      访问exports的方式有两种:

      1. exports
      2. module.exports
      • 当我们在其他模块中引入当前模块时,require函数返回的就是exports -
      • 可以将希望暴露给外部模块的内容设置为exports的属性
      ------------------------------m1.js----------------------------------------
      // 可以通过exports 一个一个的导出值
      // exports.a = "孙悟空"
      // exports.b = {name:"白骨精"}
      // exports.c = function fn(){
      //     console.log("哈哈")
      // }
      
      // 也可以直接通过module.exports同时导出多个值
      module.exports = {
          a: "哈哈",
          b: [1, 3, 5, 7],
          c: () =>{
              console.log(111)
          }
      }
      
      

      CommonJS执行原理:

      1. 所有的CommonJS的模块都会被包装到一个函数中

        function(exports, require, module, __filename, __dirname){
            //模块代码会被放到这里
        }

        exports:用来设置模块向外部暴露的内容

        require:用来引入模块的方法

        module:当前模块的引用

        __filename:模块的路径

        __dirname:模块所在目录的路径

    2.ES6模块化#

    Node.js中同样支持ES模块化,使用模块化无非就是需要注意两件事导出和导入

    1. 导出

      // 导出变量(命名导出)
      export let name1, name2,, nameN; 
      export let name1 =, name2 =,, nameN; 
      // 导出函数(命名导出)
      export function functionName(){...}
      // 导出类(命名导出)
      export class ClassName {...}
      // 导出一组
      export { name1, name2,, nameN };
      // 重命名导出
      export { variable1 as name1, variable2 as name2,, nameN };
      // 解构赋值后导出
      export const { name1, name2: bar } = o;
      // 默认导出
      export default expression;
      export default function () {} // also class, function*
      export default function name1() {} // also class, function*
      export { name1 as default,};
      // 聚合模块
      export * from …; // 将其他模块中的全部内容导出(除了default)
      export * as name1 from …; // ECMAScript® 2O20 将其他模块中的全部内容以指定别名导出
      export { name1, name2,, nameN } from …; // 将其他模块中的指定内容导出
      export { import1 as name1, import2 as name2,, nameN } from …; // 将其他模块中的指定内容重命名导出
      export { default,} from …; 
      
    2. 引入

      // 引入默认导出
      import defaultExport from "module-name";
      // 将所有模块导入到指定命名空间中
      import * as name from "module-name";
      // 引入模块中的指定内容
      import { export1 } from "module-name";
      import { export1 , export2 } from "module-name";
      // 以指定别名引入模块中的指定内容
      import { export1 as alias1 } from "module-name";
      import { export1 , export2 as alias2 , [...] } from "module-name";
      // 引入默认和其他内容
      import defaultExport, { export1 [ , [...] ] } from "module-name";
      import defaultExport, * as name from "module-name";
      // 引入模块
      import "module-name";
      

      需要注意的是,Node.js默认并不支持ES模块化,如果需要使用可以采用两种方式:

      1. 方式一:直接将所有js文件修改为mjs扩展名。
      2. 方式二:修改package.json中type属性为module。

    3.核心模块#

    核心模块,是node中自带的模块,可以在node中直接使用

    1. window 是浏览器的宿主对象 node中是没有的
    2. global 是node中的全局对象,作用类似于window
    3. ES标准下,全局对象的标准名应该是 globalThis
    • process

      • 表示当前的node进程

      • 可以通过改对象获取进程的信息,或者对进程做各种操作

      • 如何使用

        1. process是一个全局变量,可以直接使用

        2. 有哪些属性和方法:

          1. process.exit([code状态码])

            1. 结束当前进程,终止node
          2. process.nextTick(callback[ ...args])

            1. 将函数插入到 tick队列中

            2. tick队列中的代码,会在下一次事件循环之前执行,会在微任务队列和宏任务队列中任务之前执行

              setTimeout(()=>{
              	console.log('111')
              }) //宏任务队列
              queueMicrotask(()=>{
                  console.log('222')
              })  //微任务队列
              process.nextTick(()=>{
                  console.log('333')
              })
              console.log('444')
              
              
              //执行顺序为: 444 -> 333 -> 222 -> 111
              

        执行顺序:

        1. 调用栈
        2. tick队列(了解)
        3. 微任务队列
        4. 宏任务队列
    • path模块

      • 表示的路径

      • 通过path可以用来获取各种路径

      • 要使用path,需要先对其进行引入

      • 方法:

        • path.resolve([...paths])

          • 用来生成一个绝对路径
          • 直接调用resolve,则返回当前的工作目录
          • 注意,我们通过不同的方式执行代码时,它的工作目录是有可能发生变化的
        • 如果将一个相对路径作为参数:

          • 则resolve会自动将其转换为绝对路径
          • 此时根据工作目录的不同,他所产生的绝对路径也不同
        • 一般会将一个绝对路径作为第一个参数

          • 一个相对路径作为第二个参数
          • 这样它会自动计算出最后的路径
        //引入模块
        const path = require('node:path')
        //以后在使用路径时,尽量通过path.resolve()来生成路径
        const result = path.resolve(__dirname, './hello.js')
        
    • fs模块

      • fs用来帮助node来操作磁盘中的文件

      • 文件操作也就是所谓的I/O流,input output

      • 使用fs模块,同样需要引入

      • fs.readFileSync()

        • readFileSync() 同步的读取文件的方法,会阻塞后面的代码执行

        • 当我们通过fs模块读取磁盘中的数据时,读取到的数据总会一Buffer对象的形式返回

        • Buffer是一个临时用来存储数据的缓冲区

          //引入模块
          const path = require('node:path')
          const fs = require('node:fs')
          const buffer = fs.readFileSync(path.resolve(__dirname, './hello.txt'))
          console.log(buffer.toString())  //把Buffer数据转换为字符串类型
          
      • fs.readFile()

        • 异步的读取文件的方法

          • 方法1:回调函数式

            const path = require('node:path')
            const fs = require('node:fs')
            fs.readFile(path.resolve(__dirname, './hello.js'),(err,buffer)=>{
                if(err){
                     console.log("出错了~")
                } else {
                     console.log(buffer.toString())
                }
            })
            
          • 方法2:promise式

            const path = require('node:path')
            const fs = require('node:fs/promises')
            fs.readFile(path.resolve(__dirname, './hello.js'))
            	.then(buffer=>{
                	console.log(buffer.toString())
            	})
            	.catch(e=>{
                	console.log('出错了,有问题', e.message)
            	})
            
          • 方法3:async和await式

            ;(async ()=>{
                try {
                    const buffer = await fs.readFile(path.resolve(__dirname, './hello.js'))
                    console.log(buffer.toString())
                } catch(e){
                    console.log(’出错了....)
                }
            })()
            
      • fs.appendFile()

        • 创建新文件,或将数据添加到已有文件中
      • fs.mkdir()

        • 创建目录
      • fs.rmdir()

        • 删除目录
      • fs.rm()

        • 删除目录
      • fs.rename()

        • 重命名
      • fs.copyFile()

        • 复制文件
    1. //实现复制一个文件
      //1.读取文件中的内容
      const path = require('node:path')
      const fs = require('node:fs/promises')
      fs.readFile(path.reslove(__dirname, './hello.txt'))
      	.then(buffer =>{
          	//2.复制文件中的
          	return fs.appendFile(path.resolve(__dirname, './world.txt'), buffer)
      	})
      	.then(()=>{
          	console.log('操作结束')
      	})
      	.catch(err =>{
          	console.log('出错了..')
      	})
      
  • 相关阅读:
    MySQL:索引知识点盘点
    Java入门第二季
    linux下创建文件夹软链接
    【开发工具】VScode连接远程服务器+设置免密登录
    SpringCloud-7-Spring Boot使用Jetty容器
    〖Python 数据库开发实战 - MySQL篇㉞〗- 综合案例 - 新闻管理系统数据库设计的基本属性
    【工作记录】MQTT介绍、安装部署及springboot集成@20230912
    ssm人事管理系统
    【Docker】Docker File
    2.25每日一题(反常积分的计算:被积函数分母出现e的正负x次幂)
  • 原文地址:https://www.cnblogs.com/taotaoFrontEndDevelopment/p/16950389.html