节点模拟
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
从process
模块自动导入,除非它是process.browser
或process.env.FOO
表达式的一部分,该表达式被布尔值或环境变量的值替换。 -
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_*"]
}
}