Node 模拟
Parcel 包含几个模拟 Node.js API 的功能。这允许许多最初为 Node 编写的 npm 模块也能在浏览器中工作。此外,许多浏览器模块也采用了基于 Node.js 的 API,用于环境变量等内容。
环境变量
#Parcel 支持在 JavaScript 中内联环境变量。这可用于确定构建环境(例如开发、预发布、生产)、注入 API 密钥等。
要访问环境变量,请从 process.env 对象读取相应的属性。
if (process.env.NODE_ENV === "development") {
console.log("Happy developing!");
}
您还可以使用解构语法一次访问多个属性。
let { NODE_ENV, API_TOKEN } = process.env;
不支持以任何非静态方式访问 process.env(例如动态属性查找)。
NODE_ENV
#NODE_ENV 环境变量由 Parcel 根据模式自动设置。运行 parcel build 时,默认将 NODE_ENV 设置为 production,否则设置为 development。这可以通过自己设置 NODE_ENV(例如在 shell 中)来覆盖。
.env 文件
#Parcel 支持加载在项目根目录中的 .env 文件中定义的环境变量。这支持以换行符分隔的 NAME=value 对。以 # 开头的行被视为注释。有关更多详细信息,请参见 dotenv。
APP_NAME=test
API_KEY=12345
除了 .env,还可以创建特定于环境的覆盖,如 .env.production 和 .env.development。这些根据 NODE_ENV 环境变量应用(包括由 Parcel 自动设置的情况)。在特定于环境的覆盖中未设置的任何变量都会回退到基本 .env 文件中定义的值。
还支持 .env.local 文件用于本地覆盖环境变量,但在 NODE_ENV=test 时不使用,以确保测试对每个人都产生相同的结果。对于特定于环境的覆盖,如 .env.production.local,也支持这一点。
内置 Node 模块的填充和排除
#当针对浏览器并且您的代码(或更可能是依赖项)导入内置 Node 模块(如 crypto、fs 或 process)时,Parcel 将自动使用以下填充之一。如果没有可用的填充,则将使用空模块。您还可以使用别名来覆盖这些。
| 原生模块 | npm 替换 | 原生模块 | npm 替换 |
|---|---|---|---|
| assert | assert |
process | process/browser.js |
| buffer | buffer |
punycode | punycode |
| console | console-browserify |
querystring | querystring-es3 |
| constants | constants-browserify |
stream | stream-browserify |
| crypto | crypto-browserify |
string_decoder | string_decoder |
| domain | domain-browser |
sys | util/util.js |
| events | events |
timers | timers-browserify |
| http | stream-http |
tty | tty-browserify |
| https | https-browserify |
url | url |
| os | os-browserify/browser.js |
util | util/util.js |
| path | path-browserify |
vm | vm-browserify |
| zlib | browserify-zlib |
填充内置 Node 全局变量
#针对浏览器时,Node 中可用的全局变量的使用将被替换,以不破坏为 Node 编写的代码:
-
除非是
process.browser或process.env.FOO表达式(将被替换为布尔值或环境变量的值),否则process将自动从process模块导入。 -
Buffer将自动从buffer模块导入。 -
__filename和dirname将被替换为相对于项目根目录的资源文件路径(或父文件夹)的字符串文字。 -
global将被替换为全局变量的引用(类似于较新的globalThis)。
内联 fs.readFileSync
#如果文件路径是静态可确定的并且位于项目根目录内,则 fs.readFileSync 调用将被文件的内容替换。
fs.readFileSync(__dirname + "/file", "utf8")– 文件内容作为字符串。支持 "utf8"、"utf-8"、"hex" 和 "base64" 编码。fs.readFileSync(__dirname + "/file")– 一个 Buffer 对象。请注意,Buffer 填充相当大,因此可能不受欢迎。
可以在文件名参数中使用 __dirname 和 __filename 变量。可以使用 + 运算符和 path.join 函数进行字符串连接。不支持其他函数、变量或动态计算。计算的路径应始终是绝对的,并且不依赖于当前工作目录。
import fs from "fs";
import path from "path";
const data = fs.readFileSync(path.join(__dirname, "data.json"), "utf8");
console.log(data);
{
"foo": "bar"
}
禁用这些功能
#通过在 package.json 中创建 @parcel/transformer-js 键,可以禁用环境变量和 readFileSync 调用的内联。
{
"name": "my-project",
"dependencies": {
...
},
"@parcel/transformer-js": {
"inlineFS": false,
"inlineEnvironment": false
}
}
inlineEnvironment 也可以是一个 glob 字符串数组,允许您过滤允许的环境变量。这是确保安全的好主意,因为 node_modules 中的第三方代码也可以读取环境变量。
{
"name": "my-project",
"dependencies": {
...
},
"@parcel/transformer-js": {
"inlineEnvironment": ["SENTRY_*"]
}
}