模块化

137 阅读3分钟

模块化的演变过程

  1. stage 1 文件划分方式(完全依靠约定)
  • 污染全局作用域
  • 命名冲突问题
  • 无法管理模块依赖关系
  1. stage 2 命名空间方式
  2. stage 3IIFE 立即执行函数

模块化的规范

1.common.js 规范(同步的模式加载模块) - 一个问价就是一个模块 - 每个模块都有单独的作用域 - 通过 module.export 导出成员 - 通过 require 函数载入模块 2.AMD(Require.js) - 相对复杂 - 模块 js 问价请求频繁 js 定义模块 当前模块名字 当前依赖项 参数与依赖性一一对应 define('module1',['jquery','./module2'],function($,module2){ return { start:..... } }) 加载模块 require(['./module1'],function(module1){ module1.start() }) 3.Sea.js + CMD

前端模块化 :ES Modules node :Common.js

ES Modules

  • 用过给 script 添加 type = module 的属性,就可以 以 ES module 的标准执行其中的 JS 代码了

    1. ESM 自动采用严格模式,忽略' use strict '
    2. 每个 ES Module 都是运行在单独的私有作用域中
    3. ESM 是通过 CORS 的方式请求外部 JS 模块的
    4. ESM 的 script 标签会延迟执行脚本
  • 导入导出

    //导出
    const foo = "es modules";
    export { foo };
    export var foo = 1;
    export class Person {}
    export { foo as fooName };
    export { xx as default };
    export default foo; //将一个变量作为当前模块的默认导出
    //导入
    import { foo } from "./module.js";
    import { default as foo } from "./module.js";
    import foo from "./module.js"; //可以通过一个变量名去接收这个模块默认导出的成员
    console.log(foo);
    
  • 注意事项

    1. 导出的成员并不是字面量对象,导入的时候不是解构
    export { name, age };
    import { name, age } from "......";
    
    1. 导出时并不是导出成员的值,而是吧导出成员所存放的地址给你,会受当前模块的改变影响
    2. 在外部导入的成员是只读的成员(可以用于定义配置文件)

import

  • 有完整的文件名称,相对路径中的'./'不能省略的,可以使用绝对路径和完整的 URL

  • import {} from './module.js' 只会执行这个模块不会提取成员或写为 import './module.js'(导入不需要外界控制的子功能模块)

  • 将提取出来的所有成员放入一个对象当中

    import \* as mod from "./module.js"
    
  • 动态导入模块

    import("./module.js").then(function (module) {
      console.log(module);
    });
    
  • 同时导出命名成员和默认成员,导入时

    import { name, age, default as title } from "./module.js";
    import title, { name, age } from "./module.js";
    

直接导出导入成员

在写 index 文件时使用,将某一个目录下散落的文件组织到一起然后到处方便外部使用

export { foo, bar } from "./module.js";

es-module-loader es-module 的 polyfile es-module in Node.js(v8.5 实验特性) 1 .js-> .mjs 修改文件名 2. 启动 node --experimental-modules index.mjs

//系统内置模块兼容了ESM 的提取成员方式
import { writerFileSync } from "fs";
//不支持,因为第三方模块都是导出默认成员
import { cameCase } from "lodash";

ESmodule 中可以导入 CommonJs 模块,只能使用 ESmodule 载入默认成员的方式载入 CommonJs 模块,不能提取成员(node环境中) 不能用 CommonJs 模块载入 ESmodule(node环境中) ESM中没有CommonJs中的那些模块全局成员了(require/ module/ exports / __filename/ __dirname)

import {fileURLToPath} from  "url"
import {dirname}from "path
const __filename = fileURLToPath(import.meta,url)
console.log(__filename)
const __dirname = dirname(__filename)
console.log(__dirname)

v.12.10 在packjson添加“type”:“module”可以不用.mjs,commonjs 需要用.cjs

babel

  • yarn add @babel/node @babel/core @babel/preset-env --dev
  • yarn babel-node
  • yarn babel-node index.js --preset=@babel/preset-env
//.babelrc
{//一组插件
  "presets" : ["@babel/preset-env"]
}
  • yarn remove @babel/preset-env
  • yarn add @babel/plugin-transform-modules-commonjs --dev
//.babelrc
{
  "pluguns" : [
    "@babel/plugin-transform-modules-commonjs"
  ]
}