2
votes

I have a project I'm doing with node in ES6 which was using babel-node to run. Now I'm trying to implement babel in a more production manner and have tried two attempts.

Webpack babel-loader with following configuration:

module.exports = {
  entry: './src/cloud/main.js',
  devtool: 'source-map',
  output: {
    path: './src/static/build',
    filename: 'bundle.js'
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loaders: [
          'babel-loader?presets[]=es2015',
        ],
      },
      {
        test: /\.css$/,
        loaders: [
          'style-loader',
          'css-loader',
        ],
      },
      {
        test: /\.html$/,
        loaders: [
          'raw-loader',
        ],
      },
    ],
  },
}

It started complaining about the import statement in main.js and to silence it I used ?presets[]=es2015 which I found in a similar question. Then the problem arrived in which it filtered to the import statements that went to node_modules with the following message:

ERROR in ./~/socket.io/lib/index.js Module not found: Error: Cannot resolve module 'fs' in

My other approach was with the register hook like this:

require('babel-core/register')({
  ignore: /node_modules/,
});
require('./main.js');

but it threw this message: import express from 'express'; ^^^^^^

SyntaxError: Unexpected reserved word

//main.js - simplified

import express from 'express'
const app = express()
const server = app.listen(port, () => {
  console.log(`Listening at http://${server.address().address === '::' ? 'localhost' : server.address().address}:${server.address().port}`)
})
2
Take a look at this answer on running Babel. stackoverflow.com/questions/30921806/…Dirk

2 Answers

2
votes

I don't think you need to exclude the node_modules in your loader config. However, you might want to let webpack know what to resolve. Try adding something like this:

resolve: {
    root: path.join(__dirname),
    fallback: path.join(__dirname, 'node_modules'),
    modulesDirectories: ['node_modules'],
    extensions: ['', '.json', '.js', '.jsx', '.scss', '.png', '.jpg', '.jpeg', '.gif']
},

The modulesDirectories key should keep webpack from running down every single require / import in your working directory.

Also, adding target to the top of your config should resolve issues with builtins like fs

target: 'node'
2
votes

Ok I figured it out thanks to other answers and 4m1r' answer. I post the example code.

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

var nodeModules = {};
fs.readdirSync('node_modules')
  .filter(function (x) {
    return ['.bin'].indexOf(x) === -1;
  })
  .forEach(function (mod) {
    nodeModules[mod] = 'commonjs ' + mod;
  });

module.exports = {
  name: 'server',
  target: 'node',
  context: path.join(__dirname, 'src', 'cloud'),
  entry: {
    server: './main.js'
  },
  output: {
    path: path.join(__dirname),
    filename: '[name].js'
  },
  externals: nodeModules,
  module: {
    loaders: [
      {test: /\.js$/, exclude: /node_modules/, loaders: ['babel-loader?presets[]=es2015']}
    ]
  },
  resolve: {
    root: path.join(__dirname),
    fallback: path.join(__dirname, 'node_modules'),
    modulesDirectories: ['node_modules'],
  }
};

What was really important too was the externals key which prevented it fro leaking to the node_modules through requires and specifying for some reason ?presets[]=2015 in the babel-loader. I'm accepting 4m1r because it was what finally fixed the code.