ES Modules【浏览器端的模块开发规范】

编程入门 行业动态 更新时间:2024-10-25 04:24:47

目录

一、ES Modules 特性

二、ES Modules 导出

三、ES Modules 浏览器环境 Polyfill 

四、ES Modules in Node.js - 支持情况

五、 ES Modules in Node.js - 与 CommonJS 交互

六、ES Modules in Node.js - 与 CommonJS 的差异

七、ES Modules in Node.js - 新版本进一步支持 

八、 ES Modules in Node.js - Babel 兼容方案 


一、ES Modules 特性

  • 特性1:EMS 自动采用严格模式,忽略 ‘use strict’ 
  <script type="module">
    console.log(this)
  </script>
  • 特性2:每个 ES module 都是运行在单独的私有作用域中 
  <script type="module">
    var foo = 100
    console.log(foo) //100
  </script>
  <script type="module">
    console.log(foo) //找不到
  </script>
  • 特性3:ESM 是通过 CORS 的方式请求外部 JS 模块的 
<script type="module" src="https://unpkg/jquery@3.4.1/dist/jquery.min.js"></script> 
  •  特性4,:ESM 的 script 标签会延迟执行脚本

二、ES Modules 导出

  • import 是载入模块
     
    
    import { name, hello, Person } from './module.js'
    console.log(name, hello, Person)
    
    import { name } from './module.js' //不能省略 .js
    
    import { name } from './module.js' //不能省略 ./
    import { name } from '04-import//module.js'
    
    import {  } from './module.js' //只是导出模块,并不会提取成员
    import './module.js'
    
    import * as mod from './module.js' //导出所有成员
    
    import('./module.js').then(function (modile) { //动态导入模块
        console.log(modile)
    })
    
    import { name, age, default as title } from './module.js' //导出默认成员
    import title, { name, age } from './module.js'
  • export 是导出模块 
    //index.js
    export { default as button } from './button.js'
    export { Avatar } from './avatar.js'
    
    //button.js
    export var BUtton = 'Button Component'
    
    export default Button
    
    //avatar.js
    export var Avatar = 'Avatar Component'
  • 案例如下
     
    <!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>ES Module 导出与导入</title>
    </head>
    <body>
      <script type="module" src="app.js"></script>
    </body>
    </html>
    //module.js
    
    var name = 'foo module'
    
    function hello () {
      console.log('hello')
    }
    
    class Person {}
    
    export { name, hello, Person } //注意:这个导出的成员并不是字面量对象,{ } 是导出固定的语法
    
    //app.js
    
    import { name, hello, Person } from './module.js' // 导出也不是结构对象,是固定的一种语法
    console.log(name, hello, Person) // 导出的成员是只读的成员

三、ES Modules 浏览器环境 Polyfill 

  • ES Modules 是2014年出来的,目前很多浏览器不支持此功能,需要引入 js文件,引入链接如下,也可 npm 安装
<!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>ES Module 浏览器环境 Polyfill</title>
</head>
<body>
  <!-- nomodule 表示支持 polyfill的浏览器不去加载,解决二次执行的问题 ,测试阶段使用,生产阶段不可以用,因为原理在运行阶段动态解析脚本,效率非常差,要用的话在项目里预先编译-->
  <script nomodule src="https://unpkg/promise-polyfill@8.1.3/dist/polyfill.min.js"></script>
  <script nomodule src="https://unpkg/browser-es-module-loader@0.4.1/dist/babel-browser-build.js"></script>
  <script nomodule src="https://unpkg/browser-es-module-loader@0.4.1/dist/browser-es-module-loader.js"></script>
  <script type="module">
    import { foo } from './module.js'
    console.log(foo)
  </script>
</body>
</html>

 四、ES Modules in Node.js - 支持情况

命令行输入:node --experimental-modules esm.mjs 

// 第一,将文件的扩展名由 .js 改为 .mjs;
// 第二,启动时需要额外添加 `--experimental-modules` 参数;

import { foo, bar } from './module.mjs'

console.log(foo, bar)

// 此时我们也可以通过 esm 加载内置模块了
 import fs from 'fs'
 fs.writeFileSync('./foo.txt', 'es module working')

// 也可以直接提取模块内的成员,内置模块兼容了 ESM 的提取成员方式
 import { writeFileSync } from 'fs'
 writeFileSync('./bar.txt', 'es module working')

// // 对于第三方的 NPM 模块也可以通过 esm 加载
import _ from 'lodash'
 _.camelCase('ES Module')

// 不支持,因为第三方模块都是导出默认成员
 import { camelCase } from 'lodash'
 console.log(camelCase('ES Module'))

 五、 ES Modules in Node.js - 与 CommonJS 交互

  • ES Modules中可以导入 CommonJS 模块
  • CommonJS 中不能导入 ES Modules 模块
  • CommonJS 始终只会导出一个默认成员
  • 注意 import 不是解构导出对象

六、ES Modules in Node.js - 与 CommonJS 的差异

  • 在 CommonJS 下可以正常输出
    //cjs.js
    
    // 加载模块函数
    console.log(require)
    
    // 模块对象
    console.log(module)
    
    // 导出对象别名
    console.log(exports)
    
    // 当前文件的绝对路径
    console.log(__filename)
    
    // 当前文件所在目录
    console.log(__dirname)
    
  • 在 ES Module 下需要引用路径才能正常输出内容 
    // ESM 中没有模块全局成员了
    
    // require, module, exports 自然是通过 import 和 export 代替
    
    // __filename 和 __dirname 通过 import 对象的 meta 属性获取
    // const currentUrl = import.meta.url
    // console.log(currentUrl)
    
    // 通过 url 模块的 fileURLToPath 方法转换为路径
    import { fileURLToPath } from 'url'
    import { dirname } from 'path'
    const __filename = fileURLToPath(import.meta.url)
    const __dirname = dirname(__filename)
    console.log(__filename)
    console.log(__dirname)
    

七、ES Modules in Node.js - 新版本进一步支持 

  • 在 package.json 将 type 类型 设置为 module,就可以使用 ES Module 模块,此时就不需要修改文件扩展名为 .mjs 了 
    //package.json
    {
      "type": "module"
    }
    

八、 ES Modules in Node.js - Babel 兼容方案 

  • 安装 babel 插件和预设插件 yarn add @babel/node @babel/core @babel/preset-env --dev 
  • yarn babel-node index.js --presets=@babel/preset-env
  • 如果觉得配置麻烦,可以新建一个 .babelrc文件进行配置
    {
      "presets": [
        "@babel/preset-env"
      ]
    }
  • yarn babel-node index.js
  • yarn remove @babel/preset-env
  • yarn add @babel/plugin-transform-modules-commonjs --dev
    {
      "plugins": [
        "@babel/plugin-transform-modules-commonjs"
      ]
    }
  • yarn babel-node index.js 

更多推荐

ES Modules【浏览器端的模块开发规范】

本文发布于:2023-06-14 02:19:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1427195.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模块   浏览器   ES   Modules

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!