【问题标题】:Using Babel with a single output file and ES6 modules将 Babel 与单个输出文件和 ES6 模块一起使用
【发布时间】:2016-03-02 01:06:43
【问题描述】:

这是我将 ES6 代码编译成单个 ES5 文件的 gulp 任务。我在 ES6 中使用类和模块(importexport)。

  gulp.src(paths.scripts)
        .pipe(sourcemaps.init())
        .pipe(babel({
          presets: ['es2015']
         }))
        .pipe(concat('all.js'))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('./www/js'));

但是,由于 Babel 将 ES6 import 指令编译成 require 命令,并且 require 将尝试请求文件,因此请求文件失败,因为所有 ES5 代码都被合并到一个文件 all.js 中。

结果是一堆“错误:找不到模块”错误。当模块都保存在一个文件中时,如何编译可以工作的模块?

【问题讨论】:

  • 如果没有 Browserify 之类的东西,这似乎不再起作用(另请参阅 this answer)。但是,由于您似乎打算在浏览器中运行代码,因此无论如何您都应该看看 :-)

标签: javascript ecmascript-6 babeljs ecmascript-5


【解决方案1】:

您不是第一个需要使用 Babel 将 JSX/ES6 转换为 ES5 但不使用 CommonJS 模块和因此使用 Browserify/Webpack 的人。不幸的是,这在当时是不可能的(123),而且看起来永远不可能。如果您想使用通过 Babel 转译的 ES6,您几乎不得不使用这些工具,但是您将没有机会将生成的代码与其他串联/内联 JavaScript 一起使用(因为所有这些 require() 调用而不是window 上的全局变量)。可惜 Babel 不允许改变这种行为。

【讨论】:

    【解决方案2】:

    您可能需要 Browserify 才能使其与 gulp 一起使用:

        browserify('./js/script.js', { debug: true })
          .add(require.resolve('babel-polyfill'))
          .transform(babelify.configure({presets: ['es2015']}))
          .bundle()
          .on('error', util.log.bind(util, 'Browserify Error'))
          .pipe(source('all.js'))
          .pipe(buffer())
          .pipe(sourcemaps.init({loadMaps: true}))
          .pipe(uglify({ mangle: false }))
          .pipe(sourcemaps.write('./'))
          .pipe(gulp.dest('./www/js'));
    

    例如: https://github.com/glued/harp-babel/blob/babel-gulp-v6/gulpfile.babel.js

    【讨论】:

      【解决方案3】:

      有一种方法可以完全不使用 import 而是使用 gulp-include 来处理这个问题。

      所以你要做的是使用 gulp-include 告诉 gulp 如何包含文件。

      然后在你的 js 文件中你可以这样做:

      //=require views/_*.js
      //=require views/*.js
      

      假设我有一个名为 BaseView 的类,我将它放在一个名为 _baseView.js 的文件中。然后我在一个名为 homeView.js 的文件中有另一个名为 HomeView 的类。

      HomeView 继承 BaseView

      所以需要先加载_baseView.js。

      上面的 require cmets 行通过首先导入所有以 _ 开头的视图然后导入其余的视图来确保发生这种情况“注意:它不会多次导入同一个文件,这就是 require 与 include 所做的。 require 只会拉入一个文件并忽略以后对同一文件的调用。包含将拉入文件的次数与使用包含的次数一样多。

      所以我要做的是创建 1 个单独的类,称为“main.js”,然后在该类中放入所有 //=require cmets 以提取我的所有代码。

      然后在我的 gulp 任务中,我需要的唯一源脚本是 main.js,其余的由 gulp-include 处理。

      你仍然可以充分利用 ES6 的大部分功能,只是摆脱了使用 Import 和 Export 的需要。

      这是一个非常简单的 main.js

      "use strict";
      
      (function () {
          //=require views/_*.js
          //=require views/*.js
      })();
      

      这是一个简单的 gulp 4 任务:

      function demoScripts() {
          var ret = src([
                  path.join(paths.srcDemoJs, 'main.js')
              ])
              .pipe(include({
                  hardFail: true,
                  includePaths: [
                      paths.stage,
                      path.join(paths.srcDemoJs)
                  ]            
              }))
              .pipe(babel({
                  presets: ['@babel/env']
              }))
              .pipe(dest(paths.dstDemo));
              return ret;
      }
      
      exports.build = demoScripts;
      

      我的 gulpFile 使用 gulp4 和 es6,因为它是节点,设计时环境,不关心 es6 那里的东西,所以导出 gulp 任务就可以了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-07-03
        • 1970-01-01
        • 1970-01-01
        • 2020-03-15
        • 1970-01-01
        • 2020-02-12
        • 2021-02-13
        相关资源
        最近更新 更多