前言
- cjs就是commonJS,node里面就是这种模块化形式,不能在浏览器工作,需要通过转换打包
- esm js的标准模块化系统方案,具有cjs的简单语法,amd的异步;常用方式import
场景应用
CJS方式和ESM方式写入文件
node执行文件的时候,识别不了esm方式的写法
node在几个场景把内容识别为ES模块
- 带有
.mjs扩展名的文件,优先级大于type配置 - package.json的module配置为type
还有一种方式会识别成ESM模式
- 使用标记为参数带有
--eval,或者通过管道传递nodevi字符串。
STDIN --input-type=module
例子中没办法识别为ES模块,应该是用法的问题
混用的时候,type是为module
Modules loaders模块加载器的加载情况
commonjs模块加载器
- 同步
- 负责处理require()
- 可修补
- 支持文件夹做模块
- 找不到匹配时,会找
.js.json等,然后会尝试把文件夹解析为模块 - 不能加载ECMAscript模块
ECMAScript模块加载器
- 异步
- 负责处理
import import() - 不可修补,使用loader hook自定义
- 不支持文件为模块,必须制定目录索引
- 不进行扩展搜索
- 可以加载json,需要断言
- 只接受.js, .mjs cjs可扩展名
- 可用于加载commonjs,通过cjs-module-lexer
执行问题
commonjs模式运行不了是因为使用了export,export是esm的写法,而esm模式运行不了是因为,本身getUrlParms方法没有做为到处的方式来写。
- main字段只是定义包的主要入口点。
之前支持两种模式的方法
借助 Node 原生支持 CJS 去支持 require 语法,借助 Webpack 等打包工具去识别 package.json 的 module 字段,从而支持 ESM,相对 require 还顺便做到了 tree-shaking。
- node14.13 后提供了exports配置可以解决一些问题,通过不同的指向在引用的时候使用不同的模块
exports使用配置不同环境下,不同的模块入口文件
例如一些第三方 UI 包需要引入对应的样式文件才能正常使用,
import `packageA/dist/css/index.css`;
"exports": { "./style": "./dist/css/index.css' },
import `packageA/style`;
例子
在用typescript结合来开发工具库的同时要了解tsconfig.json中的几个重要参数配置
moduleResolution
模块解析策略,参数 'node'[用于nodejs的commonjs实现], 'node16'[4.7开始支持nodenext], 'classic'[1.6之前]
Specify how TypeScript looks up a file from a given module specifier.
指定 TypeScript 如何从给定的模块说明符中查找文件。
paths
避免代码库中有较长的相对映射
module
指定生成什么模块代码。
target
设置更改了JS哪些功能需要被降级,那些功能保持不变,例如是ES5的,箭头是否要转换为function。【慎用ESNext】
noEmit
不去编译输出文件,如果JS源代码,源映射或说明
resolveJsonModule
允许解析'.json'扩展名的模块
files
指定程序中允许包括的文件,如果找不到任何文件,则会发生错误
includes
制定要包含的文件名或者模式数组【支持通配符来实现glob模式】
exclude
排除include设置的部分文件
allowUnreachableCode
使用 JavaScript 语法而无法访问的代码有关
noImplicitReturns
确保声明后的返回值的能够匹配
rootDirs
允许编辑器解析这些虚拟目录的相对模块导入,好像被合并到同个目录一样
不会影响TS转成JS的方式
"rootDirs": ["src", "generated"]
outFile
所有全局【非模块的】文件连接输出到指定的单个文件
allowSyntheticDefaultImports
允许编写导入
import React from "react"; 替代 import * as React from "react"
esModuleInterop
esModule模块的一些操作,默认情况下,TS会把commonjs/amd/umd
模块视为ES6模块,但是会出现的影响
import * as moment from "moment"
const moment = require("moment")
出现default问题,找不到该default,像Ts,babel, webpack都有相应的机制去处理,这里这个配置就是开启Ts对这块的处理。
import moment from "moment"
const moment = require("moment").default
参考链接