【node】深入探讨 class URL
📌 浅说 fileURLToPath()
在vite.config.ts
中有这么一段代码:
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
export default defineConfig({
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
咱们先来讲讲 fileURLToPath
:
// * @param url The file URL string or URL object to convert to a path.
url:url要转换为路径的文件url字符串或url对象。
// * @default undefined
options: 如果' path '应该作为Windows文件路径返回,则为' true ',如果为posix则为' false ',如果为系统默认值则为' undefined '。
// * @return The fully-resolved platform-specific Node.js file path.
返回:特定平台完全解析的Node.js文件路径。
以下示例,来加深理解:
import { fileURLToPath } from 'node:url'
import.meta.url
// file:///D:/test-project/vite.config.ts
fileURLToPath(import.meta.url)
// D:\test-project\vite.config.ts
❌new URL('file:///C:/path/').pathname
// Incorrect: /C:/path/
✔️ fileURLToPath('file:///C:/path/')
// Correct: C:\path\ (Windows)
❌ new URL('file://nas/foo.txt').pathname
// Incorrect: /foo.txt
✔️ fileURLToPath('file://nas/foo.txt')
// Correct: \\nas\foo.txt (Windows)
❌ new URL('file:///你好.txt').pathname
// Incorrect: /%E4%BD%A0%E5%A5%BD.txt
✔️ fileURLToPath('file:///你好.txt')
// Correct: /你好.txt (POSIX)
❌ new URL('file:///hello world').pathname
// Incorrect: /hello%20world
✔️ fileURLToPath('file:///hello world')
// Correct: /hello world (POSIX)
回到 vite.config.ts
代码段, 来看看这句代码的输出内容是什么:
fileURLToPath(new URL('./src', import.meta.url))
// console
D:\test-project\src
没错,这个输出结果和模块作用域(__filename
/_dirname
)相似,如:
- __filename
__filename
// console
D:\test-project\vite.config.ts
- __dirname
__dirname
// console
D:\test-project
- path.dirname(__filename)
path.dirname(\_\_filename)
// console
D:\test-project
那么这段代码的含义,就是使用文件系统路径进行别名化
处理
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
比如,有这么一个文件目录树
test-project/
├── src/
│ ├── assets/
│ │ └── logo.svg
│ └── App.vue
├── index.html
├── vite.config.ts
└── package.json
在 App.vue
中有这么一段代码,来阐述文件路径别名的实际应用:
<img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />
当然,alias
并不局限对象来实现文件路径别名。它可以是一个 对象
,或一个 数组
,类型如下:
Record<string, string> |
Array<{
find: string | RegExp
replacement: string
customResolver?: ResolverFunction | ResolverObject
}>
🔍 探讨 new URL()
与 new URL()
区别
回到正题,探讨 new URL()
既然有 Web API 的
new URL()
,那么nodejs
为什么又重写呢?
-
import { URL } from 'node:url'
中的URL
是 Node.js 提供的内置模块url
中的类,用于处理 URL。 -
而 MDN 的 URL API 是指 Web 标准中定义的用于处理 URL 的 JavaScript API。
这两者虽然都是用于处理 URL,但有一些区别:
-
Node.js URL 模块:Node.js 的
url
模块提供了一组用于解析和格式化 URL 的实用工具。它主要用于服务器端的 JavaScript 程序,如在 HTTP 请求中解析 URL,或在文件系统中处理文件路径。它与浏览器的 URL API 在一些细节上有所不同,因为 Node.js 和浏览器在处理 URL 和文件路径时有不同的需求。 -
MDN URL API:MDN 上的 URL API 是 Web 标准中定义的 JavaScript API,用于在浏览器环境中处理 URL。它提供了一组用于创建、解析和操作 URL 的方法和属性。与 Node.js 的 URL 模块相比,它更适用于在客户端 JavaScript 中操作 URL,如在 Web 应用程序中处理页面的 URL。
虽然这两者有不同的实现和使用场景,但它们都是用于处理 URL 的工具。如果你在 Node.js 环境下开发,可以使用 node:url
模块中的 URL
类。如果你在浏览器环境下开发,可以使用浏览器原生的 URL API。
方法使用、输出区别
- node
// vite.config
import { URL } from 'node:url'
new URL(import.meta.url)
// terminal
URL {
href: 'file:///D:/test-project/vite.config.ts',
origin: 'null',
protocol: 'file:',
username: '',
password: '',
host: '',
hostname: '',
port: '',
pathname: '/D:/test-project/vite.config.ts',
search: '',
searchParams: URLSearchParams {},
hash: ''
}
- WEB API
// App.vue
new URL(import.meta.url)
// Browser console
URL {
hash: "",
host: "localhost:5173",
hostname: "localhost",
href: "http://localhost:5173/src/App.vue",
origin: "http://localhost:5173",
password: "",
pathname: "/src/App.vue",
port: "5173",
protocol: "http:",
search: "",
searchParams: URLSearchParams {size: 0},
username: "",
}
本质区别就是 web api: URL
无需引用便可用,它是浏览器中的一个标准,当然由浏览器去解析。
如果浏览器尚不支持
URL()
构造函数,则可以使用Window中的Window.URL
属性。
但是如果你这么做:
// browser
console.log(new URL(import.meta.url))
// console
Uncaught SyntaxError: Cannot use 'import.meta' outside a module
原因是,浏览器终端无法处理 import.meta
, 它由 JavaScript
运行时(即浏览器
或 Node.js
)负责处理,然后交给浏览器呈现。
当然,你可以这么做:
// Browser console
console.log(new URL('file:///D:/test-project/vite.config.ts'))
// console
URL {
hash:"",
host:"",
hostname:"",
href:"file:///D:/test-project/vite.config.ts",
origin:"file://",
password:"",
pathname:"/D:/test-project/vite.config.ts",
port:"",
protocol:"file:",
search:"",
searchParams: URLSearchParams { size:0 },
username:""
}
来一个横向比较图示:
(pc端看效果更佳)
🔐 剖析 Node class URL
参照标准:URL Standard
让我们来看看nodejs
的URL
类的基本结构是怎么写样的:
class URL {
static createObjectURL(blob: NodeBlob): string
static revokeObjectURL(id: string): void
static canParse(input: string, base?: string): boolean
constructor(input: string | { toString: () => string }, base?: string | URL)
hash: string
host: string
hostname: string
href: string
readonly origin: string
password: string
pathname: string
port: string
protocol: string
search: string
readonly searchParams: URLSearchParams
username: string
toString(): string
toJSON(): string
}
方法:
-
createObjectURL(blob)
- 用途:创建一个指向传入的
Blob
对象的 URL。 - 注意事项:需要注意在使用后需要通过
revokeObjectURL(id)
来释放 URL,防止内存泄漏。 - 示例:
const { URL } = require('url') const url = new URL('https://example.com') const blob = new Blob(['Hello, world!'], { type: 'text/plain' }) const objUrl = url.createObjectURL(blob) console.log(objUrl) // 输出类似 'blob:https://example.com/5a3c5ebc-79f9-4a70-a3ec-6d9f8a2f2c5f' url.revokeObjectURL(objUrl) // 使用后需要撤销 URL
- 用途:创建一个指向传入的
-
revokeObjectURL(id)
- 用途:释放之前通过
createObjectURL
创建的 URL。 - 注意事项:调用后,之前通过
createObjectURL
创建的 URL 将不再有效,应及时释放以避免内存泄漏。 - 示例:见上面的示例。
- 用途:释放之前通过
-
canParse(input, base)
- 用途:检查给定的字符串是否能被解析为有效的 URL。
- 注意事项:返回一个布尔值,用于判断是否能够成功解析。
- 示例:
const { URL } = require('url') console.log(URL.canParse('https://example.com')) // true console.log(URL.canParse('not_a_url')) // false
属性:
-
hash
- 用途:获取或设置 URL 的片段标识符(即
#
后面的内容)。 - 注意事项:可以直接读取和修改,修改后 URL 对象的其他部分会相应更新。
- 示例:
const { URL } = require('url') const url = new URL('https://example.com#section') console.log(url.hash) // 输出 '#section' url.hash = '#newsection' console.log(url.href) // 输出 'https://example.com#newsection'
- 用途:获取或设置 URL 的片段标识符(即
-
host / hostname / href / origin / password / pathname / port / protocol / search / username
- 用途:分别获取或设置 URL 的主机、主机名、完整 URL、源、用户名、路径名、端口、协议、查询部分。
- 注意事项:这些属性用于精确控制和操作 URL 的不同部分,修改后 URL 对象的其他部分会相应更新。
- 示例:
const { URL } = require('url') const url = new URL('https://username:password@example.com:8080/path?query=string#fragment') console.log(url.host) // 输出 'example.com:8080' console.log(url.pathname) // 输出 '/path' url.protocol = 'https:' url.searchParams.set('newparam', 'value') console.log(url.href) // 输出 'https://username:password@example.com:8080/path?query=string&newparam=value#fragment'
-
searchParams
- 用途:获取 URL 查询参数部分的
URLSearchParams
对象,用于操作和管理 URL 的查询参数。 - 注意事项:可以使用
set()
、get()
、append()
、delete()
等方法来修改查询参数,修改后 URL 对象的href
属性会相应更新。 - 示例:
const { URL } = require('url') const url = new URL('https://example.com/path?query=string') url.searchParams.set('newparam', 'value') console.log(url.href) // 输出 'https://example.com/path?query=string&newparam=value'
- 用途:获取 URL 查询参数部分的
其他方法:
- toString():返回序列化后的完整 URL 字符串。
- toJSON():返回 URL 对象的 JSON 表示,通常与
JSON.stringify()
结合使用。
实际应用场景:
这些方法和属性使得 URL
类在 Node.js 中成为处理和操作 URL 非常便捷的工具,特别适用于需要频繁处理 URL 的场景,如 Web 服务器开发
、爬虫程序
等。
⛳ 总结
当谈论现代 Web 开发时,涉及到多种 URL 相关的概念和工具。
Node.js 中的 URL 类提供了强大的 URL 解析和操作功能,适用于服务器端和脚本任务。例如,它允许开发者轻松解析和修改 URL 的各个部分,如协议、主机名、路径和查询参数。
与此同时,Vite 提供了 fileURLToPath 函数,用于将文件 URL 转换为本地文件路径,便于在开发过程中处理模块和资源。
此外,Vite 还支持使用 alias 别名,使开发者能够通过自定义简短的名称引用复杂或深层次的文件路径,提高了项目结构的清晰度和开发效率。
尽管 Node.js 的 URL 类提供了广泛的 URL 处理功能,但它与 Web API 中的 URL 对象存在一些本质区别。
Node.js 的 URL 类主要用于服务器端编程和脚本任务,它的实现更加偏向于文件系统和模块加载的处理。
而 Web API 中的 URL 对象则更加面向浏览器环境,提供了对当前页面 URL 的访问和修改,以及处理跨域资源共享(CORS)等网络相关的特性。
因此,开发者在使用这两种 URL 类时,需要根据具体的应用场景和需求选择合适的工具来操作和管理 URL。
【Vinca】 欢迎 点赞、关注、收藏,您的支持将是我分享更多资源的动力哦~
🌸