parcel-reporter-static-files-copy icon indicating copy to clipboard operation
parcel-reporter-static-files-copy copied to clipboard

trying to copy from wrong directory

Open hayesmaker opened this issue 4 years ago • 6 comments

I'm running my parcel build in a directory named "hype" but it's looking for the static folder 2 folders up from where I need it to.. resulting in the error in the log here:

➜  hype git:(main) ✗ npm run clean && npm run build

> [email protected] clean
> rimraf dist


> [email protected] build
> parcel build

✨ Built in 1.98s

dist/index.html               549 B    16ms
dist/index.16d576fc.js     511.7 KB    14ms
dist/index.b29bc0d1.js    511.34 KB    17ms
Error: ENOENT: no such file or directory, scandir '/home/hayesmaker64/Workspace/chilli-os/static'
    at Object.readdirSync (fs.js:1043:3)
    at recurse (/home/hayesmaker64/Workspace/chilli-os/packages/hype/node_modules/parcel-reporter-static-files-copy/index.js:68:8)
    at recurseSync (/home/hayesmaker64/Workspace/chilli-os/packages/hype/node_modules/parcel-reporter-static-files-copy/index.js:82:3)
    at copyDir (/home/hayesmaker64/Workspace/chilli-os/packages/hype/node_modules/parcel-reporter-static-files-copy/index.js:53:3)
    at Object.report (/home/hayesmaker64/Workspace/chilli-os/packages/hype/node_modules/parcel-reporter-static-files-copy/index.js:33:9)
    at ReporterRunner.report (/home/hayesmaker64/Workspace/chilli-os/packages/hype/node_modules/@parcel/core/lib/ReporterRunner.js:105:33)
    at async Parcel._build (/home/hayesmaker64/Workspace/chilli-os/packages/hype/node_modules/@parcel/core/lib/Parcel.js:446:7)
    at async Parcel.run (/home/hayesmaker64/Workspace/chilli-os/packages/hype/node_modules/@parcel/core/lib/Parcel.js:275:18)
    at async run (/home/hayesmaker64/Workspace/chilli-os/packages/hype/node_modules/parcel/lib/cli.js:374:7) {
  errno: -2,
  syscall: 'scandir',
  code: 'ENOENT',
  path: '/home/hayesmaker64/Workspace/chilli-os/static'
}
➜  hype git:(main) ✗ 
➜  hype git:(main) ✗ pwd
/home/hayesmaker64/Workspace/chilli-os/packages/hype
➜  hype git:(main) ✗ 

this is my config:

.parcelrc

{
  "extends": ["@parcel/config-default"],
  "reporters":  ["...", "parcel-reporter-static-files-copy"]
}

package.json

  "staticFiles": {
    "staticPath": "./static",
    "staticOutPath": "./assets"
  },

I don't think I need the staticPath in package.json because it should look in static by default - but I get the same error either way.

hayesmaker avatar Nov 03 '21 19:11 hayesmaker

Hello, I'm guessing that something (pixi-parcel-rollup?) is messing up with working directory for ParcelJS there and that's why it is searching for static folder two folders above (in chilli-os instead of chilli-os/packages/hype).

Can you prepare some minimal project that replicates this issue?

elwin013 avatar Nov 04 '21 08:11 elwin013

sure... I don't know why, but I just noticed the .parcel-cache also gets created in chilli-os.. does it recursively search for a package-json up directories? There's a package.json in the folder I'm trying to build in (hype), so I don't know what's making it decide to put the parcel-cache in chilli-os.

To recreate the issue you could use yeoman together with my yeoman generator to create a default parcel project (similar to create-react-app): https://www.npmjs.com/package/generator-rizzla

to install and prepare the project, create a folder called project-a or any other name, then cd into it, then run:

npm i -g yo generator-rizzla && yo rizzla

npm run build (will create dist and .parcel-cache etc)

npm start to check project runs. (if you received the static copy error I saw you'll only see text with no images).

It seems like the problem only occurs if project-a is created inside a folder that has a package.json in another folder somewhere higher in the directory tree.. (if not it works fine).

but i'd expect that .parcel-cache should always create itself in the proper working directory and not check any folders higher than where the build is run.

To clean up the global npm installs from above do: npm uninstall -g yo generator-rizzla

then remove the folder with the project that was just created.

hayesmaker avatar Nov 07 '21 20:11 hayesmaker

Maybe related to https://github.com/parcel-bundler/parcel/issues/7075 ? Sorry for not following the issue in detail but I experienced similar situation with npm workspace.

📁 my_project
    📁 my_front_project
        📄 package.json
    📁 my_backend_project
        📄 package.json
    📄 package.json // npm workspace (with "workspaces" key)
{
  "name": "my_project",
  "workspaces": ["my_front_project", "my_backend_project"],
  "scripts": {  "npm run build --workspaces"  }
}

With workspace configuration, options.projectRoot looks like pointing to the workspace root directory (my_project), causing missing staticFiles key since there's no such key in the root package.json.

https://github.com/elwin013/parcel-reporter-static-files-copy/blob/0adfda07b040619d38d6b705b4019326245433b8/index.js#L11

https://github.com/elwin013/parcel-reporter-static-files-copy/blob/0adfda07b040619d38d6b705b4019326245433b8/index.js#L85-L90

Since the key is missing it defaults to static and result source path becomes my_project/static.

https://github.com/elwin013/parcel-reporter-static-files-copy/blob/0adfda07b040619d38d6b705b4019326245433b8/index.js#L29-L30

sftblw avatar Dec 15 '21 08:12 sftblw

I just ran into this problem trying to use this library. After smashing my head against the keyboard for an hour and digging through the source and parcel, I finally discovered that if there's a package.json file in a higher directory (in my case, it was in my home directory and my code was in ~/projects/project-name, parcel itself would set projectRoot to that higher directory.

Deleting the package.json file in my home directory -- it was there by accident -- solved the problem for me.

mrkrstphr avatar Dec 24 '21 01:12 mrkrstphr

@mrkrstphr this was also the issue for me. Thanks for that. I had an errant package-lock.json in a parent of my parcel project and it messed everything up

kristojorg avatar Feb 17 '22 15:02 kristojorg

This is what I did to fix the issue:

diff --git a/node_modules/parcel-reporter-static-files-copy/index.js b/node_modules/parcel-reporter-static-files-copy/index.js
index bf9a7f4..2025def 100644
--- a/node_modules/parcel-reporter-static-files-copy/index.js
+++ b/node_modules/parcel-reporter-static-files-copy/index.js
@@ -8,7 +8,7 @@ const PACKAGE_JSON_SECTION = "staticFiles";
 const staticCopyPlugin = new Reporter({
   async report({ event, options }) {
     if (event.type === "buildSuccess") {
-      let config = Object.assign({}, getSettings(options.projectRoot));
+      let config = Object.assign({}, getSettings(event, options));
 
       // Get all dist dir from targets, we'll copy static files into them
       let targets = Array.from(
@@ -26,8 +26,7 @@ const staticCopyPlugin = new Reporter({
         distPaths = distPaths.map((p) => path.join(p, config.staticOutPath));
       }
 
-      let staticPath =
-        config.staticPath || path.join(options.projectRoot, "static");
+      let staticPath = config.staticPath;
 
       let fn = fs.statSync(staticPath).isDirectory() ? copyDir : copyFile;
       
@@ -88,11 +87,33 @@ const recurseSync = (dirpath, callback) => {
   recurse(dirpath);
 };
 
-const getSettings = (projectRoot) => {
+const getSettings = (event, options) => {
+  const projectRoot = (() => {
+    try {
+      const bundle = event.bundleGraph.getBundles()[0];
+      let currentPath = event.bundleGraph.getEntryRoot(bundle.target);
+      while (true) {
+        const packageJsonPath = path.join(currentPath, "package.json");
+        if (fs.existsSync(packageJsonPath)) {
+          return currentPath;
+        }
+        const nextProjectRoot = path.normalize(path.join(currentPath, ".."));
+        if(nextProjectRoot === currentPath) {
+          return null;
+        }
+        currentPath = nextProjectRoot;
+      }
+    }
+    catch {
+      return null;
+    }
+  })() ?? options.projectRoot;
   let packageJson = JSON.parse(
     fs.readFileSync(path.join(projectRoot, "package.json"))
   );
-  return Object.assign({}, packageJson[PACKAGE_JSON_SECTION]);
+  return Object.assign({
+    staticPath: path.join(projectRoot, "static"),
+  }, packageJson[PACKAGE_JSON_SECTION]);
 };
 
 exports.default = staticCopyPlugin;

kkirby avatar Oct 26 '22 14:10 kkirby

So the solution is still to fix the library yourself? I can't remove the package.json from my higher up directory since I'm trying to create a parcel project in an npm workspace.

hayesmaker avatar Jun 20 '23 07:06 hayesmaker

Looks like with the Parcel 2.9.2 everything working correctly now - please look at master where I've wrapped examples into the workspace. Running npm run build in example or running npm run build --ws in workspace directory works as it should.

elwin013 avatar Jun 21 '23 05:06 elwin013

Still not working for me:

// from package.json devDeps:

"parcel": "^2.9.2",
"parcel-reporter-static-files-copy": "^1.5.0",

it's looking for a "static" folder in root directoy

~/Workspace/chilli-os/packages/slots (main)
$ npm run build

> @chilli-os/[email protected] build
> parcel build --public-url /slots-overlay

√ Built in 6.51s

dist\index.html                         689 B    468ms
dist\index.fbc47ae2.css                 152 B    131ms
dist\04b30-webfont.10e27565.woff2     4.04 KB     95ms
dist\index.cfd4b34f.js               713.3 KB    1.32s
dist\index.4114130a.js               713.5 KB    1.32s
Error: ENOENT: no such file or directory, stat 'C:\Users\andyg\Workspace\chilli-os\static'
    at Object.statSync (node:fs:1596:3)
    at Object.report (C:\Users\andyg\Workspace\chilli-os\node_modules\parcel-reporter-static-files-copy\index.js:38:21)
    at ReporterRunner.report (C:\Users\andyg\Workspace\chilli-os\node_modules\@parcel\core\lib\ReporterRunner.js:98:33)
    at async Parcel._build (C:\Users\andyg\Workspace\chilli-os\node_modules\@parcel\core\lib\Parcel.js:346:7)
    at async Parcel.run (C:\Users\andyg\Workspace\chilli-os\node_modules\@parcel\core\lib\Parcel.js:195:18)
    at async run (C:\Users\andyg\Workspace\chilli-os\node_modules\parcel\lib\cli.js:308:7) {
  errno: -4058,
  syscall: 'stat',
  code: 'ENOENT',
  path: 'C:\\Users\\andyg\\Workspace\\chilli-os\\static'
}

hayesmaker avatar Jul 21 '23 20:07 hayesmaker

Yay, finally I can reproduce the issue! 🙃

elwin013 avatar Jul 29 '23 21:07 elwin013

It is fixed with 1.5.2 version. Works with npm and pnpm, should work with yarn 2.x and upper.

New version is on npmjs.org - [email protected]

elwin013 avatar Jul 29 '23 21:07 elwin013

Btw. the issue for the Parcel itself still exists (see #7579 at Parcel repo).

Temporary workaround for any plugin is to add lockfile to the subpackage folder - this will force Parcel to treat subpackage directory as a project root.

elwin013 avatar Jul 30 '23 10:07 elwin013

@hayesmaker @elwin013 I still see this in parcel v2.9.3 and pnpm:

  • .proxyrc is read from root of monorepo (and not package root)
    • parcel-cache and parcel-bundle-reports are created in the root of monorepo (and not package root)
  • missing dependencies (wrongly assumed missing) are installed in the root of monorepo (and not package root)

How did you solve?

More context:

  • I run pnpm -F webapp build:dev from monorepo root (which execute build:dev inside webapp directory)
  • I have no yarn.lock anywhere, just:
package.json
packages/
   webapp/
      package.json

damianobarbati avatar Sep 13 '23 15:09 damianobarbati