Search code examples
reactjswebpackrelative-pathabsolute-path

Why relative path is used in entry point and absolute path in output property of webpack?


Recently started learning how to config react with Webpack module bundler. Below code is a simple code that I have configured till now. I have taken this code from the official documentation of Webpack.

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

I understood that the entry point is the point where the webpack looks to start the bundling process and the output tells where to emit the bundled file that webpack creates.

But here I am getting confused why we need to have a relative path in the entry path and an absolute path in the output path?

I tried to search this information from official documentation but I didn't found any reference.


Solution

  • It is not necessary for the entry path to be relative. It can be an absolute path too, because what's happening under the hood is a custom join operation:

    const join = (rootPath, request) => {
        if (!request) return normalize(rootPath);
        const requestType = getType(request);
        switch (requestType) {
            case PathType.AbsolutePosix:
                return posixNormalize(request);
            case PathType.AbsoluteWin:
                return winNormalize(request);
        }
        switch (getType(rootPath)) {
            case PathType.Normal:
            case PathType.Relative:
            case PathType.AbsolutePosix:
                return posixNormalize(`${rootPath}/${request}`);
            case PathType.AbsoluteWin:
                return winNormalize(`${rootPath}\\${request}`);
        }
        /* ... */
    };
    

    So, if both rootPath and request are absolute, then the normalized version of the request will be returned. The normalization is achieved through the Node.js' normalize function(which also depends on the environment, but it fulfills the same purpose).

    From path.normalize docs:

    The path.normalize() method normalizes the given path, resolving '..' and '.' segments.

    However, if the request is not absolute, then obviously it is relative and the result of the join operation will be the resulted path after normalizing the combination of rootPath and request.

    Let's now clarify what rootPath and request are. By default, the rootPath points to the current working directory, because it refers to the the default value of options.context, which is process.cwd(). So, rootPath refers to the current working directory.
    On the other hand, concisely, request refers to the path you provided to the entry option in your snippet.

    Maybe an example will clarify this. Let's assume I have a repo called understanding-webpack(I actually have one, here). If you clone that, the rootPath will point, by default, to home/user/Documents/understanding-webpack. If the entry's value is src/foo.js, then the normalized path will be home/user/Documents/understanding-webpack/src/foo.js.

    But, as already mentioned, the entry's value can also be an absolute path. You can provide an absolute path like this:

    const config = {
      /* ... */
      entry: path.join(__dirname, 'src'),
      /* ... */
    }
    

    and now, as we've seen, the normalized version of the request will be returned(i.e path.join(__dirname, 'src')).

    Providing an absolute path can be useful when the directory structure is not a common one, like

    - src
      - index.js
    - webpack.config.js
    

    For example, in the repo I was referring to earlier, the webpack config files are within the examples directory. So, each entry value will be absolute, otherwise the resulting path will always be /home/user/Documents/understanding-webpack/src/index.js. This is not desired, since the examples part does not exist.


    The join operation takes place here, in the JoinRequestPlugin.