Node Emulation
Parcel includes several features that emulate the Node.js API. This allows many modules on npm that were originally written for Node to also work in the browser. In addition, many browser modules have also adopted Node.js-based APIs for things like environment variables.
Environment Variables
#Parcel supports inlining environment variables in JavaScript. This can be used to determine the build environment (e.g. development, staging, production), inject API keys, etc.
To access an environment variable, read the corresponding property from the process.env
object.
if (process.env.NODE_ENV === 'development') {
console.log('Happy developing!');
}
You can also use destructuring syntax to access multiple properties at once.
let {NODE_ENV, API_TOKEN} = process.env;
Accessing process.env
in any non-static ways (e.g. dynamic property lookups) is not supported.
NODE_ENV
#The NODE_ENV
environment variable is automatically set by Parcel depending on the mode. When running parcel build
, NODE_ENV
is set to production
by default, otherwise it is set to development
. This can be overridden by setting NODE_ENV
yourself (e.g. in your shell).
.env
files
#Parcel supports loading environment variables defined in .env
files in your project root. This supports NAME=value
pairs separated by newlines. Lines starting with #
are treated as comments. See dotenv for more details.
In addition to .env
, environment-specific overrides such as .env.production
and .env.development
can also be created. These are applied based on the NODE_ENV
environment variable (including when automatically set by Parcel). Any variables that are not set in environment-specific overrides fall back to the values defined in the base .env
file.
The .env.local
file is also supported for local overrides of environment variables, however, it is not used when NODE_ENV=test
so that tests produce the same result for everyone. This is also supported for environment-specific overrides, such as .env.production.local
.
Polyfilling & Excluding Builtin Node Modules
#When targetting the browser and your code, or more likely a dependency, imports builtin Node modules such as crypto
, fs
or process
, Parcel will automatically use one of the following polyfills. If no polyfill is available, then an empty module will be used instead. You can also use aliases to override these.
native module | npm replacement | native module | npm replacement |
---|---|---|---|
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 |
Shimming Builtin Node Globals
#When targetting the browser, usages of global variables that are available in Node are replaced to not break code written for Node:
-
process
is imported automatically from theprocess
module, unless it's part of aprocess.browser
orprocess.env.FOO
expression which is replaced by a boolean or the value of the environment variable. -
Buffer
is imported automatically from thebuffer
module. -
__filename
anddirname
are replaced by string literals of the asset's filepath (or the parent folder) relative to the project root. -
global
is replaced with a reference to the global variable (behaving like the newerglobalThis
).
Inlining fs.readFileSync
#Calls to fs.readFileSync
are replaced with the file's contents if the filepath is statically determinable and inside the project root.
fs.readFileSync(__dirname + "/file", "utf8")
– the contents of the file as a string. The "utf8", "utf-8", "hex", and "base64" encodings are supported.fs.readFileSync(__dirname + "/file")
– a Buffer object. Note that the Buffer polyfill is quite large so this may be undesired.
The __dirname
and __filename
variables can be used in the filename argument. String concatenation via the +
operator and the path.join
function may be used. Other functions, variables, or dynamic computations are not supported. Computed paths should always be absolute, and not rely on the current working directory.
Disabling These Features
#Inlining of environment variables and readFileSync
calls can be disabled by creating a @parcel/transformer-js
key in package.json
.
inlineEnvironment
can also be an array of glob strings, which allows you to filter the allowed environment variables. This is a good idea to ensure security, since third party code in node_modules can also read environment variables.
{
"name": "my-project",
"dependencies": {
...
},
"@parcel/transformer-js": {
"inlineEnvironment": ["SENTRY_*"]
}
}