Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SyntaxError: 'import' and 'export' may appear only with 'sourceType: module' - Gulp

Consider the following two files:

app.js

import Game       from './game/game';
import React      from 'react';
import ReactDOM   from 'react-dom';

export default (absPath) => {
  let gameElement = document.getElementById("container");

  if (gameElement !== null) {
      ReactDOM.render(
          <Game mainPath={absPath} />,
          gameElement
      );
  }
}

index.js

import App from './src/app';

The gulpfile.js

var gulp        = require('gulp');
var source      = require('vinyl-source-stream');
var browserify  = require('browserify');
var babelify    = require("babelify");
var watch       = require('gulp-watch');

gulp.task('make:game', function(){
  return browserify({
    entries: [
      'index.js'
    ]
  })
  .transform('babelify')
  .bundle()
  .pipe(source('index.js'))
  .pipe(gulp.dest('app/'));
});

The error:

gulp make:game
[13:09:48] Using gulpfile ~/Documents/ice-cream/gulpfile.js
[13:09:48] Starting 'make:game'...

events.js:154
      throw er; // Unhandled 'error' event
      ^
SyntaxError: 'import' and 'export' may appear only with 'sourceType: module'

What is this error? What am I doing wrong?

like image 796
TheWebs Avatar asked Oct 13 '16 19:10

TheWebs


4 Answers

Older versions of Babel came with everything out of the box. The newer version requires you install whichever plugins your setup needs. First, you'll need to install the ES2015 preset.

npm install babel-preset-es2015 --save-dev

Next, you need to tell babelify to use the preset you installed.

return browserify({ ... })
  .transform(babelify.configure({
    presets: ["es2015"]
  }))
  ...

Source

like image 62
Mike Cluck Avatar answered Nov 01 '22 14:11

Mike Cluck


ESLint natively doesnt support this because this is against the spec. But if you use babel-eslint parser then inside your eslint config file you can do this:

{
    "parser": "babel-eslint",
    "parserOptions": {
        "sourceType": "module",
        "allowImportExportEverywhere": true
    }
}

Doc ref: https://github.com/babel/babel-eslint#configuration

Answer referred from here : ignore eslint error: 'import' and 'export' may only appear at the top level

like image 32
kaushalop Avatar answered Nov 01 '22 12:11

kaushalop


I came across the same error trying to import a module from node_modules that exports in ES6 style. Nothing that has been suggested on SO worked out for me. Then I found FAQ section on babelify repo. According to the insight from there, the error appears since modules from node_modules are not transpiled by default and ES6 declarations like export default ModuleName in them are not understood by node powered by Common.js-style modules.

So, I updated my packages and then used global option to run babelify as a global transform excluding all node modules but the one I was interested in as indicated on the babelify repo page:

...    
browserify.transform("babelify", 
    {
        presets: ["@babel/preset-env"], 
        sourceMaps: true, 
        global: true, 
        ignore: [/\/node_modules\/(?!your module folder\/)/]
    }).bundle()
...

Hope it helps.

like image 23
curveball Avatar answered Nov 01 '22 14:11

curveball


For some reason, babelify 8.0.0 didn't work for me with either the es2015 or env presents. However, as of 2018-07-10, the esmify plugin by mattdesl did work for me. My test case was exporting Spinner from spin.js as a window global. My example repo is here; key details follow.

main.js

import {Spinner} from 'spin.js';
window.Spinner = Spinner;

Test

In an empty directory:

npm init

and accept all defaults, then:

npm install --save spin.js
npm install --save-dev browserify esmify
npx browserify -p esmify main.js -o main-packed.js

Test HTML file

<html><head>
    <link rel="stylesheet" href="node_modules/spin.js/spin.css" />
    <script src="main-packed.js"></script>    <!-- <== the browserify output -->
</head>
<body>
    <div id="x"></div>
    <script>
    var target = document.getElementById('x');
    var spin = new Spinner().spin(target);
    </script>
</body></html>

When loaded, it displays a spinner in the center of the page.

Note: I am not affiliated with mattdesl or esmify.

like image 15
cxw Avatar answered Nov 01 '22 14:11

cxw