【问题标题】:SyntaxError: 'import' and 'export' may appear only with 'sourceType: module' in Gulp + Babel + TypeScript + Source MapsSyntaxError: 'import' 和 'export' 可能只出现在 Gulp + Babel + TypeScript + Source Maps 中的 'sourceType: module' 中
【发布时间】:2015-11-15 11:17:39
【问题描述】:

我正在尝试从.ts 编译为.min.js,如下所示:

TS --> ES6 ---> ES5 ---> .min.js + .map

在我只是执行以下操作并且一切正常之前:

TS ---> ES5 --->  .min.js + .map

我希望能够使用源地图。我的 tsconfig.json 如下:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "moduleResolution": "node",
    "isolatedModules": false,
    "jsx": "react",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "declaration": false,
    "noImplicitAny": false,
    "removeComments": true,
    "noLib": false,
    "preserveConstEnums": true,
    "suppressImplicitAnyIndexErrors": true
  }
}

由于我添加了"target": "es6",我收到了错误:

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

tsify 文档说:

当 TypeScript 文件在通过 Browserify 捆绑器运行之前未编译为 JavaScript 时,会发生此错误。您可能会遇到几个已知的原因。

但在我的 Gulp 任务中,在 babelify 之前运行 tsify:

gulp.task("bundle", function() {

  var mainTsFilePath = "src/main.ts";
  var outputFolder   = "bundle/src/";
  var outputFileName = settings.projectName + ".min.js";
  var pkg            = require("./package.json");

  var banner = [
    "/**",
    " * <%= pkg.name %> v.<%= pkg.version %> - <%= pkg.description %>",
    " * Copyright (c) 2015 <%= pkg.author %>",
    " * <%= pkg.license %>",
    " */", ""
  ].join("\n");

  var bundler = browserify({
    debug: true,
    standalone : settings.projectName
  });

  var babelifyConfig = { extensions: ['.js','.jsx','.ts','.tsx'] };

  // TS compiler options are in tsconfig.json file
  return bundler.plugin(tsify)
                // Added this line and target es6
                .transform(babelify.configure(babelifyConfig)) 
                .add(mainTsFilePath)
                .bundle()
                .pipe(source(outputFileName))
                .pipe(buffer())
                .pipe(sourcemaps.init({ loadMaps: true }))
                .pipe(uglify())
                .pipe(header(banner, { pkg : pkg } ))
                .pipe(sourcemaps.write("."))
                .pipe(gulp.dest(outputFolder));
});

我刚刚添加了 ES6 编译,在我将 TS 编译到 ES5 之前,一切正常(包括源映射)。

我不知道出了什么问题。你有什么想法?提前致谢!

【问题讨论】:

  • 您首先使用 typescript 生成 ES6,然后使用 babelify 生成 ES5,是否有特定的原因?你的 babelifyConfig 看起来怎么样?
  • 计划是让 babel 处理 polyfill,因为它比 TypeScript 做得更好,所以我从 TS 中获得了字符串类型的好处,而从 babel 中获得了 polyfills 的好处。我的 babelify 配置只设置了一些扩展: var babelifyConfig = { extensions: ['.js','.jsx','.ts','.tsx'] };
  • @RemoH.Jansen 你解决了吗?
  • 解决了我自己的问题。我将奖励赏金以很好地解释 gulp、tsify 和 babelify 如何协同工作。

标签: typescript gulp babeljs uglifyjs source-maps


【解决方案1】:

看来 browserify 及其对符号链接转换的解析存在问题。但是,由于this commit 使用了返回规范化绝对路径名的fs.realpathSync 方法,因此应该解决此问题。而且它肯定已经登陆了node-browserify10.2.5版本。

作为 James 的mentioned,如果您无法更新到较新的版本,您可以使用realpathify 来查看他的答案,fixes 是同样的问题。

gulp 和 browerify 如何协同工作非常有趣,因为它是一种罕见的工具,实际上不需要关联的 gulp 插件(甚至在某些时候被 blacklisted 强制用户直接使用 browserify 包)。 不需要它的原因是因为@substack,以作为 browserify 和磁带的创建者而闻名,他非常了解(我假设,喜欢)他在这两个项目中使用的节点流的使用.鉴于此前提,以及 99% 的 gulp 插件仅插入他们想要与流一起使用的工具这一事实,gulp 插件是不必要的,因为 browserify 已经在使用您可以在任务中返回的流。

小旁注,他还写了一篇 handbook 关于在 node 中做流的文章,如果你想了解更多关于 gulp 内部工作原理的信息,值得一看。

关于tsify,它的工作方式与任何其他插件相同,编译 typescript 文件并将输出传递到流以供 browserify 进程继续。

【讨论】:

    【解决方案2】:

    Aperçu's answer 中很好地描述了您收到错误的原因。如前所述,更新应该可以解决该问题,但如果无法解决,您可以查看James' answer

    Gulp、Babelify 和 TSify 协同工作,将您的代码从 TypeScript ES2015 转换为与浏览器兼容的带有模块的纯 ES5。以下是它们的基本介绍:

    • Gulp - 一个任务运行器,它使用流允许您一次分组和执行某些较小的任务,以提高构建的效率和简单性

    • Babelify - 一个 Browserify 转换器,可在捆绑之前将您的文件原位转换为纯 JavaScript,根据您的预设和插件与浏览器兼容; Babel 用于 Browserify

    • TSify - 一个 Browserify 插件,可将您的 TypeScript 编译为浏览器的 JavaScript

    使用 Gulp,您可以设置两个 Browserify 插件,以一项简单的任务将您的 TypeScript 文件转换为 ECMAScript 2015 文件。除了使用被列入黑名单的gulp-browserify,您可以继续使用browserify 包,因为它已经使用流,这是 Gulp 所期望的,因此不需要额外的 Gulp 插件。

    现在介绍它们如何协同工作。把 Gulp 想象成一个制作苹果派的工厂,你的 Gulp 任务是你的工厂执行的某些任务,以便它可以创建最终产品:制作面团、制作馅料、烘烤馅饼等。假设我想创建填充,我需要开始:

    • 采摘苹果并进口
    • 用柠檬汁改变苹果的风味
    • 加热然后加入所有成分
    • 让它慢炖并冷却,直到为下一阶段做好准备

    这些类似于 Gulp 任务中任务的某些部分。如果我想从 TypeScript 创建浏览器可运行的 JavaScript,我会类似地:

    • 选择要转译的目标文件
    • 使用插件 (TSify) 转换我的目标文件并将它们编译为(在本例中)ES2015
    • 使用转换器 (Babelify) 转换我的目标文件,以将它们从 TSify 的 ES2015 转换为浏览器的 ES5

    将其应用到实际代码中,我们得到:

    1. 创建一个新的 Gulp 任务,将我们的代码从 TypeScript ES2015 转换为纯 ES5
    2. 使用browserify 实例和流选择将要转译代码的入口文件,然后将它们传递到流中
    3. 通过注册插件tsify 继续处理流中的文件,该插件将运行并将流中的 TypeScript 文件转换为 ES2015(如果 target 是 ES2015),然后将它们传递到流中李>
    4. 将流中的新 ES2015 文件移交给 babelify,这会将 ES2015 转换为具有特定预设 es2015 的浏览器友好的 ES5,然后将它们传递到流中以便管道继续

    所有部分协同工作,让您可以通过一项任务完成多项任务,最终将您的 TypeScript 转换为 ES5。

    【讨论】:

    • 您基本上指出了我们的答案,复制粘贴了一段,添加了它们单独描述的列表以及对 gulp 是什么的基本解释(完全超出了范围)。下次尝试更有创意。
    • @Aperçu 如果您发现任何抄袭,请随时标记我的答案。赏金海报说对 Gulp、TSify 和 Babelify 以及它们如何协同工作的深入解释将适合赏金,这就是我所做的。另外,为了未来读者的利益,请取消删除您的答案,这真的很有价值。
    • 不,他绝对没有要求解释它们分别是什么,请重读。您还必须了解,即使有赏金,您也必须尝试与最初的 OP 保持话题。此外,我不认为你真的觉得它有价值,否则你会投票的,对吧?
    • @Aperçu 你说得对;我想我被赏金蒙蔽了双眼。我会继续做一个标志来制作我的答案社区维基。我强烈建议您在此处取消删除您的答案,因为它实际上回答的问题与您提到的我的不同。
    • 我认为这不会改变任何事情,但感谢您的认可。
    【解决方案3】:

    我遇到了同样的问题,这是由于我的 node_modules 中有符号链接造成的。我通过将 realpathify 插件添加到 browserify 来修复它。

    var gulp = require("gulp")
    var browserify = require("browserify")
    var babelify = require("babelify")
    var source = require('vinyl-source-stream')
    var tsify = require("tsify")
    var sourcemaps = require('gulp-sourcemaps')
    var buffer = require('vinyl-buffer');
    var realpathify = require('realpathify')
    
    gulp.task("default", function () {
    
        browserify({
            basedir: '.',
            debug: true,
            cache: {},
            packageCache: {},
            entries: [ 'app/browser.ts' ]
        })
        .plugin(tsify)
        .plugin(realpathify)
        .transform(babelify, {extensions: ['.js', '.ts'], presets: ['es2015']})
        .bundle()
        .on('error', function (error) { report(error) })
        .pipe(source('bundle.js'))
        .pipe(buffer())
        .pipe(sourcemaps.init({loadMaps: true}))
        .pipe(sourcemaps.write('./'))
        .pipe(gulp.dest("dist"))
    })
    

    【讨论】:

      猜你喜欢
      • 2017-02-23
      • 2017-05-16
      • 1970-01-01
      • 2017-04-23
      • 1970-01-01
      • 2018-05-28
      • 1970-01-01
      • 2017-10-06
      • 1970-01-01
      相关资源
      最近更新 更多