Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having trouble with the webpack module resolution

I have a global npm module installed, let's call it abc-cli. Now I have a react app that runs with this command: abc-cli run.

What abc-cli basically does is gets the components in the app and compiles and runs it with its source.

Now I want to publish this app as a separate npm module. So I am using the Webpack to generate the bundle. While resolving modules, webpack is unable to resolve the modules that are a part of the abc-cli. That is obvious, webpack has no idea what abc-cli is.

So my question is how do I make sure that webpack resolves the modules dependencies? Is there any way I can make the webpack run/compile the abc-cli while bundling.

Or the worst case could be how to suppress the module resolution warning or ignore those modules. Because I know that its going to be present.

Example:

In my app, I have an import statement as

import SomeComponent from '@abc/components';

Now while bundling, the webpack won't resolve this module:

Module not found: Error: Can't resolve '@abc/components' in '/home/shishir/app/src/shared/visualizations'

It would be great help if I could get around this.

My webpack configuration:

module.exports = {
  mode: 'development',
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: 'index.js',
    libraryTarget: 'commonjs2'
  },
  resolve: {
    extensions: ['.mjs', '.js', '.jsx']
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        include: path.resolve(__dirname, 'src'),
        exclude: /(node_modules|bower_components|build)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              'es2015',
              'react',
              'stage-2'
            ]
          }
        }
      },
      {
        test: /\.css$/,
        use: [
          { loader: "style-loader" },
          { loader: "css-loader" }
        ]
      },
      {
        test: /\.(png|svg|jpg|gif)$/,
        use: [
          'file-loader'
        ]
      }
    ]
  },
  externals: {
    'react': 'commonjs react'
  }
};

I tried the null-loader:

{
        test: require.resolve("@abc/components"),
        use: 'null-loader'
}

but it didnt help.

like image 704
Shishir Anshuman Avatar asked Mar 19 '19 08:03

Shishir Anshuman


People also ask

What is module resolution?

Module resolution is the process the compiler uses to figure out what an import refers to. Consider an import statement like import { a } from "moduleA" ; in order to check any use of a , the compiler needs to know exactly what it represents, and will need to check its definition moduleA .

What is webpack and what problem does it solve?

Webpack applies automatic transformations on your working files to make them into production files that are more useful for your end user. Those transformed files are copies, and they go to a different folder, so the original files are never modified on this process and stuff keeps tidy.

What is __ Dirname in webpack?

The __dirname in a node script returns the path of the folder where the current JavaScript file resides. __filename and __dirname are used to get the filename and directory name of the currently executing file.


1 Answers

These're two ways to inform webpack of extra location to look for a module.

// webpack.config.js

module.exports = {
  //...
  resolve: {
    // 1. add extra `node_modules` directory to search path
    modules: ['node_modules', '/abs_path/to/global/node_modules'],
    // 2. use alias to explicitly map a module name to its exact location
    alias: {
      '@abc': '/abs_path/to/global/node_modules/@abc'
    }
  }
};

For your use case, if you only has @abc module sitting outside the conventional local node_modules directory, I'd recommend you use resolve.alias.

Source: https://webpack.js.org/configuration/resolve/#resolvemodules.

like image 75
hackape Avatar answered Nov 09 '22 07:11

hackape