Currently, Parcel uses a limited shim of the node fs module to provide the ability to read in file contents at build time. This is prone to errors (conflicts with actual fs for isomorphic modules, confusion for people new to Parcel, etc) and also conceptually clunky.
I would propose that this gets replaced with an export from the parcel-bundler module instead. This would more explicitly be documented as a "magic" value that only exists at build time, with a default static export of the same name from parcel-bundler that can easily be error-checked for isomorphic modules.
fsfs module provided by Electron.path.resolveAn example of the new method in use at build time (names subject to change):
import { dirname, inlineFileContents } from 'parcel-bundler';
const jsonContents = inlineFileContents(dirname, 'subdirectory', 'jsonfile.json');
An example of attempting to use the method outside of build time:
import { dirname, inlineFileContents } from 'parcel-bundler';
dirname; // null
inlineFileContents; // null
inlineFileContents(dirname, 'subdirectory', 'jsonfile.json'); // 'is not a function' exception
An example of an isomorphic module:
import fs from 'fs';
import { dirname, inlineFileContents } from 'parcel-bundler';
if (fs) {
  // Running in Node context
} else if (inlineFileContents) {
  // Running in Parcel build context
} else {
  // Running in the browser
}
Commented here with some potential solutions: https://github.com/parcel-bundler/parcel/issues/1244#issuecomment-402370984. We allow disabling fs inlining, but it's pretty common across different tools - both webpack and browserify have plugins for it.
I don't think we want to introduce something like the above API because it is Parcel specific. We don't want users to have Parcel specific things in their code so that it is interoperable with other tools.
I don't think we want to introduce something like the above API because it is Parcel specific. We don't want users to have Parcel specific things in their code so that it is interoperable with other tools.
The basic problem here, though, is that the current behavior is Parcel specific. I can't write readFileSync calls the same way as actually using real fs because path doesn't exist, for example, and I can't write code the same way when compiling for a Node or Electron target as when compiling for a web target, even when I absolutely want to (like inlining resource files into the source at build time, but keeping that distinct from runtime fs usage).
If the concern is about being generic, it still feels like a better solution would be to define an API interface for a nonexistent package (e.g. import bundlerUtils from 'compile-time-bundler-utils';, where compile-time-bundler-utils is actually an empty package that exports nothing) and leave that open for other bundlers/compilers to use, rather than pretending that there isn't anything special going on.
@icopp for node and electron you can use 鈥攖arget node or 鈥攖arget electron and Devon already explained how to disable fs for browser. Im pretty sure every bundler does this though (with config probably)
Sent with GitHawk
for node and electron you can use 鈥攖arget node or 鈥攖arget electron and Devon already explained how to disable fs for browser.
That just reinforces my point, though: how you have to write the code depends on which flag you're passing to Parcel, which means the code you have is already Parcel-specific. It also doesn't help with the case of intentionally wanting to inline some files at build time while reading others at runtime, which could itself be done in an isomorphic way (e.g. check for both fs and fetch and do different things depending on the run environment).
It's not really parcel specific at all. We're shimming the node API so it works everywhere.
It's not really parcel specific at all. We're shimming the node API so it works everywhere.
I've already mentioned the problems with this:
path and anything else that could plausibly interact with fs. Anything short of that and you're still writing for Parcel-specific behavior.fs, I can't both do that and inline resources at build time. This isn't a problem for targeting the web, but can be hugely annoying if using -t node for something meant to be used as a library in a web build.For a simple example of the latter, a project I'm currently working on uses a secondary repo that provides an Icon component. I can't actually inline the icons themselves (svgs) at build time for the secondary repo without using a parcel plugin, which then raises more issues (for example, I can't have an Icon with inlined svgs and a Wallpaper with imported svgs)
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs.
Most helpful comment
I've already mentioned the problems with this:
pathand anything else that could plausibly interact withfs. Anything short of that and you're still writing for Parcel-specific behavior.fs, I can't both do that and inline resources at build time. This isn't a problem for targeting the web, but can be hugely annoying if using-t nodefor something meant to be used as a library in a web build.For a simple example of the latter, a project I'm currently working on uses a secondary repo that provides an
Iconcomponent. I can't actually inline the icons themselves (svgs) at build time for the secondary repo without using a parcel plugin, which then raises more issues (for example, I can't have anIconwith inlined svgs and aWallpaperwith imported svgs)