模块化开发

本文探讨了模块化开发的历史演变,从基于文件的原始方式到ESM模块系统的标准化。讲解了CommonJS、AMD和ESM规范,以及它们在浏览器和Node.js中的应用,包括打包工具的优化技巧和跨环境兼容策略。
摘要由CSDN通过智能技术生成

模块化开发是一种思想 是一种代码组织方式 

本记内容:

|演变                                                          |模块化规范

|常用打包工具                                            |举例:基于模块化工具构建的现代web 应用

|打包工具的优化技巧演变

演变

1. 基于文件划分(原始方式):     功能/模块数据 - 单独存放到一个文件中 - <script> 引入

                                                        缺陷: 全局工作|命名冲突|依赖关系管理问题

2. 命名空间方式(基于第一中) : 每一个模块 只 暴露 一个全局对象  -  <script> 引入

                                                        解决了:命名冲突问题

                                                        未解决:全局工作|依赖关系管理

3. 立即执行函数(IIFE):             将数据放入函数私有作用域中,需要全局的则挂在全局

                                                        window.moduleA = { .... }

                                                        解决了: 全局工作/私有空间

                                                        未解决: 依赖关系管理问题


模块化规范

最佳实践: Node.js     =  Common JS 

                   Browsers  =   ES Modules (ES6 定义的模块系统)|语言层面

1. Common JS 规范:一个文件一个模块一个作用域 |使用: module.exports  + require 

                                   同步加载模式 | node 环境ok:node 启动时加载所有模块,需要时调用

                                   浏览器 问题: 页面加载出现大量同步请求出现 => 效率低下

2. AMD|异步模块定义:为浏览器设计的规范 | 社区提出的规范 

                                    约定:每一个模块都通过 define 定义 |require 加载模块

                                    弱点:使用相对复杂|模块JS文件请求频繁

                                    代表:require.js (实现了AMD + 模块加载器)

                                    使用:define(参数1 字符:模块名字,

                                                            参数2 数组: 声明模块依赖 ,

                                                            参数3 函数: 其参数与参数2对应:

                                                                                  为当先模块提供私有空间

                                                                                  return 向外部导出成员 )

                                                 require(数组:依赖,函数)

3. ES Module

内容:特性 和 语法 | 兼容性问题

基本特性:  <script type="module'></script>

                    1. 自动采用严格模式 => 全局模式下 this is undefined | 忽略'use strict'

                    2. 每一个module 都有独立的作用域

                    3.  CORS 方式请求 外部模块 |需要外部服务器响应头中提供CORS header

                            3a.  CORS 不支持文件方式访问, 必须以http server 访问

                    4. 延迟执行 script, 相当于 <script defer></script> | 等待渲染完成加载script

                      |注:网页默认是对script 立即执行的|

导出 和 导入 :

const foo = 'content'

const bName = 'export default'

export { foo }       // 导出

        | export 可以修饰变量 |也可以修饰函数

        |export { name1, name2 ... } 底部集中导出, 常见方法

        |导出 成员重命名: export {

                                                name1 as fooName1 // import 使用fooName1

                                                name2 as default

                                                //特殊情况:重命名为defualt时 导入需要重命名

                                           }

        |export default bName // 将bName 作为默认导出 // export default <变量|值>

        |注意点: export { foo, bar } // 不是字面量,而是固定语法 export { }

                           export default { foo, bar }  // 导出一个对象,foo bar 为keys


import { foo } from './module.js'       // 导入   

import { default as aName } from './module.js'    // default 导入需要重命名

import someName from './module.js' // 直接使用变量名导入默认成员

        | import 的 变量 是只读

        |import { name } from './module.js' // 相对路径  .js 不能省略, 必须提供完整路径

                                                                // 否者:ESM 会 加加载第三方模块

         | import { name } from '/src/module.js' // 绝对路径 |从网站根目录开始

         | import { name } from 'http://localhost3000/src/module.js' // url 地址 

        |import { } from './module.js' // 只执行 不提取 === import './module.js'

        |import * as mod from './module.js' // 全部提取放入对象中,成员为mod的值

        |import('./module.js').then( function( module) { .... } ) // 动态加载模块,

                                                                                             // 通过参数获取成员

       |import { name, age, default as title } from './module.js'  // 传入多个 

       | import title,{ name, age } from './module.js' // 简写上一行

       | export { name } from './module.js' // 直接导出导入结果

                        import   { name } from './components.js'

                        export { name } 

4. ES Module in Browsers

polyfill 兼容方案 | ES Module 2014 出生|有些浏览器不支持

browser-es-module-loader

通过unpkg获取地址:unpkg.com/browser-es-module-loader

                                   https://unpkg.com/browse/browser-es-module-loader@0.4.1/dist/ 

promise-polfill:  https://unpkg.com/promise-polyfill

<script nomodule></script> 只在不支持ESM的浏览器工作|动态解析脚本|生产模式❌

4. ES Module in Node.js

1. 文件名: .js => .mjs

2. 全部引用:

     import fs from 'fs'  // working | 内置

     import _ from 'lodash' // working | 第三方


直接引用成员:

    import { writeFileSync } from 'fs' // working |内置|已兼容

    import { camelCase } from 'lodash' // not working |第三方|未兼容

5. Common JS 和 ESM 交互

1. ESM 可以直接导入 CJS 模块

2. ESM 不能直接导入CJS 模块成员: import { } 不是解构

3. Node 环境中:CJS 模块 不能 导入 ESM 模块

6.Common JS 中模块成员 在 ESM 中不可用

 require | module| exports 使用 import export 代替

__filename | __dirname : import.meta.url (代码段)

import { fileURLToPath } from 'url'
const __filename = fileURLToPath(import.meta.url)
import { dirname } from 'path'
const __dirname = dirname(__filename)

7. 新版本node中 ESM 支持

1. package.json 中  { "type": "module"}  => 主 ESM 辅 CJS

2. 则 CJS 书写的js文件 改名为 .cjs

8. Node.js Bable 兼容方案

低版本node 中使用 ESM

使用bable 运行node: @babel/node 它需要依赖 @babel/core 和 @babel/prset-env

yarn add @babel/node @babel/core @babel/preset-env

yarn add@babel/plugin-transform-modules-commonjs@7.6.0 --dev


    "@babel/core": "^7.6.0",
    "@babel/node": "^7.6.1",
    "@babel/plugin-transform-modules-commonjs": "^7.6.0"

yarn babel-node index.js //运行文件

yarn babel-node index.js --presets=@babel/presets-env // 添加preset 编译 

 为babel 添加配置文件 转换 ESM 

// .babelrc
{
    "presets":["@babel/preset-env"]
}
// .babelrc
{
    plugins: ["@babel/plugin-transform-modules-commonjs"]
}
// node
yarn babel-node index.js // 添加配置文件后可以直接运行文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值