简体   繁体   中英

Making export default work with Babel, webpack and Node.js

I can't figure out why my code doesn't work.

I am building a ES6 style class and want to export it to be able to use it somewhere else in the server side. I put the code into a file called PlayerManager.js in the server folder.

I put my client code in the src folder. And my server code in my server folder and server.js outside of server folder.

Here is the directory structure:

Root
 - dist
 - node_modules
 - public
 - server
 - src
 server.js
 webpack.base.js
 webpack.dist.js
 package.json
 .babelrc

PlayerManager.js file:

class PlayerManager {

    constructor() {
        if (! PlayerManager.instance) {
            this.playerList = {};
            this.bulletList = {};
            this.initPack = {player: [], bullet: []};
            this.removePack = {player: [], bullet: []};

            PlayerManager.instance = this;
        }

        return PlayerManager.instance;
    }

    resetData() {
        this.initPack.player = [];
        this.initPack.bullet = [];
        this.removePack.player = [];
        this.removePack.bullet = [];
    }

}

const instance = new PlayerManager();
Object.freeze(instance);

export default instance;

However, when I use npm run dev which runs node server.js it throws an error saying

export default instance;
^^^^^^
SyntaxError: Unexpected token export
    at Object.exports.runInThisContext (vm.js:53:16)

Here is the configuration for babel in webpack:

const path = require('path');
var CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
  entry: {
    main: './src/main'
  },

  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].bundle.js'
  },

  plugins: [
    new CopyWebpackPlugin([
        { from: 'public/img',
          to: 'static' },
        { from: 'public' }
      ])
  ],

  module: {
    loaders: [
      {
        test: /\.js$/,
        loader: 'babel',
        //include: path.join(__dirname, 'src')
        exclude: [
          path.resolve(__dirname, "node_modules"),
        ],
      },
      { test: /\.(png|jpg)$/, loader: 'url-loader?limit=90000' } 
    ]
  },

  resolve: {
    extensions: ['', '.js']
  }
};

In .babelrc :

{
  "presets": [
    "es2015"
  ],

  "sourceRoot": "./src"
}

In my package.json file:

"scripts": {
    "build": "npm run lint && npm run release",
    "lint": "./node_modules/.bin/eslint ./src/**/*.js",
    "dev": "node server.js",
    "release": "NODE_ENV=production webpack --config ./webpack.dist.js --progress",
    "test": "./test/*.test.js --compilers js:babel-core/register --recursive --reporter spec"
  },

Webpack is a bundler for producing packages that run on the client (in the browser), it is not aware of or concerned with code on the server. (Unless you are doing universal application stuff.)

You will notice too that your npm dev script is simply asking node to load the server.js file, which is (correctly) not mentioned anywhere in your Webpack config.

You are looking for babel-register :

One of the ways you can use Babel is through the require hook. The require hook will bind itself to node's require and automatically compile files on the fly.

Create an "entry" file that first requires babel-register and then requires your server.js file:

// server-entry.js
require('babel-register')
require('./server.js')

Now change your npm dev script to be node server-entry.js .

______

Aside: it is necessary to create an entry file as babel-register cannot transpile the file in which it is invoked. For example, this would fail:

// server.js
require('babel-register')

export default function () {}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM