• JS 模块化- 05 ES Module & 4 大规范总结


    1 ES Module 规范

    ES Module 是目前使用较多的模块化规范,在 Vue、React 中大量使用,大家应该非常熟悉。TypeScript 中的模块化与 ES 类似。

    1.1 导出模块

    导出模块有两种方式:按需导出默认导出

    按需导出是使用 export 关键字,将需要导出的成员(变量、函数、对象等)依次导出:

    export const xxx = ''
    export const xxx = () => {}
    

    一个模块中可以有多个按需导出,但只能有一个默认导出。假设默认导出 A 模块,当 B 模块直接导入模块 A 时,其导入的值就是模块 A 默认导出的值。

    export default {}
    

    1.2 导入模块

    导入按需导出的模块:

    import { xxx } from 'xxx'
    

    上面语法中,花括号 {} 中的内容必须与导出的名称一致。

    如果按需导出的成员较多,可以使用 as 一次性导入:

    import * as xxx from 'xxx'
    

    导入默认导出的模块:

    import xxx from 'xxx'
    

    也可以直接导入一个模块,并直接执行该模块的代码:

    import 'xxxxx'
    

    2 使用 Webpack 编译 ES Module

    2.1 初始化项目

    创建 modules 目录,里面存放两个模块 module1.jsmodule2.js。入口文件与 modules 目录同级,名为 index.js。文件和目录结构如下:

    05_ESM/
      |- modules/
        |- module1.js
        |- module2.js
      |- index.js
      |- index.html
    

    2.2 实现两个模块

    module1.js 使用按需导出变量 str1 和函数 fun1,默认导出 user 对象:

    console.log('in module1')
    
    export const str1 = 'hello module1'
    
    export const fun1 = (msg) => {
      return `module1:${msg}`
    }
    
    
    const user = {
      name: 'zhangsan',
      age: 30
    }
    
    export default user
    

    module2.js 使用默认导出,导出一个对象,这个对象包括属性 str2 和方法 fun2

    console.log('in module2')
    
    const str2 = 'hello module2'
    
    const fun2 = (msg) => {
      return `module2:${msg}`
    }
    
    export default {
      str2,
      fun2
    }
    

    2.3 实现入口文件

    在入口文件 index.js 中导入两个模块。由于 module1.js 是按需导出,故导入时需要使用 {}module2.js 是默认导出,故此处可以直接导入:

    import { str1, fun1 } from './modules/module1'
    import m2 from './modules/module2'
    
    console.log(str1)
    console.log(fun1('程序员优雅哥'))
    console.log(m2.str2)
    console.log(m2.fun2('youyacoder'))
    

    2.4 入口 HTML

    创建 index.html 文件,使用 script 标签导入 index.js

    <script src="./index.js">script>
    

    在浏览器中访问 index.html 文件,控制台会提示如下错误:

    Uncaught SyntaxError: Cannot use import statement outside a module (at index.js:1:1)
    

    这是由于浏览器不认识 ESM 语法。可以使用 babel 将 ES6 语法编译为 ES5 的语法,然后使用 browserify 进行打包;也可以使用 webpack 打包。此处我使用 webpack 5

    2.5 使用 Webpack 打包

    使用 npmyarn 初始化项目:

    yarn init -y
    

    安装 webpackwebpack-cli 为开发依赖:

    yarn add webpack webpack-cli -D 
    

    使用 webpack 打包:

    npx webpack ./index.js -o ./dist/ --mode development
    

    上面的打包命令直接在命令中配置参数,省略了额外的配置的文件。该命令指定了打包的入口文件为:index.js;输出的目录为 dist 目录,打包模式为 development。关于 webpack 5 的使用,有兴趣的可以看优雅哥的 webpack 5 系列文章。

    执行完打包命令后,会生成 dist 目录,并且在该目录中有个 main.js 文件。

    index.html 中删除之前引入的 index.js,替换为 dist/main.js

    <script src="./dist/main.js">script>
    

    重新在浏览器中访问 index.html, 控制台输出如下:

    image-20220926223738435

    3 ES Module 总结

    导出模块:

    • 默认导出:export default xxx
    • 按需导出 export const xxx

    导入模块:

    • 默认导入: import xxx from 'xxx'

    • 按需导入 import { xxx } from 'xxx'

    4 JS 模块化 4 大规范总结

    前面优雅哥依次写了模块化的发展史,模块化的规范(可进主页查看每个规范详细版本),现进行一个大汇总方便大家查阅和总结:

    01- 模块化前传

    02 - Common JS 规范

    03 - AMD 规范(Require JS 实现)

    04 - CMD 规范 (Sea JS 实现)

    05 - ESM 规范

    模块化相关 demo 源码可以 github 搜索关键词 js-module-demo 或联系 程序员优雅哥 获取。

    image

    源码目录如下:

    js-module-demo/
    |- 01_Histry/			模块化发展史
    |- 02_CommonJS/		CommonJS 规范
    |- 03_AMD/				ADM 规范
    |- 04_CMD/				CMD 规范
    |- 05_ESM/				ESM 规范
    

    各个模块化规范有相似之处,也有差异,模块定义与模块加载的语法如下:

    4.1 Common JS 规范

    定义模块的语法:

    // 暴露函数
    module.exports = function () {}
    
    // 暴露对象
    module.exports = {
      xxx: () => {}
    }
    
    exports.xxx = {}
    
    exports.xxx = function() {}
    

    加载模块的语法:

    const xxx = require('xxxx')
    

    4.2 AMD 规范

    定义模块的语法:

    define(id?, dependencies?, factory)
    

    加载模块的语法:

    require([module], callback)
    

    4.3 CMD 规范

    定义模块的语法:

    // 定义模块
    define(function(require, exports, module) {
    	
    	// 使用 exports 导出模块
    	exports.xxx = xxx
    	
    	//也可以使用 return 导出模块
    	// return xxx
    })
    

    加载模块的语法:

    // 同步加载模块
    const m1 = require('../xxx')
    
    // 异步加载模块
    require.async('../xxx', function (m2) {
    })
    

    4.4 ESM 规范

    导出模块:

    // 按需导出
    export const xxx = ''
    export const xxx = () => {}
    
    // 默认导出
    export default xxx
    

    导入模块:

    import { xxx, yyy } from 'xxx'
    import * as xxx from 'xxx'
    import xxx from 'xxx'
    import 'xxx'
    

    感谢你阅读本文,如果本文给了你一点点帮助或者启发,还请三连支持一下,点赞、关注、收藏,作者会持续与大家分享更多干货

  • 相关阅读:
    java计算机毕业设计springcloud+vue购物商城网站系统
    latex 模板使用技巧——参考文献篇
    idea Java代码格式化规范
    图像去雾开源数据集资源汇总
    -----指针进阶
    程序执行的四个阶段
    【配送路径规划】基于matlab遗传算法求解静态外卖骑手路径规划问题【含Matlab源码 2248期】
    在Win11系统中使用TeamCity执行BuildStep时C#/.net6.0的跨平台项目无法build的问题解决
    Spring中的JdbcTemplate的使用
    利用WSL2搭建Qemu仿真Vexpress-a9开发环境
  • 原文地址:https://www.cnblogs.com/youyacoder/p/16738533.html