SyntaxError: Unexpected token export

punkbit picture punkbit · Feb 26, 2017 · Viewed 12.4k times · Source

I'm working on a npm package called foobar, locally, to allow me to make changes or modifications in real time without having to publish/unpublish to improve development time and sanity.

In projectTest, I have linked foobar by using the command npm link foobar. If you don't know, the npm link flag creates a symlink to your globals (you can read more about it here: https://docs.npmjs.com/cli/link)

The projectTest happens to be a Reactjs project, written in ES2015, Webpack, babel, etc; and where I do import { x } from 'package', without any issues, etc.

As mentioned, the package foobar exists in the node_modules has a link to its development directory, but for some reason, when I try to import:

import { myFn } from 'foobar'

The following error is thrown into the console:

/foobar/lib/index.js:3
export const loadImage = () => {
^^^^^^
SyntaxError: Unexpected token export
    at Object.exports.runInThisContext (vm.js:78:16)
    at Module._compile (module.js:543:28)

This is not expected, based in the fact that other imports inplace work perfectly; Why doesn't this happen in the other existing imports where the code is also ES2015? It's not transpiled ahead or to a static file, but in real time AFAIK, since I have webpack setup with babel loader like:

var path = require('path')
var webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var AssetsPlugin = require('assets-webpack-plugin')
var assetsPluginInstance = new AssetsPlugin()

module.exports = {
  devtool: 'inline-source-map',
  context: path.resolve(__dirname, 'src'),
  entry: [
    'react-hot-loader/patch',
    'webpack/hot/dev-server',
    'webpack-hot-middleware/client',
    'babel-polyfill',
    './js/index.js'
  ],
  output: {
    path: __dirname,
    publicPath: '/assets/',
    filename: 'js/bundle.js?[hash]'
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: [
          'babel-loader'
        ]
      }
      ...
}

I'd like to understand the reason of this happening! So, to help me trace the issue, tried an import that is not to the node_module's linked package, but instead, to the full or relative path, for example:

import { myFn } from '/bar/zoo/lar/deep/foobar'

Where I have placed an equivalent syntax/file, of a working import that is my utils or helper functions, that I use across the project without problems. The syntax is:

export const myFn = () => {
  return 'myFn call!'
}

Where I import it from my app.js let's say, like:

import { myFn } from './utils' // works fine! BUT if I DO:
import { myFn } from '/path/to/packageFoobar' // I get the syntax error!

SO user @felixKling left a nice comment about webpack node_module being ignored, which I've now tested but I still get the error after removing the node_module:

(function (exports, require, module, __filename, __dirname) { export const styleObjectParser = str => {
                                                              ^^^^^^
SyntaxError: Unexpected token export
    at Object.exports.runInThisContext (vm.js:78:16)
    at Module._compile (module.js:543:28)

From what I can see this far, is that, in the webpack dev configuration file, only the code under the context is transpiled in run time. But I might be wrong:

module.exports = {
  devtool: 'inline-source-map',
  context: path.resolve(__dirname, 'src'),
  entry: [
    'react-hot-loader/patch',
    'webpack/hot/dev-server',
    'webpack-hot-middleware/client',
    'babel-polyfill',
    './js/index.js'
  ],

I'd like to confirm that changing the syntax works perfectly fine, so this is related with the context the babel-loader runs. Even though I don't understand why the syntax error happens, even when the node_module exclusion is removed.

module.exports = {
  myFn: function () {
    console.log('Syntax correct! myFn works!')
  }
}

I am using webpack2, node v7.4.0

Answer

alessia pileri picture alessia pileri · Feb 14, 2018

I think the problem is foobar project is not transpiled when linked with npm link, but projectTest shouldn't compile foobar project, it should just link it. You have to transpile foobar with babel before you link it in other project. You can add a build script in package.json of foobar project to transpile code into a /dist folder, and modify the main field of package.json in this way:

"main": "./dist/index.js"

Add npm run build in your development process, in order to have dist folder updated while developing foobar. Now projectTest should link transpiled version of foobar.