0

I have the following code to read a file in my project with Node fs.

 const files: FileSystemTree = {
      "Component.tsx": {
        file: {
          contents: fs.readFileSync(
            `../../apps/components/${name.toLowerCase()}/${name.charAt(0).toUpperCase()}${name.slice(1)}.tsx`
          )
        }
      }
    };

Which is part of the overall class:

import {WebContainer, FileSystemTree} from "@webcontainer/api";
import fs from "fs";

export default class Container {
  private mContainer!: WebContainer;

  constructor() {
    this.CreateContainer();
    this.ScaffoldViteApp();
    this.StartDevServer();
  }

  private CreateContainer = async () => {
    try {
      this.mContainer = await WebContainer.boot();
    } catch (err) {
      throw new Error(JSON.stringify(err));
    }

    return this.mContainer;
  }; 

  private ScaffoldViteApp = async () => {
    try {
      this.mContainer.spawn("npm", [
        "create",
        "vite",
        "container-example -- --template react-swc-ts"
      ]);
    } catch (err) {
      throw new Error(JSON.stringify(err));
    }

    return this.mContainer;
  };

  private StartDevServer = async () => {
    try {
      this.mContainer.spawn("npm", ["run", "dev"]);
    } catch (err) {
      throw new Error(JSON.stringify(err));
    }

    return this.mContainer;
  };

  public SetComponent(name: string) {
    const files: FileSystemTree = {
      "Component.tsx": {
        file: {
          contents: fs.readFileSync(
            `../../apps/components/${name.toLowerCase()}/${name.charAt(0).toUpperCase()}${name.slice(1)}.tsx`
          )
        }
      }
    };

    console.log(fs.readFileSync(
        `../../apps/components/${name.toLowerCase()}/${name.charAt(0).toUpperCase()}${name.slice(1)}`
      ))

    try {
      this.mContainer.fs.mkdir("components");
    } catch (err) {
      throw new Error(JSON.stringify(err));
    }

    try {
      this.mContainer.mount(files, {mountPoint: "components"});
    } catch (err) {
      throw new Error(JSON.stringify(err));
    }

    return this.mContainer;
  }

  public GetIframe() {
    return this.mContainer.on("server-ready", (port, url) => {
      return url;
    });
  }

  public WriteComponent(name: string, content: string) {
    const files: FileSystemTree = {
      "Component.tsx": {
        file: {
          contents: content
        }
      }
    };

    try {
      this.mContainer.mount(files, {mountPoint: "components"});
    } catch (err) {
      throw new Error(JSON.stringify(err));
    }

    return this.mContainer;
  }
}

When I use vitest to run: Container.SetComponent() I get an error:

Error: ENOENT: no such file or directory, open '../../apps/components/example/Example'

However, upon commanding clicking the path it does in fact exist. I have tried the same thing with a .tsx ending to no avail. I have also tried running the file with ts-node and tsx and I get the same results. Here is my project structure:

.
├── README.md
├── apps
│   ├── components
│   │   ├── example
│   │   │   ├── Example.tsx
│   │   │   ├── stories
│   │   │   │   └── Example.stories.tsx
│   │   │   └── tests
│   │   │       └── example.spec.tsx
│   │   └── project.json
│   ├── docs
│   │   ├── README.md
│   │   ├── astro.config.mjs
│   │   ├── node_modules
│   │   │   ├── @astrojs
│   │   │   │   ├── check -> ../../../../node_modules/.pnpm/@[email protected][email protected][email protected]/node_modules/@astrojs/check
│   │   │   │   └── starlight -> ../../../../node_modules/.pnpm/@[email protected][email protected]_@[email protected][email protected][email protected]_/node_modules/@astrojs/starlight
│   │   │   ├── astro -> ../../../node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected]/node_modules/astro
│   │   │   ├── sharp -> ../../../node_modules/.pnpm/[email protected]/node_modules/sharp
│   │   │   └── typescript -> ../../../node_modules/.pnpm/[email protected]/node_modules/typescript
│   │   ├── package.json
│   │   ├── project.json
│   │   ├── public
│   │   │   └── favicon.svg
│   │   └── src
│   │       ├── assets
│   │       │   └── houston.webp
│   │       ├── content
│   │       │   ├── config.ts
│   │       │   └── docs
│   │       │       ├── components
│   │       │       │   └── example.mdx
│   │       │       ├── guides
│   │       │       │   └── example.md
│   │       │       └── index.mdx
│   │       └── env.d.ts
│   └── storybook
│       ├── node_modules
│       ├── package.json
│       ├── project.json
│       ├── tsconfig.json
│       └── tsconfig.storybook.json
├── docs
│   ├── assets
│   │   ├── highlight.css
│   │   ├── icons.js
│   │   ├── icons.svg
│   │   ├── main.js
│   │   ├── navigation.js
│   │   ├── search.js
│   │   └── style.css
│   ├── functions
│   │   └── default.html
│   ├── index.html
│   ├── modules.html
│   └── types
│       └── Props.html
├── eslint.config.js
├── index.css
├── nx.json
├── package.json
├── packages
│   ├── docs-sandbox
│   │   ├── createContainer.ts
│   │   ├── project.json
│   │   └── tests
│   │       └── createContainer.spec.ts
│   ├── etech-ui-dev
│   │   └── project.json
│   └── etech-ui-utils
│       └── project.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── postcss.config.cjs
├── reactDocgen.ts
├── tailwind.config.js
├── tests
│   └── setup.ts
├── tsconfig.astro.json
├── tsconfig.json
├── tsconfig.node.json
├── tsconfig.react.json
├── types
│   └── eslint-plugin-react.d.ts
└── vite.config.ts
6
  • What do you get if you do console.log(path.resolve('../../my/path/here'))? Does the path look like you expect? Commented Jun 5, 2024 at 17:19
  • Yes the output is apps/components/example/Example.tsx Commented Jun 5, 2024 at 17:25
  • You sure? path.resolve says it resolves to an absolute path: nodejs.org/api/path.html#pathresolvepaths but that doesn't look like an absolute path Commented Jun 5, 2024 at 17:31
  • It was absolute I trimmed the path Commented Jun 5, 2024 at 17:43
  • So if you copy that absolute path and run ls path/you/copied/here then you get a result? I'm trying to ascertain that the path being resolved is indeed the correct path. Which I can't know from your question since I don't have your directory structure or your absolute path. Commented Jun 5, 2024 at 17:49

1 Answer 1

0

This is probably because paths in node are relative to the current working directory (where you invoked the command to launch the node executable) and not from the file with the path in it.

So you probably either want this, if apps is in the root of your project where you are running this command from:

apps/components/path/here

Or perhaps this if you want it to be relative to the current file:

path.join(__dirname, '../../app/components/path/here')
// or if using es modules
path.join(import.meta.dirname, '../../app/components/path/here')
Sign up to request clarification or add additional context in comments.

2 Comments

When I use path.join I get an error ReferenceError: __dirname is not defined in ES module scope
If you are using ES modules, then I think you need import.meta.dirname instead. See: nodejs.org/api/esm.html#no-__filename-or-__dirname. Also that issue has a lot of answers on stack overflow already if want to learn more about that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.