BabelJS - 将 ES6 模块转换为 ES5
在本章中,我们将了解如何使用 Babel 将 ES6 模块转换为 ES5。
模块
考虑这样一种情况,其中需要重用部分 JavaScript 代码。ES6 通过模块的概念来帮助您。
模块只不过是写在文件中的一段 JavaScript 代码。模块中的函数或变量不可供使用,除非模块文件导出它们。
简单地说,模块可帮助您在模块中编写代码,并仅公开代码中其他部分应访问的代码部分。
让我们考虑一个例子来了解如何使用模块以及如何导出它以在代码中使用它。
示例
add.js
var add = (x,y) => { return x+y; } module.exports=add;
multiply.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.js 和 multiply.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
Package.json
我们已将打包和发布任务添加到脚本中,以便使用 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
dev/main_bundle.js 公共文件已创建。此文件结合了 add.js、multiply.js 和 main.js,并将其存储在 dev/main_bundle.js 中。
/******/ (function(modules) { // webpackBootstrap /******/ // 模块缓存 /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // 检查模块是否在缓存中 /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // 创建一个新模块(并将其放入缓存中) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // 执行模块函数 /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // 将模块标记为已加载 /******/ module.l = true; /******/ /******/ // 返回模块的导出 /******/ return module.exports; /******/ } /******/ /******/ /******/ // 公开模块对象(__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // 公开模块缓存 /******/ __webpack_require__.c = installedModules; /******/ /******/ // 为 harmony 导出定义 getter 函数 /******/ __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 }); /******/ }; /******/ /******/ // 创建一个假的命名空间对象 /******/ // 模式 & 1:值是一个模块 ID,需要它 /******/ // 模式 & 2:将值的所有属性合并到 ns /******/ // 模式 & 4:当已经是 ns 对象时返回值 /******/ // 模式 & 8|1:表现得像需要 /******/ __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 函数用于兼容非 Harmony 模块 /******/ __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( " var add = function add(x, y) { return x + y; }; module.exports = add; //# sourceURL = webpack:///./src/add.js?" ); /***/ }), /***/ "./src/main.js": /*!*********************!*\ !*** ./src/main.js ***! \*********************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; eval( " var _add = __webpack_require__(/*! ./add */ \"./src/add.js\"); var _add2 = _interopRequireDefault(_add); var _multiply = __webpack_require__(/*! ./multiply */ \"./src/multiply.js\"); 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;\"); //# sourceURL = webpack:///./src/main.js?" ); /***/ }), /***/ "./src/multiply.js": /*!*************************!*\ !*** ./src/multiply.js ***! \*************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; eval( " var multiply = function multiply(x, y) { return x * y; }; module.exports = multiply; //# sourceURL = webpack:///./src/multiply.js?" ); /***/ }) /******/ });
命令
以下是在浏览器中测试输出的命令 −
npm run publish
在项目中添加 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 相同的文件。
示例
add.js
var add = (x,y) => { return x+y; } module.exports=add;
multiply.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 在此处创建。用户将浏览器化并使用转换进行 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,其中使用预设环境调用了 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>