本文目录一览:
- 1、在 Node.js 中使用原生 ES 模块方法解析
- 2、使用 MockJs — 实现真正的前后端分离
- 3、「官方」总结2021的IPFS:成为Web3主流势头的支柱
- 4、在node环境下怎么使用commonjs模块去使用require方法
- 5、怎样写一个能同时用于 Node 和浏览器的
在 Node.js 中使用原生 ES 模块方法解析
从版本
8.5.0
开始,Node.js
开始支持原生
ES
模块,可以通过命令行选项打开该功能。新功能很大程度上得归功于
Bradley
Farias。
1.演示
这个示例的代码目录结构如下:
esm-demo/
lib.mjs
main.mjs
lib.mjs:
export
function
add(x,
y)
{
return
x
+
y;
}
main.mjs:
import
{add}
from
'./lib.mjs';
console.log('Result:
'+add(2,
3));
运行演示:
$
node
--experimental-modules
main.mjs
Result:
5
2.清单:需要注意的事情
ES
模块:
·不能动态导入模块。但是
动态import()
的相关工作正在进行中,应该很快就能提供支持。
·没有元变量,如
__dirname
和
__filename。但是,有一个的类似功能的提案:“import.meta”。看起来可能是这样:
console.log(import.meta.url);
·现在所有模块标识符都是
URL(这部分在
Node.js
是新增的):
·文件
-
带文件扩展名的相对路径:
../util/tools.mjs
·库
-
没有文件扩展名,也没有路径
lodash
·如何更好地使
npm
库在浏览器中也可用(不使用
bundler)仍有待观察。一种可能性是引入
RequireJS
风格的配置数据,将路径映射到实际路径。目前,在浏览器中使用
bare
path
的模块标识符是非法的。
与
CJS
模块的互操作性
你可以导入
CJS
模块,但它们总是只有默认的导出
-
即
module.exports
的值。让
CJS
模块支持命名导出已经在做了,但可能需要一段时间。如果你能帮忙,可以来做。
import
fs1
from
'fs';
console.log(Object.keys(fs1).length);
//
86
import
*
as
fs2
from
'fs';
console.log(Object.keys(fs2));
//
['default']
·
不能在
ES
模块中使用
require()。主要原因是:
· 路径解析工作稍有不同:ESM
不支持
NODE_PATH
和
require.extensions。而且,它的标识符始终是
URL
也会导致一些细微差异。
·
ES
模块始终以异步方式加载,这确保了与
Web
的最大兼容性。这种加载风格并不能通过
require()
混合使用同步加载
CJS
模块。
·
禁止同步模块加载也可以为
Top-level
await
导入
ES
模块保留后路(一个当前正在考虑的功能)。
3.早期版本的
Node.js
上的
ES
模块
如果要在
8.5.0
之前的
Node.js
版本上使用
ES
模块,请参阅
John-David
Dalton
的
@std/esm。
提示:如果不启用任何可解锁的额外功能,将在
Node.js
保持
100%
兼容原生
ES
模块.
FAQ
什么时候可以不带命令行选项使用ES
模块?
目前的计划是在
Node.js
10
LTS
中默认可使用
ES
模块。
进一步阅读
有关
Node.js
和浏览器中
ES
模块的更多信息:
·
“Making
transpiled
ES
modules
more
spec-compliant”
[using
ES
modules
natively
vs.
transpiling
them
via
Babel]
·
“Module
specifiers:
what's
new
with
ES
modules?”
[Why
.mjs?
How
are
module
specifiers
resolved?
Etc.]
·
“Modules”
[in-depth
chapter
on
ES
modules
in
“Exploring
ES6”]
即将到来的
ECMAScript
提案:
·
博客:
“ES
proposal:
import()
–
dynamically
importing
ES
modules”
·
提案:
“import.meta”
总结
以上就是小编给大家带来的在
Node.js
中使用原生
ES
模块方法解析的全部内容,希望对大家有所帮助。如果您有什么问题,可以给我留言。感谢大家对本站的支持。
使用 MockJs — 实现真正的前后端分离
前言: 刚刚看了下的后台,发现我技术文章中,阅读留言最多的是关于移动端的文章,甚至还有人付费赞赏或咨询。关于 PC 端的技术文章就显得比较冷清了,唉,废了好大劲写的,没人看。 和我想的一样,移动端才是王道,下次找工作我也搞移动端? 。
背景: 去年我写了一篇 学习使用 json-server 和 mockjs 的文章,当时没有仔细研究,文章只提到了 MockJs 其中一个 Random 的用法,关于 MockJs 拦截器和另一个很常用的 Mock.mock 函数都没有提及。这次来搞一下。
唉!以前我也是经常会听到 前后端分离 这个名词,只模糊的知道它最重要的一个作用就是,大大的提升了 前端的地位。 但是平时在开发的时候,我也会想奶奶的,没有接口这前端不就写了一个破页面,后期还的和后端对接口,对接口的时候花费的时间,肯定是不比前端开发的时候短,工期上最起码一半一半吧, 这也就前后端分离 ,我这个小脑袋就不是太明白了。
不过我现在是终于搞明白这个问题了, 对于前端来讲,真正的前后端分离,标志是不依赖后端的前端工作开发完成,项目基本宣告结束。 后端开发完接口,只需要提换一个 URL 就行了,这也意味着前端需要去写一些接口。
除了带来开发任务稍微重点外,我至少看到了两个最大的优点:
我体会最深就是这两点。
插曲 :对了,今天中午我捡到一个手机,我必须要用一张动图来描述下:
这个经典的 GIF ,来自郑伊健的恐怖电影「第一诫」,清凉一冬,绝对值得一看,虽然剧情有很大的 bug ,但是港片就这点好,它有很抓人的地方,让你觉得特别好看。
正文由此开始:
待续~~~
上面三种方案都可以,但你要知道接口很多,需要支持批量引入,所以 使用 Axios 响应拦截器 就不太可取,只能在这简单的造些假数据。
著名开源项目 vue-element-admin 开发环境下模拟假接口使用的是 在 webpack-dev-server 的 before 处拦截。生产环境下是在项目入口文件( index,js )使用 Mock.mock 模拟的。
拦截请求的步骤如下,根据 devserverbefore 配置的栗子?:
可知道 before 接收一个函数,函数的第一个参数一般叫 app ,因为它的作用和 express 的 app 是等效的。也就是说这个 app 自带路由, 正好解决接口批量引入的问题。
在项目中,一般都是这么写,把逻辑提出去:
./mock/mock-server.js 文件的内容为:
./mock/index.js 文件的内容为:
mockXHR 不用看,因为这是给线上环境用的,所以可以简单的改写为:
随便找一个,例如 user 看下接口怎么写的:
完美,到此结束。
我想你一定对更改文件的时候,为什么要 清路由和清缓存感兴趣。
如果熟悉 express 框架,看到 app._router.stack 你就知道了。不知道也没关,我演示给你看,新建一个JS 文件,文件内容为:
执行结束,看在 test.js 文件的内容:
发现没,重复被添加的路由,不是覆盖而是扩展。
这个涉及到 CJS 模块的运行机制, 记住 require 的文件会被加到 require.cache 里面,当文件改变读的是缓存,而不是最新更改的文件。
项目结构过大,如果只在 mock 文件夹里面管理有点麻烦,我就想在页面所在目录直接写接口,怎么办?没错使用 require.context 来批量引入。但是 NodeJs 是没有批量引入的 API 的。找遍了 npm 也没发现一个 package 和 require.context 长得像的。
难道没办法了吗?当然不是,自己动手丰衣足食。 依照 vue-cli 插件的命名规范,我给写的 package 取名 node-plugin-require-context ,简单讲下实现原理:
其实还有一个缺点,如果你看过 Antd-Pro 项目,你就会发现它模拟数据,模块化采用的是 ESModule ,而不是 CJS。保持编码模块化风格一致确实也是需要优化的一个地方,不管了,反正我不干。
官网本来就是中文的,我在使用中发现写的贼好,我就不用画蛇添足了。建议每次使用前:
「官方」总结2021的IPFS:成为Web3主流势头的支柱
原文:
Web3 应用程序在 2021 年的受欢迎程度飙升。该技术用例的增长也为支持它们的基础设施带来了更大的需求。 IPFS 已成为开发人员和用户在新兴 Web3 生态系统中使用的解决方案不可或缺的一部分。 网络统计:存储在 IPFS 上的 NFT:15M+每周唯一活跃 IPFS 节点:230K+ipfs.io 网关用户每周:370 万+ipfs.io 每周网关请求:805M+
2021 年合作与整合
拥有 IPFS 和NFT.Storage等工具 , Web3.存储 , 和Estuary 在后端使项目能够提供分散存储功能作为其产品的一部分。
让我们来看看一些最值得注意的应用程序:
1 Opensea 集成 NFT.Storage 以实现安全、平台范围的 NFT 持久性
OpenSea 是去中心化网络上最大的 NFT 市场之一。它合作了 与 IPFS 和 FIlecoin 集成 NFT.Storage 并允许用户“冻结”他们的 NFT 元数据。这个过程允许创作者真正去中心化他们的 NFT,将权力交还给创作者,而不是托管者。
如今, OpenSea 用户可以创建不可变的 NFT 数据以持久存储在 Filecoin 的区块链上,并通过 IPFS 内容 ID 完成检索数据的寻址。 IPFS 内容寻址通过消除“地毯拉动”或 NFT 元数据错位的可能性,为 NFT 托管提供了完美的解决方案。
2 Brave 在其正在进行的 Web3 集成中添加了对 IPFS 的本地支持
在包含自己的加密货币钱包之后,Brave 通过集成 IPFS,继续为其桌面 Web 浏览器添加 Web3 功能。 现在允许用户通过本地解析 IPFS 地址来访问存储在协议上的内容。
整合是多年合作的结果 两个团队之间的合作, 目标是让最终用户尽可能地访问 IPFS。这是朝着将 IPFS 转变为所有浏览器最终可能支持的公认互联网标准迈出的一大步。
3 Opera 扩展了对 IPFS 协议寻址的支持
Opera 于 2020 年首次在其 Android 浏览器中添加了对 IPFS 的支持 。今年,它将相同的功能扩展到其Opera Touch iOS 用户的浏览器,允许他们导航到 ipfs:// 和 ipns:// 地址。
4 Pinata 让任何人都可以轻松利用 IPFS
这种固定和文件管理服务允许用户以简单无缝的方式存储区块链经常引用的内容。 Pinata 充分利用IPFS 固定服务 API 将内容发布到 IPFS 网络,允许基于 CID 的去中心化存储和高效检索 。
5 ScalaShare 通过 IPFS 为 Web3 带来了安全的文件共享
互联网上用户之间的文件共享始于 P2P 共享,但ScalaShare 带来了 在 IPFS 的帮助下将此功能应用于 Web3。 对于那些不愿意将数据交给大公司的人来说,这个简单的开源工具可能会成为首选的文件存储系统。
6 Audius 依靠 CID 按需流式传输音乐
Audius 将 Web3 上的音乐流媒体服务带入了一个新的方向。 Audius使用 IPFS 集成来存储和检索数据 可以确保没有断开的曲目链接,并且所有音乐都交付给用户,而不依赖于集中式服务器 。
IPFS 的 CID 是确保此音乐流媒体服务正常运行并继续使用的关键 流行的 Web 2.0 应用程序(如 TikTok)上的 Web3 基础架构。
7 Palm 在其可持续的 NFT 平台上使用 IPFS 进行存储
这个相对较新的 NFT 工作室最近与 IPFS 合作。Palm 具有用于生成 NFT 的可持续架构。它使用基于代币的经济来维持具有快速交易时间和低gas费用的生态系统,所有这些都基于节能技术。 IPFS 提供了它需要的解决方案,以确保用户始终可以访问他们的工作 。
8 Valist 信任 IPFS 以实现安全的 Web3 软件分发
通过网站或应用商店发布软件有时会引入安全问题,正如 2020 SolarWinds 攻击所证明的那样。Valist通过允许开发团队以 Web3-native 方式分发软件来解决这个问题。 IPFS 通过提供大量开箱即用的安全保证,充当 Valist 的主要存储层。
9 Snapshot 确保 DAO 投票过程通过 IPFS 去中心化
流行的 DAO 投票系统快照 依赖 IPFS 作为其基础设施的核心部分。 它允许 DAO 成员通过去中心化投票过程就特定协议提案达成共识。快照是从产品到协议的一切社区治理不断增长的空间中最常用的工具之一
技术更新
2021 年还见证了 IPFS 工作方式的多项技术更新。其中的核心是:
1 IPFS 0.11.0
这是面向 Go 开发人员的 IPFS 实现。除了重要的修复之外, 最新版本还改进了 UnixFS 分片和 PubSub 实验以及对 Circuit-Relay v2 的支持 。在这一年中,还进行了其他改进,例如:
对 go-ipfs 的 IPLD 内部结构的更改使使用非 UnixFS DAG 更容易提供多种新命令和配置选项网关支持通过 DAG 导出端点下载任意 IPLD 图自定义 DNS 解析器支持非 ICANN DNSLink 名称单独打包的迁移为 Apple M1 硬件构建固定服务的 WebUI 支持远程固定服务更快的固定和取消固定
2 JS IPFS 0.60.0
JS IPFS 是基于 JavaScript 的类似实现。 它缓解了将 IPFS 数据与 JavaScript 应用程序链接的问题,允许开发人员使用它来本地访问 IPFS 数据 。最新版本包括重要的错误修复,并且全年进行了重要的改进,例如:
ESM 和 CJS 双重发布一个更简单的 globSource APIPubSub 支持解决浏览器连接限制ipfs.get 上的压缩包输出默认从 RSA 切换到 Ed25519Dag 导入导出实现更好的类型定义启用 NAT UPnP 打孔在 ipfs-http-client 中添加了对支持远程固定服务的支持
3 IPFS 集群 0.14.1
用于设置和运行 IPFS 集群的源代码 。这个开源发行版向更多用户和开发人员打开了 IPFS 的世界。在这一年中,它收到了更新,包括:
提高可以列出 pinset 的速度将内容迁移到新集群时更灵活CAR导入支持批量固定摄取对 Badger 数据存储的自动垃圾收集
为了更好地理解为什么这些改进很重要,请务必查看本技术指南 到 IPFS。
采用的下一步
尽管 IPFS 在去年取得了长足的进步,但仍有增长空间。新的合作伙伴关系和进步将是更广泛的 Web3 可用性的关键。 随着越来越多的主流用户意识到对去中心化互联网的需求,对 IPFS 等工具的需求将会增加 。随着他们继续进入这个领域,我们将看到 2022 年会带来什么。
在node环境下怎么使用commonjs模块去使用require方法
最初的 CommonJS 小组 的参与者们决定弄一份于时下的 JavaScript 编程语言有效,但不必束缚于浏览器 JS 环境的限制,的模块规范。开始的愿景是在浏览器里使用一些权宜之计, 并希望能借此影响浏览器厂商,促使它们为这种模块规范的原生支持提供解决方案。权宜之计有:
要么使用一个服务来转译 CJS 模块成浏览器中可用的代码
要么使用 XMLHttpRequest(XHR)以文本形式加载模块,再在浏览器中做文本变换、解析的工作
CJS 模块规范仅允许每文件一个模块,所以为优化、打包,可使用某种“转换格式”将多个模块合并到单个文件。
通过这种方式,CommonJS 小组搞定了依赖引用、如何处理循环依赖,以及如何获得当前模块的某些属性等问题。 但是,他们并没能接纳浏览器环境里不可改变、并且仍将影响模块设计的某些特性:
网络加载
异步继承 … 这也同时意味着他们为了实现这个规范,将负担更多地放到了 Web 开发者身上,而这些权宜之计也使调试变得更麻烦。 调试 eval 的代码,或者调试多个文件合并之后的单个文件,都有实际使用时的坏处。 这些缺点或许在未来某天会被浏览器调试工具解决掉,但结论仍然是:在最普遍的 JS 环境,浏览器中,使用 CommonJS 模块并不是最好的办法。
怎样写一个能同时用于 Node 和浏览器的
因此让我们来写一个小的 JavaScript 包,叫做 base64-encode-string。它所做的只是接收一个字符串作为输入,输出其 base64 编码的版本。
对于浏览器来说,这很简单:我们只需要使用自带的 btoa 函数:
module.exports = function (string) {
return btoa(string);
};
然而在 Node 里并没有 btoa 函数。因此,作为替代,我们需要自己创建一个 Buffer,然后在上面调用 buffer.toString():
module.exports = function (string) {
return Buffer.from(string, 'binary').toString('base64');
};
对于一个字符串,这两者都应提供其正确的 base64 编码版本,比如:
var b64encode = require('base64-encode-string');
b64encode('foo'); // Zm9v
b64encode('foobar'); // Zm9vYmFy
现在我们只需要一些方法来检测我们究竟是在浏览器上运行还是在 Node 上,好让我们能保证使用正确的版本。Browserify 和 Webpack 都定义了一个叫 process.browser 的字段,它会返回 true(译者注:即浏览器环境下),然而在 Node 上这个字段返回 false。所以我们只需要简单地:
if (process.browser) {
module.exports = function (string) {
return btoa(string);
};
} else {
module.exports = function (string) {
return Buffer.from(string, 'binary').toString('base64');
};
}
现在我们只需要把我们的文件命名为 index.js,键入 npm publish,我们就完成了,对不对?好的吧,这个方法有效,但不幸的是,这种实现有一个巨大的性能问题。
因为我们的 index.js 文件包含了对 Node 自带的 process 和 Buffer 模块的引用,Browserify 和 Webpack 都会自动引入 其 polyfill,来将它们打包进这些模块。
对于这个简单的九行模块,我算了一下, Browserify 和 Webpack 会创建 一个压缩后有 24.7KB 的包 (7.6KB min+gz)。对于这种东西,用掉的空间实在是太多,因为在浏览器里,只需要 btoa 就能表示这个。
“browser” 字段,我该如何爱你
如果你在 Browserify 或者 Webpack 文档里找解决这个问题的提示,你可能最后会发现 node-browser-resolve。这是一个对于 package.json 内 "browser" 字段的规范,可以被用于定义在浏览器版本构建时需要被换掉的东西。
使用这种技术,我们可以将接下来这段加入我们的 package.json:
{
/* ... */
"browser": {
"./index.js": "./browser.js"
}
}
然后将函数分割成两个不同的文件:index.js 和 browser.js:
// index.js
module.exports = function (string) {
return Buffer.from(string, 'binary').toString('base64');
};
// browser.js
module.exports = function (string) {
return btoa(string);
};
有了这次改进以后,Browserify 和 Webpack 会给出 更加合理的包:Browserify 的包压缩后是 511 字节(315 min+gz),Webpack 的包压缩后是 550 字节(297 min+gz)。
当我们将我们的包发布到 npm 时,在 Node 里运行 require('base64-encode-string') 的人将得到 Node 版的代码,在 Browserfy 和 Webpack 里跑的人会得到浏览器版的代码。
对于 Rollup 来说,这就有点复杂了,但也不需要太多额外的工作。Rollup 用户需要使用 rollup-plugin-node-resolve 并在选项里将 browser 设置为 true。
对 jspm 来说,很不幸地,没有对 “browser” 字段的支持,但是 jspm 用户可以通过 require('base64-encode-string/browser') 或者 jspm install npm:base64-encode-string -o "{main:'browser.js'}" 来迂回地解决问题。另一种方法是,包的作者可以在他们的 package.json 里 指定一个 “jspm” 字段。
进阶技巧
这种直接使用的 "browser" 方法可以工作得很好,但是对于大型项目来说,我发现它在 package.json 和代码库间引入了一种尴尬的耦合。比如说,我们的 package.json 会很快长成这样:
{
/* ... */
"browser": {
"./index.js": "./browser.js",
"./widget.js": "./widget-browser.js",
"./doodad.js": "./doodad-browser.js",
/* etc. */
}
}
在这种情况下,任何时候你想要一个适配于浏览器的模块,都需要分别创建两个文件,并且要记住在 "browser" 字段上添加额外行来将它们连接起来。还要注意不能拼错任何东西!
并且,你会发现你在费尽心机地将微小的代码提取到分离的模块里,仅仅是因为你想要避免 if (process.browser) {} 检查。当这些 *-browser.js 文件积累起来的时候,它们会开始让代码库变得很难跳转。
如果这种情况变得实在太笨重了,有一些别的解决方案。我自己的偏好是使用 Rollup 作为构建工具,来自动地将单个代码库分割到不同的 index.js 和 browser.js 文件里。这对于将你提供给用户的代码的解模块化有额外的价值,节省了空间和时间。
要这样做的话,先安装 rollup 和 rollup-plugin-replace,然后定义一个 rollup.config.js 文件:
import replace from 'rollup-plugin-replace';
export default {
entry: 'src/index.js',
format: 'cjs',
plugins: [
replace({ 'process.browser': !!process.env.BROWSER })
]
};
(我们将使用 process.env.BROWSER 作为一种方便地在浏览器构建和 Node 构建间切换的方式。)
接下来,我们可以创建一个带有单个函数的 src/index.js 文件,使用普通的 process.browser 条件:
export default function base64Encode(string) {
if (process.browser) {
return btoa(string);
} else {
return Buffer.from(string, 'binary').toString('base64');
}
}
然后将 prepublish 步骤添加到 package.json 内,来生成文件:
{
/* ... */
"scripts": {
"prepublish": "rollup -c index.js BROWSER=true rollup -c
browser.js"
}
}
生成的文件都相当直白易读:
// index.js
'use strict';
function base64Encode(string) {
{
return Buffer.from(string, 'binary').toString('base64');
}
}
module.exports = base64Encode;
// browser.js
'use strict';
function base64Encode(string) {
{
return btoa(string);
}
}
module.exports = base64Encode;
你将注意到,Rollup 会按需自动地将 process.browser 转换成 true 或者 false,然后去掉那些无用代码。所以在生成的浏览器包里不会有对于 process 或者 Buffer 的引用。
使用这个技巧,在你的代码库里可以有任意个的 process.browser 切换,并且发布的结果是两个小的集中的 index.js 和 browser.js 文件,其中对于 Node 只有 Node 相关的代码,对于浏览器只有浏览器相关的代码。