Search code examples
javascripthtmldirectorynwjs

Why is relative path not working in NWJS application?


Only absolute paths are working. This code works. If I use ../../../SYSTEM.USER/DOCUMENTS/DOCUMENTS.NFO' it won't work.

EDIT: How can I use a variable like /%APPLICATION%/SYSTEM.USER/DOCUMENTS/DOCUMENTS.NFO? Is that possible in this manner?

Main.js

function OpenDocuments() {
    const path = require('path');
    nw.Shell.showItemInFolder(path.resolve('D:/PROTON DRIVE/PROTON.USER/DOCUMENTS/DOCUMENTS.NFO'));
}

Default.html

<div name="FolderMenuContainer" id="FolderMenuContainer" class="FolderMenuContainer">
    <span name="FolderIcon" id="FolderIcon" class="material-icons"> description </span>
    <span name="FolderText" id="FolderText" class="FolderText" onclick="OpenDocuments()"> Documents </span>
</div>

File Structure

enter image description here

enter image description here


Solution

  • One way I use is to use path.join and process.cwd(). cwd means "Current Working Directory".

    Example:

    const path = require('path');
    const place = path.join(process.cwd(), '..', '..', 'my-folder');
    

    You can also use __dirname which is relative to the file the code is executed from, which may be different from the Current Working Directory.

    const path = require('path');
    const place = path.join(__dirname, '..', '..', 'my-folder');
    

    If you want to use resolve Windows environment variables, I would recommend making a helper function like this:

    /**
     * Replaces all environment variables with their actual value.
     * Keeps intact non-environment variables using '%'.
     *
     * @example
     * // 'C:\Users\bob\Desktop\AMD64'
     * resolveWindowsEnvironmentVariables('C:\Users\%USERNAME%\Desktop\%PROCESSOR_ARCHITECTURE%');
     *
     * @param  {string} filePath  The input file path with percents.
     * @return {string}           The resolved file path.
     */
    function resolveWindowsEnvironmentVariables (filePath) {
      if (process.platform !== 'win32') {
        return filePath;
      }
      if (!filePath || typeof(filePath) !== 'string') {
        return undefined;
      }
    
      /**
       * Returns the value stored in the process.env for a given
       * environment variable. Or the original '%ASDF%' string if
       * not found.
       *
       * @example
       * replaceEnvironmentVariable('%USERNAME%', 'USERNAME');
       *
       * @param  {string} withPercents     '%USERNAME%'
       * @param  {string} withoutPercents  'USERNAME'
       * @return {string}                  'bob' || '%USERNAME%'
       */
      function replaceEnvironmentVariable (withPercents, withoutPercents) {
        let found = process.env[withoutPercents];
        // 'C:\Users\%USERNAME%\Desktop\%asdf%' => 'C:\Users\bob\Desktop\%asdf%'
        return found || withPercents;
      }
    
      // 'C:\Users\%USERNAME%\Desktop\%PROCESSOR_ARCHITECTURE%' => 'C:\Users\bob\Desktop\AMD64'
      filePath = filePath.replace(/%([^%]+)%/g, replaceEnvironmentVariable);
    
      return filePath;
    }
    

    You may also want to resolve non-windows paths

    /**
     * Resolves paths that start with a tilde to the user's
     * home directory.
     *
     * @example
     * // '/home/bob/GitHub/Repo/file.png'
     * resolveTilde('~/GitHub/Repo/file.png');
     *
     * @param  {string} filePath  '~/GitHub/Repo/file.png'
     * @return {string}           '/home/bob/GitHub/Repo/file.png'
     */
    function resolveTilde (filePath) {
      if (process.platform === 'win32') {
        return filePath;
      }
      if (!filePath || typeof(filePath) !== 'string') {
        return undefined;
      }
    
      const os = require('os');
      // '~/folder/path' or '~' not '~alias/folder/path'
      if (filePath.startsWith('~/') || filePath === '~') {
        return filePath.replace('~', os.homedir());
      }
    
      return filePath;
    }