Releases: cloudflare/miniflare
v2.6.0
Features
- 🪣 Add support for R2 bucket bindings. Closes issue #276, thank you so much @CraigglesO for the massive PR.
- Add support for
navigator.userAgent
. Closes issue #209, thanks @Electroid. - Return fixed time from
new Date()
/Date.now()
, unless the--actual-time
/actualTime: true
option is set, to match the behaviour the Workers runtime. Closes issue #225, thanks @ItalyPaleAle. - Add support for
(De)CompressionStream
. Closes issue #206, thanks @Electroid. - Add an interactive REPL via the
--repl
flag. Any other flag can be passed too, and options will automatically be loaded fromwrangler.toml
files. Specifying a script is optional when--repl
is enabled. The REPL can also be started programmatically via theMiniflare#startREPL()
method. See for more details. Thanks @threepointone for the idea over at cloudflare/wrangler2#1263.
Fixes
- Load service bindings from
services
instead ofexperimental_services
, and usebinding
instead ofname
for the binding name. Thanks @jrencz for the PR. issue #280. - Log warning instead of error when fetching
Request#cf
object fails. Closes issue #224, thanks @threepointone. - Increase the subrequest limit for
unbound
workers from 50 to 1000, and limit the number of calls to internal APIs such as KV/Durable Object to 1000. Closes issue #274, thanks @isaac-mcfadyen. - Fix logging of accessible hosts in Node.js 18
- Remove
name
fromDurableObjectId
s inDurableObjectState
to match the behaviour of the Workers runtime. Closes issue #219. - Allow failure WebSocket upgrade responses. Closes issue #174, thanks @jinjor.
- Correctly handle internationalised domain names in routes. Closes issue #186, thanks @dsod.
- Improve the error message when Durable Object bindings are missing a script to mention mounting. Closes issue #221, thanks @konsumer.
- Allow WebSockets to be closed without a status code. Closes issue #284, thanks @hansottowirtz.
- Allow Durable Object alarms to be scheduled less than 30 seconds in the future. Closes issue #290, thanks @wighawag and @CraigglesO for the PR.
- Fix
DurableObjectStorage#list()
when alarms are scheduled. Closes issue #297, thanks @evanderkoogh and @CraigglesO for the PR.
v2.5.1
⚠️ Security Update
- Upgrade
undici
to5.5.1
, addressing GHSA-pgw7-wx7w-2w33 - Upgrade
node-forge
to1.3.1
, addressing GHSA-2r2c-g63r-vccr, GHSA-x4jg-mjrx-434g and GHSA-cfm4-qjh2-4765 - Upgrade
minimist
to1.2.6
, addressing GHSA-xvch-5gv4-984h
v2.5.0
Features
- ⏰ Add support for Durable Object alarms. Thanks @CraigglesO for the PR.
- Add support for
URLPattern
. Closes issue #199, thanks @Electroid and @tom-sherman for the PR. - Add support for the
Response.json()
static method. Closes issue #272, thanks @Cherry. - Add support for the
startAfter
Durable Objectlist()
option. Closes issue #266, thanks @vlovich. - Add support for Jest 28 and custom export conditions. By default, the Miniflare Jest environment will use the
worker
condition, followed bybrowser
. Closes issues #249 and #255, thanks @awwong1 and @SupremeTechnopriest.
Fixes
- Fixed issue where
403 Forbidden
responses were returned when a site behind Cloudflare was set as the upstream. Closes issue #237, thanks @james-maher for the PR. - Respect
env_path
option inwrangler.toml
when using mounts or the Miniflare Jest environment. Closes issue #240, thanks @bkniffler. - Fix cases where BYOB readers didn't notice the end of the stream. Closes issue #192, thanks @vlovich for the PR.
- Wait for unawaited writes within a Durable Object transaction before attempting to commit. Closes issue #250, thanks @vlovich.
- Correctly bind
this
incrypto
andcrypto.subtle
. Closes issue #256, thanks @lmcarreiro and @awwong1 for the PR. - Bump
busboy
to resolve a security issue. Closes issue #267, thanks @grempe and @Cherry for the PR. - Set incoming
Accept-Encoding
headers togzip
and put actual client encodings inrequest.cf.clientAcceptEncoding
to match the behaviour of the Workers runtime. Closes issue #180, thanks @evanderkoogh and @leader22 for the PR. - Remove restriction on supported
TextDecoder
encodings. Closes issue #212. - Make
headers
on returnedfetch
Response
s immutable. Closes issue #242, thanks @nickreese. - Use lexicographic ordering for KV/Durable Object
list()
s. Closes issue #235, thanks @vlovich. - Re-export
Request
,RequestInfo
,RequestInit
andResponse
fromminiflare
. Closes issue #258, thanks @ajwootto. - Add
jest-environment-miniflare
's missingdependencies
. Thanks @BasixKOR for the PR.
v2.4.0
Features
- Add support for
[text_blobs]
. Closes issue #211, thanks @caass for the PR. - Add support for
[data_blobs]
. Closes issue #231, thanks @threepointone for the PR. - Do not display the pretty error page when making requests with
curl
. Closes issue #198, thanks @GregBrimble for the PR.
Fixes
- Pass correctly-typed value to
webcrypto.getRandomValues()
. Closes issue #188, thanks @vlovich. - Fix
fetch
withContent-Length: 0
header. Closes issue #193, thanks @orls for the PR. - Bind
this
towebcrypto
methods, fixingcrypto.getRandomValues()
andcrypto.subtle.generateKey()
. Thanks @szkl for the PR.
v2.3.0
Features
- Route
/cdn-cgi/mf/scheduled
requests based on mount routes. Closes issue #163, thanks @jed. - Add clear error if a Durable Object class is missing a
fetch
handler. Closes issue #164, thanks @aboodman. - Upgrade
undici
to4.13.0
Fixes
- Fix
instanceof
when subclassingError
. Subclasses ofError
were previously treated asError
s themselves ininstanceof
checks. Closes issue #159, thanks @valeriangalliat. - Return
null
bodies whenfetch
ingResponse
s with a null status. Closes issue #165, thanks @lukaszczerpak for reporting this and @GregBrimble for the PR. - Clone
ArrayBuffer
bodies when constructingRequest
/Response
s. Closes issue #171, thanks @segator and @leader22. - Watch
index.js
by default intype = "webpack"
projects - Throw
TypeError
s instead ofstring
s onHTMLRewriter
parser errors - Disable nested mounts via
Miniflare#getMount().setOptions()
v2.2.0
Features
- Add support for the
HTMLRewriter
Element#onEndTag(handler)
method - Add support for the
html_rewriter_treats_esi_include_as_void_tag
compatibility flag - Make the error message when attempting to import Node.js built-in modules more helpful
Fixes
- Fix
instanceof
checks withnull
values. Closes issues #152 and #154. Thanks @Cerberus for the PR, and @bduff9, @huw & @g45t345rt for reporting this. - Fix subdirectory watching on Linux. Closes issue #153, thanks @huw for reporting this.
- Throw a
TypeError
instead of astring
when the parameter passed to aHTMLRewriter
handler is used outside the handler
v2.1.0
Features
-
Allow multiple build watch paths to be set in
wrangler.toml
files. Use the[miniflare] build_watch_dirs
option. Note this gets merged with the regular[build] watch_dir
option:[build] watch_dir = "src1" [miniflare] build_watch_dirs = ["src2", "src3"]
-
WebSocket handshake headers are now included in responses from the HTTP server and WebSocket upgrade
fetch
es. Closes issue #151, thanks @jed.
Fixes
- Allow Miniflare to be installed with Yarn PnP. Closes issue #144, thanks @lookfirst, @merceyz, and @DJtheRedstoner.
- Use the actual body length for the
Content-Length
header in HTTP server responses, instead of the value provided in theResponse
constructor. Closes issue #148, thanks @lukaszczerpak. - Don't rewrite the
Host
header to match the upstream URL. Closes issue #149, thanks @hansede. - Bump dependencies, fixing
npm audit
warnings. Thanks @leader22 for the PR. - Make
instanceof
spec-compliant, ensuring checks likeObject instanceof Object
succeed. This particular check was used by Lodash's_.isPlainObject()
method, which is internally called by_.merge()
, causing unexpected results. - Make the unimplemented
Response#type
property non-enumerable - Copy header guard when
clone()
ingRequest
s, ensuringRequest
s with immutable headers still have immutable headers whenclone()
ed - Fix race conditions in file-system watcher
v2.0.0
Miniflare 2 has been completely redesigned from version 1 with 3 primary design goals:
- 📚 Modular: Miniflare 2 splits Workers components (KV, Durable Objects, etc.) into separate packages (
@miniflare/kv
,@miniflare/durable-objects
, etc.) that you can import separately for testing. - ✨ Lightweight: Miniflare 1 included 122 third-party packages with a total install size of
88MB
. Miniflare 2 reduces this to 24 packages and6MB
by leveraging features included with Node.js 16. - ✅ Accurate: Miniflare 2 more accurately replicates the quirks and thrown errors of the real Workers runtime, so you'll know before you deploy if things are going to break.
Check out the migration guide if you're upgrading from version 1.
Notable Changes
- ✳️ Node.js 16.7.0 is now the minimum required version
- 🤹 Added a custom Jest test environment, allowing you to run unit tests in the Miniflare sandbox, with isolated storage for each test
- 🔌 Added support for running multiple workers in the same Miniflare instance
- ⚡️ Added a live reload feature (
--live-reload
) that automatically refreshes your browser when your worker reloads - 🚪 Added Durable Object input and output gates, and write coalescing
- 🛑 Added the
DurableObjectState#blockConcurrencyWhile(callback)
method - 📅 Added support for compatibility dates and flags:
durable_object_fetch_requires_full_url
,fetch_refuses_unknown_protocols
,formdata_parser_supports_files
- 📚 Added a proper CommonJS module loader
- 🗺 Automatically fetch the incoming
Request#cf
object from a trusted Cloudflare endpoint - 🎲 Added support for
crypto.randomUUID()
- 🔐 Added support for the
NODE-ED25519
algorithm - ✉️ Added support for sending/receiving binary WebSocket messages
Breaking Changes
-
Node.js 16.7.0 is now the minimum required version. You should use the latest Node.js version if possible, as Cloudflare Workers use a very up-to-date version of V8. Consider using a Node.js version manager such as https://volta.sh/ or https://github.com/nvm-sh/nvm.
-
Changed the storage format for Durable Objects and cached responses. If you're using file-system or Redis storage, you'll need to delete these directories/namespaces.
-
Changed the Durable Object ID format to include a hash of the object name. Durable Object IDs generated in Miniflare 1 cannot be used with Miniflare 2.
-
Correctly implement the Durable Object
script_name
option. In Miniflare 1, this incorrectly expected a script path instead of a script name. This now relies on mounting the other worker. See 📌 Durable Objects for more details. -
Removed the non-standard
DurableObjectStub#storage()
method. To access Durable Object storage outside a worker, use the newMiniflare#getDurableObjectStorage(id)
method, passing aDurableObjectId
obtained from a stub. See 📌 Durable Objects for more details. -
Renamed the
--disable-cache
/disableCache: true
option to--no-cache
/cache: false
-
Renamed the
--disable-updater
option to--no-update-check
-
When using the API,
wrangler.toml
,package.json
and.env
are no longer automatically loaded from their default locations. To re-enable this behaviour, set these options totrue
:const mf = new Miniflare({ wranglerConfigPath: true, packagePath: true, envPath: true, });
-
Replaced the
ConsoleLog
class with theLog
class from@miniflare/shared
. You can construct this with aLogLevel
to control how much information is logged to the console:import { Miniflare, Log, LogLevel } from "miniflare"; const mf = new Miniflare({ log: new Log(LogLevel.DEBUG), });
-
Load WASM bindings from the standard
wasm_modules
wrangler.toml
key instead ofminiflare.wasm_bindings
.[miniflare] wasm_bindings = [ { name = "MODULE1", path="module1.wasm" }, { name = "MODULE2", path="module2.wasm" } ]
...should now be...
[wasm_modules] MODULE1 = "module1.wasm" MODULE2 = "module2.wasm"
-
Renamed the
buildWatchPath
option tobuildWatchPaths
. This is now an array of string paths to watch as opposed to a single string. -
Replaced the
Miniflare#reloadOptions()
method with theMiniflare#reload()
andMiniflare#setOptions({ ... })
methods.reload()
will reload options fromwrangler.toml
(useful if not watching), andsetOptions()
accepts the same options object as thenew Miniflare
constructor, applies those options, then reloads the worker. -
Replaced the
Miniflare#getCache()
method theMiniflare#getCaches()
method. This returns the globalcaches
object. See ✨ Cache . -
Miniflare#createServer()
now always returns aPromise
which you must await to get ahttp.Server
/https.Server
instance. You may want to check out the newMiniflare#startServer()
method which automatically starts a server using the configuredhost
andport
. -
Redis support is no longer included by default. If you're persisting KV, Durable Objects or cached responses in Redis, you must install the
@miniflare/storage-redis
optional peer dependency. -
Replaced how Miniflare sanitises file paths for file-system storage so namespace separators (
/
,\
,:
and|
) now create new directories. -
The result of
Miniflare#dispatchScheduled
will no longer includeundefined
if a module scheduled handler doesn't return a value
Features and Fixes
Cache:
- Added support for
cf.cacheKey
,cf.cacheTtl
andcf.cacheTtlByStatus
onRequest
. Closes issue #37, thanks @cdloh. - Added the
CF-Cache-Status: HIT
header to matchedResponse
s - Log warning when trying to use cache with
workers_dev = true
inwrangler.toml
. Cache operations are a no-op onworkers.dev
subdomains. - Throw errors when trying to cache Web Socket, non-
GET
,206 Partial Content
, orVary: *
responses - Throw an error when trying to
open
a cache with a name longer than1024
characters
CLI:
- Separated command line options into sections
- Validate types of all command line options
Core:
-
Added support for running multiple workers in the same Miniflare instance. See 🔌 Multiple Workers for more details.
-
Added support for compatibility dates and flags, specifically the flags
durable_object_fetch_requires_full_url
,fetch_refuses_unknown_protocols
,formdata_parser_supports_files
are now supported. This feature is exposed under the--compat-date
and--compat-flag
CLI options, in addition to the standard keys inwrangler.toml
. Closes issue #48, thanks @PaganMuffin. See 📅 Compatibility Dates for more details. -
Added a proper CommonJS module loader. Workers built with Webpack will be more likely to work with Miniflare now. Closes issue #44, thanks @TimTinkers.
-
Don't crash on unhandled promise rejections when using the CLI. Instead, log them. Closes issue #115, thanks @togglydev.
-
Limit the number of subrequests to 50, as per the Workers runtime. Closes issue #117, thanks @leader22 for the suggestion.
-
To match the behaviour of the Workers runtime, some functionality, such as asynchronous I/O (
fetch
, Cache API, KV), timeouts (setTimeout
,setInterval
), and generating cryptographically-secure random values (crypto.getRandomValues
,crypto.subtle.generateKey
), can now only be performed while handling a request.This behaviour can be disabled by setting the
--global-async-io
/globalAsyncIO
,--global-timers
/globalTimers
and--global-random
/globalRandom
options respectively, which may be useful for tests or libraries that need async I/O for setup during local development. Note the Miniflare Jest environment automatically enables these options.KV namespaces and caches returned from
Miniflare#getKVNamespace()
andgetCaches()
are unaffected by this change, so they can still be used in tests without setting any additional options. -
To match the behaviour of the Workers runtime, Miniflare now enforces recursion depth limits. Durable Object
fetch
es can recurse up to 16 times, and service bindings can recurse up to 32 times. This means if a Durable Object fetch triggers another Durable Object fetch, and so on 16 times, an error will be thrown. -
Incoming request headers are now immutable. Closes issue #36, thanks @grahamlyons.
-
Disabled dynamic WebAssembly compilation in the Miniflare sandbox
-
Fixed
instanceof
on primitives such asObject
,Array
,Promise
, etc. from outside the Miniflare sandbox. This makes it much easier to run Rust workers in Miniflare, aswasm-bindgen
frequently generates this code. -
Added a new
--verbose
/verbose: true
option that enables verbose logging with more debugging information -
Throw a more helpful error with suggested fixes when Miniflare can't find your worker's script
-
On...
v2.0.0-rc.5
This update is mostly focused on improving mounts for service bindings. It also matches some other core behaviour of the Workers runtime, like blocking asynchronous I/O outside request handlers, and limiting request recursion depth.
Breaking Changes
NOTE: this change will be reverted in the next release. I've thought of an alternative solution that doesn't need this flag.instanceof
checks on primitives such asObject
,Array
,Promise
, etc. from outside the Miniflare sandbox no longer succeed by default. This was initially added to make it easier to run Rust workers in Miniflare, aswasm-bindgen
frequently generates this code. However, the implementation causedObject
prototype/constructor checks to fail in JavaScript. The previous behaviour can be restored with the--proxy-primitive
/miniflare.proxy_primitive_instanceof
/proxyPrimitiveInstanceOf
CLI/wrangler.toml
/API option. This should be enabled when developing Rust workers. See this comment for more details. Closes issues #109, #137, #141 and cloudflare/wrangler2#91. Thanks @EmilianoSanchez, @lukaszczerpak, @SirJosh3917 and @johnhenry.- Mount paths defined in
wrangler.toml
are now resolved relative to the directory containing thewrangler.toml
file - Mount names must match the
name
field inwrangler.toml
if its defined
Features
-
To match the behaviour of the Workers runtime, some functionality, such as asynchronous I/O (
fetch
, Cache API, KV), timeouts (setTimeout
,setInterval
), and generating cryptographically-secure random values (crypto.getRandomValues
,crypto.subtle.generateKey
), can now only be performed while handling a request.-
This behaviour can be disabled by setting the
--global-async-io
/globalAsyncIO
,--global-timers
/globalTimers
and--global-random
/globalRandom
options respectively, which may be useful for tests or libraries that need async I/O for setup during local development. Note the Miniflare Jest environment automatically enables these options. -
KV namespaces and caches returned from
Miniflare#getKVNamespace()
andgetCaches()
are unaffected by this change, so they can still be used in tests without setting any additional options.
-
-
Adds highly experimental support for service bindings. This is primarily meant for internal testing, and users outside the beta can't deploy workers using this feature yet, but feel free to play around with them locally and let us know what you think in the Cloudflare Workers Discord server.
To enable these, mount your service (so Miniflare knows where to find it) then add the binding. Note the bound service name must match the mounted name:
$ miniflare --mount auth=./auth --service AUTH_SERVICE=auth # or -S
# wrangler.toml experimental_services = [ # Note environment is currently ignored { name = "AUTH_SERVICE", service = "auth", environment = "production" } ] [miniflare.mounts] auth = "./auth"
const mf = new Miniflare({ mounts: { auth: "./auth" }, serviceBindings: { AUTH_SERVICE: "auth" }, });
...then to use the service binding:
export default { async fetch(request, env, ctx) { const res = await env.AUTH_SERVICE.fetch("..."); // ... }, };
If
./auth/wrangler.toml
contains its own service bindings, those services must also be mounted in the root worker (i.e. inwrangler.toml
not./auth/wrangler.toml
). Nested mounts are not supported. -
To match the behaviour of the Workers runtime, Miniflare now enforces recursion depth limits. Durable Object
fetch
es can recurse up to 16 times, and service bindings can recurse up to 32 times. This means if a Durable Object fetch triggers another Durable Object fetch, and so on 16 times, an error will be thrown. -
The root worker is now routable using
route
/routes
as with mounts if it has aname
set. This means if it has more specific routes than other mounts, they'll be used instead. The root worker is always used as a fallback if no mounts' routes match. -
Mounted workers can now access Durable Objects defined in other mounts or the root worker (assuming a
name
is set) using thescript_name
option. -
Allow the subrequest limit to be customised using the
MINIFLARE_SUBREQUEST_LIMIT
environment variable. Setting this to a negative number disables the limit. Setting this to 0 disables subrequests. The majority of users should never need to touch this, hence it's configured via an environment variable, not a CLI option. This also makes the implementation much simpler. :slight_smile: Closes issue #132, thanks @DanielAGW.
Fixes
- Allow
env_path
to be set inwrangler.toml
- WebSocket client
fetch
es now contribute to the subrequest limit - Errors raised when reloading (e.g. missing Durable Object classes) in response to mount file changes are now logged, and don't crash
- Fixed issue where deleting
[miniflare.mounts]
inwrangler.toml
wouldn't unmount everything
v2.0.0-rc.4
This update incorporates the 2021-12-10
Workers runtime changes. The Miniflare docs now use the Cloudflare Docs Engine.
Features
- Switched back to CommonJS exports. A primary goal of Miniflare is to provide a fun developer experience. Currently, this is not the case when using Miniflare with a certain popular testing framework (cough,
Jest, cough), because it and its ecosystem's support for ESM isn't great yet. This also makes it easier to upgrade from Miniflare 1. Node lets you import CommonJS modules in ES modules so this won't break existing code. Thanks @Kikobeats. - Added
--open
/-O
option that automatically opens your browser once your worker is running. You can optionally specify a different URL to open with--open https://example.com
. Closes issue #121, thanks @third774 for the suggestion. - Don't crash on unhandled promise rejections when using the CLI. Instead, log them. Closes issue #115, thanks @togglydev.
- Added support for
AbortSignal.timeout()
- Added support for
crypto.DigestStream
- Added support for
scheduler.wait()
- Added support for
FixedLengthStream
. Closes issue #123, thanks @vlovich. - Limit the number of subrequests to 50, as per the Workers runtime. Closes issue #117, thanks @leader22 for the suggestion.
- Raised the Durable Object storage max value size from
32KiB
to128KiB
- Re-export remaining
fetch
types fromundici
in@miniflare/core
. Closes issue #124, thanks @GregBrimble.
Fixes
- Fixed issue where
Math
was missing in sandbox when running Worker for module exports injest-environment-miniflare
. Closes issue #128, thanks @worenga for the PR. - Fixed the script path for
type = "webpack"
Workers Sites projects - Allow
*/*
route in mounted workers kv_persist
,cache_persist
anddurable_objects_persist
options set in mounted workers'wrangler.toml
files are now respected