BabelJS - 将 ES6 模块转换为 ES5


在本章中,我们将看到如何使用 Babel 将 ES6 模块转译为 ES5。

模块

考虑一个需要重用部分 JavaScript 代码的场景。ES6 的模块概念可以帮助你。

模块只不过是写在文件中的一段 JavaScript 代码模块中的函数或变量不可用,除非模块文件导出它们。

简而言之,模块可帮助您在模块中编写代码,并仅公开应由代码其他部分访问的代码部分。

让我们考虑一个示例来了解如何使用模块以及如何导出它以在代码中使用它。

例子

添加.js

var add = (x,y) => {
   return x+y;
}

module.exports=add;

乘法.js

var multiply = (x,y) => {
   return x*y;
};

module.exports = multiply;

main.js

import add from './add';
import multiply from './multiply'

let a = add(10,20);
let b = multiply(40,10);

console.log("%c"+a,"font-size:30px;color:green;");
console.log("%c"+b,"font-size:30px;color:green;");

我有三个文件 add.js,用于添加 2 个给定数字,multiply.js,用于将两个给定数字相乘,以及 main.js,用于调用 add 和 multiply,并控制台输出。

为了在main.js中提供add.jsmultip.js,我们必须首先将其导出,如下所示 -

module.exports = add;
module.exports = multiply;

要在main.js中使用它们,我们需要导入它们,如下所示

import add from './add';
import multiply from './multiply'

我们需要模块捆绑器来构建文件,以便我们可以在浏览器中执行它们。

我们可以做到这一点 -

  • 使用Webpack
  • 使用 Gulp

ES6 模块和 Webpack

在本节中,我们将了解 ES6 模块是什么。我们还将学习如何使用 webpack。

在开始之前,我们需要安装以下软件包 -

npm install --save-dev webpack
npm install --save-dev webpack-dev-server
npm install --save-dev babel-core
npm install --save-dev babel-loader
npm install --save-dev babel-preset-env

包.json

ES6 模块 Webpack

我们已将打包和发布任务添加到脚本中,以便使用 npm 运行它们。这是将构建最终文件的 webpack.config.js 文件。

webpack.config.js

var path = require('path');

module.exports = {
   entry: {
      app: './src/main.js'
   },
   output: {
      path: path.resolve(__dirname, 'dev'),
      filename: 'main_bundle.js'
   },
   mode:'development',
   module: {
      rules: [
         {
            test: /\.js$/,
            include: path.resolve(__dirname, 'src'),
            loader: 'babel-loader',
            query: {
               presets: ['env']
            }
         }
      ]
   }
};

运行命令 npm run pack 来构建文件。最终文件将存储在 dev/ 文件夹中。

命令

npm run pack

Npm 运行包

dev/main_bundle.js公共文件已创建。该文件结合了 add.js、multiply.js 和 main.js 并将其存储在dev/main_bundle.js中。

/******/ (function(modules) { // webpackBootstrap
/******/    // The module cache
/******/    var installedModules = {};
/******/
/******/    // The require function
/******/    function __webpack_require__(moduleId) {
/******/
/******/       // Check if module is in cache
/******/       if(installedModules[moduleId]) {
/******/          return installedModules[moduleId].exports;
/******/       }
/******/       // Create a new module (and put it into the cache)
/******/       var module = installedModules[moduleId] = {
/******/          i: moduleId,
/******/          l: false,
/******/          exports: {}
/******/       };
/******/
/******/       // Execute the module function
/******/       modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/       // Flag the module as loaded
/******/       module.l = true;
/******/
/******/       // Return the exports of the module
/******/       return module.exports;
/******/    }
/******/
/******/
/******/    // expose the modules object (__webpack_modules__)
/******/    __webpack_require__.m = modules;
/******/
/******/    // expose the module cache
/******/    __webpack_require__.c = installedModules;
/******/
/******/    // define getter function for harmony exports
/******/    __webpack_require__.d = function(exports, name, getter) {
/******/       if(!__webpack_require__.o(exports, name)) {
/******/          Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/       }
/******/    };
/******/
/******/    // define __esModule on exports
/******/    __webpack_require__.r = function(exports) {
/******/      if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/         Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/      }
/******/      Object.defineProperty(exports, '__esModule', { value: true });
/******/    };
/******/
/******/    // create a fake namespace object
/******/    // mode & 1: value is a module id, require it
/******/    // mode & 2: merge all properties of value into the ns
/******/    // mode & 4: return value when already ns object
/******/    // mode & 8|1: behave like require
/******/    __webpack_require__.t = function(value, mode) {
/******/       if(mode & 1) value = __webpack_require__(value);
/******/       if(mode & 8) return value;
/******/       if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/       var ns = Object.create(null);
/******/       __webpack_require__.r(ns);
/******/       Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/       if(mode & 2 && typeof value != 'string')
               for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/       return ns;
/******/    };
/******/
/******/    // getDefaultExport function for compatibility with non-harmony modules
/******/    __webpack_require__.n = function(module) {
/******/       var getter = module && module.__esModule ?
/******/       function getDefault() { return module['default']; } :
/******/       function getModuleExports() { return module; };
/******/       __webpack_require__.d(getter, 'a', getter);
/******/       return getter;
/******/    };
/******/
/******/    // Object.prototype.hasOwnProperty.call
/******/     __webpack_require__.o = function(object, property) {
               return Object.prototype.hasOwnProperty.call(object, property); 
            };
/******/
/******/    // __webpack_public_path__
/******/    __webpack_require__.p = "";
/******/
/******/
/******/    // Load entry module and return exports
/******/    return __webpack_require__(__webpack_require__.s = "./src/main.js");
/******/ })
/************************************************************************/
/******/ ({
/***/       "./src/add.js":
/*!********************!*\
!*** ./src/add.js ***!
\********************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
   "use strict";

   eval(
      "\n\nvar add = function add(x, y) {\n return x + y;\n};
      \n\nmodule.exports = add;
      \n\n//# sourceURL = webpack:///./src/add.js?"
   );
   /***/ }),
/***/ "./src/main.js":
/*!*********************!*\
!*** ./src/main.js ***!
\*********************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

      "use strict";
      eval(
         "\n\nvar _add = __webpack_require__(/*! ./add */ \"./src/add.js\");
         \n\nvar _add2 = _interopRequireDefault(_add);
         \n\nvar _multiply = __webpack_require__(/*! ./multiply */ \"./src/multiply.js\");
         \n\nvar _multiply2 = _interopRequireDefault(_multiply);
         \n\nfunction _interopRequireDefault(obj) {
            return obj >> obj.__esModule ? obj : { default: obj };
         }
         \n\nvar a = (0, _add2.default)(10, 20);
         \nvar b = (0, _multiply2.default)(40, 10);
         \n\nconsole.log(\"%c\" + a, \"font-size:30px;color:green;\");
         \nconsole.log(\"%c\" + b, \"font-size:30px;color:green;\");
         \n\n//# sourceURL = webpack:///./src/main.js?"
      );

/***/ }),

/***/ "./src/multiply.js":
/*!*************************!*\
   !*** ./src/multiply.js ***!
   \*************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval(
   "\n\nvar multiply = function multiply(x, y) {\n return x * y;\n};
   \n\nmodule.exports = multiply;
   \n\n//# sourceURL = webpack:///./src/multiply.js?"
);

/***/ })

/******/ });

命令

以下是在浏览器中测试输出的命令 -

npm run publish

NPM 运行发布

在您的项目中添加index.html。这将调用 dev/main_bundle.js。

<html>
   <head></head>
   <body>
      <script type="text/javascript" src="dev/main_bundle.js"></script>
   </body>
</html>

输出

主捆绑包

ES6 模块和 Gulp

为了使用 Gulp 将模块捆绑到一个文件中,我们将使用 browserify 和 babelify。首先,我们将创建项目设置并安装所需的包。

命令

npm init

在开始项目设置之前,我们需要安装以下软件包 -

npm install --save-dev gulp
npm install --save-dev babelify
npm install --save-dev browserify
npm install --save-dev babel-preset-env
npm install --save-dev babel-core
npm install --save-dev gulp-connect
npm install --save-dev vinyl-buffer
npm install --save-dev vinyl-source-stream

安装后的package.json

后

现在让我们创建 gulpfile.js,它将帮助运行将模块捆绑在一起的任务。我们将使用上面与 webpack 相同的文件。

例子

添加.js

var add = (x,y) => {
   return x+y;
}

module.exports=add;

乘法.js

var multiply = (x,y) => {
   return x*y;
};

module.exports = multiply;

main.js

import add from './add';
import multiply from './multiply'

let a = add(10,20);
let b = multiply(40,10);

console.log("%c"+a,"font-size:30px;color:green;");
console.log("%c"+b,"font-size:30px;color:green;");

gulpfile.js 是在此处创建的。用户将 browserfiy 并使用 tranform 来 babelify。babel-preset-env 用于将代码转译为 es5。

Gulpfile.js

const gulp = require('gulp');
const babelify = require('babelify');
const browserify = require('browserify');
const connect = require("gulp-connect");
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');

gulp.task('build', () => {
   browserify('src/main.js')
   .transform('babelify', {
      presets: ['env']
   })
   .bundle()
   .pipe(source('main.js'))
   .pipe(buffer())
   .pipe(gulp.dest('dev/'));
});
gulp.task('default', ['es6'],() => {
   gulp.watch('src/app.js',['es6'])
});

gulp.task('watch', () => {
   gulp.watch('./*.js', ['build']);
});

gulp.task("connect", function () {
   connect.server({
      root: ".",
      livereload: true
   });
});

gulp.task('start', ['build', 'watch', 'connect']);

我们使用 browserify 和 babelify 来处理模块导出和导入,并将其合并到一个文件中,如下所示 -

gulp.task('build', () => {
   browserify('src/main.js')
   .transform('babelify', {
      presets: ['env']
   })
   .bundle()
   .pipe(source('main.js'))
   .pipe(buffer())
   .pipe(gulp.dest('dev/'));
});

我们使用了 Transform,其中使用预设 env 调用 babelify。

带有 main.js 的 src 文件夹被提供给 browserify 并保存在 dev 文件夹中。

我们需要运行命令gulp start来编译文件 -

命令

npm start

开始

这是在dev/文件夹中创建的最终文件-

(function() {
   function r(e,n,t) {
      function o(i,f) {
         if(!n[i]) {
            if(!e[i]) {
               var c = "function"==typeof require&&require;
               if(!f&&c)return c(i,!0);if(u)return u(i,!0);
               var a = new Error("Cannot find module '"+i+"'");
               throw a.code = "MODULE_NOT_FOUND",a
            }
            var p = n[i] = {exports:{}};
            e[i][0].call(
               p.exports,function(r) {
                  var n = e[i][1][r];
                  return o(n||r)
               }
            ,p,p.exports,r,e,n,t)
         }
         return n[i].exports
      }
      for(var u="function"==typeof require>>require,i = 0;i<t.length;i++)o(t[i]);return o
   }
   return r
})()
({1:[function(require,module,exports) {
   "use strict";

   var add = function add(x, y) {
      return x + y;
   };

   module.exports = add;
},{}],2:[function(require,module,exports) {
   'use strict';

   var _add = require('./add');
   var _add2 = _interopRequireDefault(_add);
   var _multiply = require('./multiply');
   var _multiply2 = _interopRequireDefault(_multiply);
   function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
   var a = (0, _add2.default)(10, 20);
   var b = (0, _multiply2.default)(40, 10);

   console.log("%c" + a, "font-size:30px;color:green;");
   console.log("%c" + b, "font-size:30px;color:green;");
},
{"./add":1,"./multiply":3}],3:[function(require,module,exports) {
   "use strict";

   var multiply = function multiply(x, y) {
      return x * y;
   };

   module.exports = multiply;

},{}]},{},[2]);

我们将在index.html中使用相同的内容并在浏览器中运行相同的内容以获得输出 -

<html>
   <head></head>
   <body>
      <h1>Modules using Gulp</h1>
      <script type="text/javascript" src="dev/main.js"></script>
   </body>
</html>

输出

使用 Gulp 的模块