stackblitz / webcontainer-core

Dev environments. In your web app.
https://webcontainers.io
MIT License
3.77k stars 142 forks source link

Download directorys and files from virtual file system to browser #1455

Closed svenhue closed 3 months ago

svenhue commented 3 months ago

Background: Building an platform with that users can create websites, internal apps, dashboards...

I am using WebContainer to create a nuxt3 project and build it in the virtual file system. Now i want to download some static assets (.output folder in nuxt root folder) from the virtual file system to my computer This feature isnt really required for the product, but i need that for testing.

I already tried to read the directorys and files declarative with fn and that works fine except i cant download the result of that (nested Array with dirs: {name: string, files: File[], subdirs: Dirs[]}[] and files: {name: string, value: string (utf8)}) to the web browser, right?

Is there a way to achive this? Downloading the hole .output folder?

Thank you so much for your work on this project!


Note that this code piece is only for testing, im aware of the problems that could occur.

` import { Dir } from "./IDirsAndFiles"; import { WebContainerService } from "./WebContainerService";

export class ApplicationBuildService extends WebContainerService{

private readonly _buildOutputDirectory: string = './.output';

public async Build(){

    await this.boot();
    let result = null;
    await this.env.RunCommand(this.api.containerInstance, 'npm', ['run', 'build'], true, "You can preview this build using", async () => {

        result = await this.GetBuildDirectory()

    }
    );

    //this.DownloadBuild(result)

}
private async DownloadBuild(dir: Dir){
    // zip + express api !? https://stackoverflow.com/questions/15641243/need-to-zip-an-entire-directory-using-node-js
    // 
}

private async GetBuildDirectory(): Promise<Dir>{

    const p = path
    const result = await copyDirOrFile(this._buildOutputDirectory, this)

    async function copyDirOrFile(dirPath, self: ApplicationBuildService){

        const dirFn = await self.api.containerInstance.fs.readdir(dirPath)

        const rootDir: Dir = {name: dirPath, files: [], subDirs: []}

            for(const dirOrFile of dirFn){  
                let isDir = true
                let file;

                try{
                    file = await self.api.containerInstance.fs.readdir(dirPath + '/' + dirOrFile, 'utf-8')

                }catch(e){
                    isDir = false
                }
                if(!isDir){
                    file = self.api.containerInstance.fs.readFile(dirPath + '/' + dirOrFile,'utf-8')

                    rootDir.files.push({value:file, name: dirOrFile})
                }else{

                    const newDir = await copyDirOrFile(dirPath + '/' + dirOrFile, self)
                    rootDir.subDirs.push(newDir)
                }
            }
            return rootDir;
    }
    return result;

}

} `

svenhue commented 3 months ago

Solutions wasnt related to this repo

Used JsZip and FileSaver to create and download a zip

issue can be closed