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

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

考虑以下两个文件:

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';

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/'));
});

错误:

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'

这是什么错误?我做错了什么?

旧版本的 Babel 随附了所有开箱即用的东西。较新的版本要求您安装设置所需的任何插件。首先,您需要安装 ES2015 预设。

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

接下来,您需要告诉 babelify 使用您安装的预设。

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

Source

为了正确编译 es2015-react 代码,您应该安装一些节点模块:

全球

npm install -g browserify

在您的应用程序目录中:

npm install --save-dev browserify babelify babel-preset-es2015 babel-preset-stage-0 babel-preset-react

然后创建gulp任务:

    var browserify = require("browserify");
    var babelify = require("babelify");

    gulp.task('es6-compile', function() {
      browserify({ debug: true })
        .transform(babelify.configure({ presets: ["es2015","react", "stage-0"] }))
        .require("./public/src/javascripts/app.js", { entry: true })
        .bundle()
        .pipe(gulp.dest('./public/dest/javascripts'));
    });

在 ./public/dest/javascripts 目录中你会找到编译后的 es5 app.js 文件。

此错误可能是由于 gulp 任务中没有包含 tsify 插件来编译打字稿。

例子

    var tsify = require('tsify');

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

在此处查看安装和使用: https://www.npmjs.com/package/tsify

出于某种原因,babelify 8.0.0 不适用于我的 es2015 或 env 礼物。然而,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;关键细节如下。

main.js

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

测试

在空目录中:

npm init

并接受所有默认值,然后:

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

测试HTML文件

<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>

加载后,它会在页面中央显示一个微调器。

注意:我不隶属于 mattdesl 或 esmify。

我用的是 export 而不是 exports.

export 更改为 exports

ESLint 本身不支持这个,因为这是违反规范的。但是如果你使用 babel-eslint 解析器然后在你的 eslint 配置文件中你可以这样做:

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

文档参考:https://github.com/babel/babel-eslint#configuration

从这里引用的答案:

.eslintrc 中,您可能必须指定解析器选项,例如:

{
"rules": {
    "indent": [
        2,
        4
    ],
    "linebreak-style": [
        2,
        "unix"
    ],
    "semi": [
        2,
        "always"
    ]
},
"env": {
    "es6": true,
    "browser": true,
    "node": true,
    "mocha": true
},
"extends": "eslint:recommended",
"parserOptions": {
    "ecmaVersion": 6,
    "sourceType": "module",
    "ecmaFeatures": {
        "jsx": true
    }
}

}

请查看 eslint 中的文档指南。

我在尝试从 node_modules 导入以 ES6 样式导出的模块时遇到了同样的错误。 SO 上的任何建议都对我没有帮助。然后我在 babelify repo 上找到了常见问题解答部分。根据那里的见解,错误出现是因为来自 node_modules 的模块在默认情况下不被转译,并且其中 export default ModuleName 之类的 ES6 声明不被 Common.js-style 模块支持的节点理解。

所以,我更新了我的包,然后使用 global 选项 运行 babelify 作为全局转换,排除所有节点模块,但我感兴趣的节点模块如 babelify 回购页面所示:

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

希望对您有所帮助。

如果您想通过 importrequire 方法在 npm 中向客户端使用任何内容,只需执行以下步骤

  1. 运行 npm install browserify babelify @babel/preset-env @babel/preset-react @babel/core es2015 --save-dev 安装所需的预设
  2. 将此代码添加到您的 package.json
"babel": {
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ] 
}
  1. /app 文件夹中创建一个名为 dom_front.js 的文件,您要将其转换为客户端 js。
const ReactDOM  = require('react-dom')
import React, {Component} from 'react' 
export {Component,React,ReactDOM};

这是模块和需求文件的混合导出数据。

注意:不要忘记安装 react-dom & react

  1. 使用 browserify api - 创建 js 文件,例如 browserifyload.js 和 assets 文件夹
const browserify = require("browserify")
const fs = require('fs')
browserify("./dom_front.js", {
  debug : true,
  standalone: "util"
}).transform(['babelify', { compact: false }], {
  global: true,                                  
  ignore: [/\/node_modules\/(?!@vizuaalog\/)/],     
  presets: [ 
    "@babel/preset-env",
    "@babel/preset-react"] 
  }).bundle().on('error', function (err) {
    console.log(err);  
  }).pipe(fs.createWriteStream('assets/mynpmmodule.js')).on('end', function(){
    console.log( 'finished writing the browserify file' );
  });
  1. 现在的文件夹结构是
app
--dom_front.js
--browserifyload.js
--assets(folder)
  1. 运行 /node_proj/app$ node browserifyload.js 或 运行 /node_proj/app$ browserify dom_front.js --transform babelify --standalone util > ./assets/mynpmmodule.js
  2. 检查资产文件夹,它现在在其中创建名为 mynpmmodule.js
  3. 的文件
  4. 将此文件添加到您的 HTML <script src="assets/mynpmmodule.js"></script>
  5. 现在您可以使用导出的 npm modules/classes 或使用上面提到的独立密钥所需的文件 util like
<script>
  const Component = util.Component;
  console.log(Component);
  const ReactDOM = util.ReactDOM;
</script>

我尝试了上面的所有答案,none 对我有用,我什至尝试使用 gulp-include / require 语法,它们既不是解决方案也不足以满足我的要求。

这是我的要求。

  1. 将所有modules/files捆绑成一个
  2. 全部保留comments/JSDocs
  3. 保留所有类型(例如const example = (parameter: string) => {}
  4. 使用import/export语法

列出要求的原因是因为我们需要一个存储库来存储我们的 shared-function、shared-config、shared-types 和共享常量作为 npm 包(使用 [= 安装51=])。在这种情况下,我们已经知道我们的项目都在使用 TypeScript,因此不需要将我们的 shared-module 编译成 .js,并且我们还需要像其他包一样保留所有描述(JSDoc 和 Type 实际上帮助 ).

到目前为止,我能做的最好的就是使用 browserifytsify。我不小心从 here.

找到了这个解决方法
browserify()
    .plugin(tsify, { target: 'es6' })
    .transform(babelify, { extensions: [ '.tsx', '.ts' ] })

我仍在寻找一种方法来保留我们的 inline-types 和 comments/JSDocs,但我相信这足以满足您的需要。

    return browserify(jsConfig.src)
  .transform(babelify.configure({
    presets: ["@babel/preset-env"]
  }))
  .bundle()
  .on('error', function (e) {
    console.log(e.message);

    this.emit('end');
  })

适合我。