Search code examples
node.jsvue.jsfile-storage

How to use node:fs inside of a vue app to save images into source directory


I'm building a personal portfolio website using Vue.js, and I'm attempting to build a form to allow me to add to my portfolio later. I'm storing the text data in firebase, but I also want to be able to upload and access pictures. I'm attempting to upload through a form and save with node:fs with the following import { writeFile } from 'node:fs'

export function saveImages (data:FileList, toDoc: string) {
  const reader = new FileReader()
  const imageNames = []
  console.log(toDoc)
  for (let i = 0; i < data.length; i++) {
    imageNames.push(toDoc + '/' + data[i].name)
    reader.readAsBinaryString(data[i])
    reader.onloadend = function (e) {
      if (e.target?.readyState === FileReader.DONE) {
        const imageFile = e.target.result as string
        if (imageFile) {
          writeFile('./assets/' + data[i].name, imageFile, 'binary', (err) =>
            console.log('was unable to save file ' + data[i].name + ' => ' + err)
          )
        }
      }
    }
  }
  return imageNames
}

When I attempt to call saveImages, I get the error

ERROR in node:fs

Module build failed: UnhandledSchemeError: Reading from "node:fs" is not handled by plugins (Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "node:" URIs.

Solution

  • As pointed out by the comments on your answer, the Node.js-fs-module is cannot be used in the frontend. Here is why:

    1. While developing your vue.js-app, you should remember that you always have to run a development server in order for the app to compile to a browser-readable format. The resulting page will not be delivered as some .vue-files and .js-files but everything will be bundled into an html-file and some additional .js-files.
    2. While running the development server, the source directory of your app is 'lying' on a server, but this is not even the directory that is delivered to the browser.
    3. In a production server, there will be static assets built out for your vue.js-app, which does also only contain .html- and .js-files.
    4. When a client (browser) accesses a route, some static files will be delivered to the browser, and all the code you are writing in your .vue-files will be run on the client's machine, not on a server. So you cannot interact with server-side directories.

    Therefore, you should look into a backend server framework, which you can connect to your frontend to allow users to upload files to a server, and those files would be saved on the server. You will then set up your vue app to communicate with the backend. Here are some additional resources: