New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
What is 全面ESM
🤩
#826
Comments
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
2023-12-12
随着最后一个 升级stylelint v16并遵循esm语法 的pr
合并vue-pure-admin
全面迈入ECMAScript
模块(ESM)时代,这能很好地适应前端发展潮流,不论从平台角度还是用户角度,它都为后续开发、升级、维护做了较好的铺垫!在前端和
Node.js
开发中,ECMAScript
模块(ESM)和CommonJS
(CJS)是最为常见和广泛使用的两种模块系统先简单介绍一下
CJS
吧CommonJS
(CJS)是一种在Node.js
中广泛使用的模块规范。它被设计用于服务器端JavaScript
环境,但也被用于一些客户端(浏览器)的工具和库中。CommonJS
的主要目标是创建一个模块生态系统,使得开发者可以编写在不同环境下可重用的模块。关键特征
同步加载:
CommonJS
模块通常是同步加载的,这意味着模块在被require
时会立即加载和执行。这在服务器端是可行的,因为文件通常都是本地的,但在浏览器中可能会导致性能问题。模块导出:
CommonJS
模块都有一个module
对象,该对象有一个exports
属性。模块可以通过添加属性到exports
对象或者直接将module.exports
赋值为一个值(如函数、对象或类)来导出内容。模块导入:
require
函数来导入其他模块。require
函数接受一个模块标识符(通常是文件路径)作为参数,并返回该模块导出的内容。模块作用域:
CommonJS
模块中的变量、函数等默认都是私有的,除非它们被明确地导出。基本语法
导出模块
导出一个函数:
导出一个对象:
或者使用
exports
作为module.exports
的快捷方式:导入模块
导入整个模块:
导入特定的函数(如果模块导出了一个对象):
使用场景
CommonJS
最初是为服务器端JavaScript
设计的,特别是Node.js
环境。Node.js
的内置模块(如fs
、http
、path
等)都遵循CommonJS
规范。npm
包都是使用CommonJS
格式编写的。再简单介绍一下
ESM
吧ECMAScript
模块(ESM)是JavaScript
的官方模块系统,由ECMAScript
(ES6)规范定义。ESM
提供了一种在JavaScript
文件之间导入和导出值(如变量、函数、类等)的标准方法。它旨在取代非标准的模块系统,如CommonJS
(CJS),并成为跨环境(浏览器和服务器端)的统一模块解决方案。关键特征
静态结构:
ESM
的导入和导出语句是静态的,正常情况下它们必须出现在模块的顶层作用域,并且不能被条件语句或函数包围。导出和导入语法:
ESM
使用export
关键字来导出模块的公共接口,使用import
关键字来导入其他模块的导出。异步和按需加载:
ESM
支持异步模块加载,允许按需动态导入模块。模块解析:
ESM
的模块解析遵循URL
的规则,可以使用相对路径、绝对路径或URL
。浏览器和
Node.js
支持:ESM
在现代浏览器中得到了原生支持,无需编译或打包。Node.js
从版本12
开始提供了对ESM
的实验性支持,并在后续版本中逐步完善。基本语法
导出模块
命名导出:
默认导出(每个模块只能有一个默认导出):
导入模块
导入命名导出:
导入默认导出:
导入整个模块作为命名空间对象:
动态导入(返回一个 Promise):
使用场景
ESM
被设计用于在浏览器和服务器端(如Node.js
)中作为统一的模块系统。JavaScript
应用程序的推荐方式,特别是单页应用程序(SPA)和服务器端应用程序。ESM
。终于来到全面
ESM
了全面采用
ESM
的好处标准化:
ESM
是ECMAScript
(JavaScript 的官方规范)的原生模块系统,因此它是标准化的,与社区和未来的发展保持一致。更好的模块化:
ESM
提供了静态模块结构,这意味着可以在编译时分析模块依赖关系,而不是在运行时。树摇(Tree Shaking):
ESM
的静态结构,构建工具可以更容易地实现树摇,这是一种移除未使用代码的优化技术。更好的性能:
ESM
可以被异步加载,这意味着可以实现更有效的代码分割和按需加载。Node.js
中的ESM
也可以提高性能,因为它允许更好的模块缓存。原生浏览器支持:
ESM
在所有现代浏览器中均得到支持,无需额外的编译步骤就可以直接使用。更好的跨环境兼容性:
ESM
既可以在浏览器中使用,也可以在服务器端(如 Node.js)中使用,这有助于统一前后端的代码模块化策略。更方便的代码重用:
ESM
,开发者可以更容易地编写可在不同环境中重用的模块,这促进了代码共享和开源库的开发。顶级
await
:ESM
支持在模块顶层直接使用await
关键字,这使得编写依赖于异步操作的模块变得更加简单。更好的工具集成:
JavaScript
工具和框架都是围绕ESM
设计的,这意味着全面采用ESM
可以更好地利用这些工具的能力。更清晰的依赖管理:
ESM
强制显式导入和导出,这使得依赖关系更加清晰,也便于开发者理解和追踪模块之间的联系。更容易的静态分析:
ESM
的静态结构,静态分析工具(如 linters 和 type checkers)可以更准确地分析代码,帮助发现潜在的错误和问题。有助于
TypeScript
的解析和编译:TypeScript
遵循ES
模块的解析算法,这意味着它可以直接利用ESM
的静态导入和导出语句来解析模块依赖。采用纯ESM
有助于TypeScript
编译器更准确地分析依赖关系,并确保模块解析的结果与运行时环境保持一致。ESM
促进了明确的导出和导入语句,这使得TypeScript
能够更精确地进行类型检查和推断。TypeScript
可以利用ESM
的导入导出语句来提供更准确的代码提示和自动化重构全面采用
ESM
的要求(也就是如何判断一个项目是不是采用纯esm
编写)使用
import
和export
语句:import
语句来导入模块。export
语句来导出模块。module.exports
、exports
、require
语法。文件扩展名:
Node.js
中,确保你的JavaScript
文件使用.mjs
或.mts
扩展名或在package.json
中指定"type": "module"
以明确它们是ES
模块,不会出现.cjs
或.cts
扩展名。比如 vue-pure-admin 就明确指出项目使用esm
模块编写,这也对node.js
以及别的工具提供更快模块解析的条件.js
扩展名,并确保服务器正确设置 MIME 类型为application/javascript
。第三方模块:
package.json
文件中的dependencies
和devDependencies
依赖项支持ESM
构建和打包工具:
ESM
的工具链,比如rollup
、esbuild
、vite
等,本项目使用的vite5
也已经 废弃 CJS Node API常见问题解答
问:全面
esm
,好家伙,搞得这么严,如果需要用cjs
语法咋办?答:随着
vite5
废弃 CJS Node API 并将在 vite6 移除,平台也开始全面迁移代码到esm
模块。如果想使用cjs
的话,文件后缀名用.cjs
或.cts
即可总结肯定少不了啊
esm
更快、更潮、更简单esm
易维护、高兼容、更nb😝当然它这么牛,肯定要照顾一下它咯,所以平台新开了个 esmjs组织 专门产出纯
esm
库。当然如果你有想法,比如想开发或迁移一个库将其支持为纯esm
语法,欢迎加入!前端的更新迭代确实太快了,究其原因,还是它太灵活太弱语言了(不是黑它啊🥹),经常被一些后端语言欺负 😮,动不动就写个工具来替代,心累。所以后端语言还是很有必要学习的,推荐学习
rust
,后面也会慢慢成为趋势吧(至少在一些性能工具方面)。有时候不想写总结不想写文章就是因为前端不论从库还是工具来说更换太快,甚至不能用年来计算😓。来学rust
吧 https://github.com/esmjs/geo/issues/1#issuecomment-1831374680后面感觉可以用 bun 代替
nodejs
了,它使用 zig 编写,可以大大减少项目启动时间和内存使用量。好嘛,又一个新语言是吧 🥹,听说它的学习成本不算高,先打个Mark
这样看来未来使用
bun
结合vite
即将推出的rust
版本的Rollup
叫做Rolldown
一起使用,在开发体验和构建速度上有很大的提升啊The text was updated successfully, but these errors were encountered: