0
votes

I'm trying to find some information about Webpack and relative imports when working with ES6 and Babel.

I have an import line in a simple entry point in my app:

// app.es6
import * as sayHello from 'sayHello';
console.log(sayHello());

sayHello.es6 is the same directory as app.es6. (The contents of sayHello.es6 is not significant).

When I run the Webpack compiler via the command line:

$ webpack

I get the following error:

ERROR in ./app/app.es6
Module not found: Error: Cannot resolve module 'sayHello' in /Users/username/Code/projectname/app

This is solved by setting the path to relative:

// app.es6 - note the ./ in the import
import * as sayHello from './sayHello';
console.log(sayHello());

This is a bit of a pain because it's different to the example es6 code on Babel website under the Modules section.

Here is my Webpack config:

var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: [
    'babel-polyfill',
    './app/app.es6'
  ],
  output: {
      publicPath: '/',
      filename: './dist/app.js'
  },
  debug: true,
  devtool: 'source-map',
  module: {
    loaders: [
      {
        test: /\.js|\.es6$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        query:
        {
          presets:['es2015']
        }
      }
    ]
  },
  resolve: {
    extensions: ['', '.js', '.es6'],
  },
};

Question: Does any one know why there is this difference? Or where the relevant information regarding ES6 module imports is in the Webpack documentation?

1
So you want to get rid of ./ in import? - Andrew Li
Basically, yeah. I was following the Babel module ES6 example and this one threw me. - Richard Fernandez
Maybe use resolve.modules? Use path to resolve - Andrew Li
Where is the example you're looking at that says to leave out the ./? Babel doesn't have any special logic here, it's the same as a require call. ./sayHello says to look for a file relative to the current one, sayHello says to load a module from node_modules called sayHello. The example is also wrong because with import * as sayHello from './sayHello'; sayHello can only ever be an object, there is no way it can be a function, in spec-compliant ES6. - loganfsmyth
The example where I leave out the ./ is in the first example. Also, I didn't realise it can only be an object. (something new learnt.) - Richard Fernandez

1 Answers

3
votes

This is by design, without prefixing it indicates the module should be loaded from node_modules directory. You can set up an alias in your webpack config which would remove the need for relative module imports

resolve: {
  alias: { 
    sayHello: '/absolute/path/to/sayHello'
  },
  extensions: ['', '.js', '.es6']
}

Then Webpack would fill in the gaps in your import statements and allow you to omit the relative path and import * as sayHello from 'sayHello'; would work throughout your project