Cómo usar módulos ECMAScript6 dentro de páginas web


Estoy muy entusiasmado con el uso de las características de ECMAScript 6 ahora a través de Babeljs - en particular, me encantaría comenzar a hacer que mi código JavaScript sea más modular utilizando la nueva función de módulos.

Esto es lo que he escrito hasta ahora:

// ECMAScript 6 code - lib.js
export const sqrt = Math.sqrt;
export function square (x) {
  return x * x;
}

export function diag (x, y) {
  return sqrt(square(x) + square(y));
}

// ECMAScript 6 code - main.js
import { square, diag } from 'lib';
console.log(square(11));
console.log(diag(4, 3));

Entiendo que puedo transpilar este código de ES6 a ES5 a través de babel en la línea de comandos:

babel lib.js > lib6to5.js
babel main.js > main6to5.js

Pero, ¿qué necesito hacer para usar este código dentro de mi HTML?

Por ejemplo, lo que sería este índice.aspecto del archivo html como:

<!-- index.html -->
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>ECMAScript 6</title>

    <!-- What goes here? 
     How do I include main6to5.js and lib6to5.js to make this work in the browser? -->
    <script src="?????"></script>

  </head>
  <body>

  </body>
</html>

Gracias

Author: Andrew Odri, 2015-02-27

4 answers

Sin utilizar módulos: Si no está utilizando módulos (importaciones / exportaciones), entonces simplemente puede transpilar su código en ES5 e incluir esos archivos ES5 en su html. Ejemplo:

// ES6 - index.js
// arrow function
var result = [1, 2, 3].map(n => n * 2);
console.log(result);

// enhanced object literal
var project = "helloWorld";
var obj = {
    // Shorthand for ‘project: project’
    project,
    // Methods
    printProject() {
     console.log(this.project);
    },
    [ "prop_" + (() => 42)() ]: 42
};
console.log(obj.printProject());
console.log(obj);

Transpile a es5: babel index.js > es5.js

En index.html, incluya <script src="es5.js"></script> Imprimirá lo siguiente en la consola:

[2,4,6]
helloWorld
{"project":"helloWorld","prop_42":42}

Uso de módulos: Ahora, si está utilizando módulos (que es su caso con lib.js y main.js), después de convertir su código en ES5 también tiene que agruparlos (desde AMD / CommonJS / Modules hasta código que tu navegador pueda entender). Usted puede hacer esto con varios sistemas de construcción como gulp, webpack, browserify, etc. Voy a usar browserify como un ejemplo aquí.

Digamos que mi estructura de carpetas se ve así:

es6
|- src
  |- lib.js
  |- main.js
|- compiled
|- index.html

Corro babel para transpilar mis archivos /src a la carpeta /compiled: babel src --out-dir compiled.

Ahora tengo mi código ES5 en la carpeta compilada. Instalo browserify en la línea cmd y luego agrupo mi principal.js (punto de entrada) en mi carpeta compilada

~/es6 » npm install --global browserify
~/es6 » browserify ./compiled/main.js -o ./bundle.js

Ahora tengo bundle.js que se ve así:

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

exports.square = square;
exports.diag = diag;
var sqrt = exports.sqrt = Math.sqrt;

function square(x) {
    return x * x;
}

function diag(x, y) {
    return sqrt(square(x) + square(y));
}

Object.defineProperty(exports, "__esModule", {
    value: true
});
},{}],2:[function(require,module,exports){
"use strict";

var _lib = require("./lib");

var square = _lib.square;
var diag = _lib.diag;

console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
},{"./lib":1}]},{},[2]);

Entonces en su índice.html:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>ECMAScript 6</title>

    <script src="./bundle.js"></script>

  </head>
  <body>

  </body>
</html>

Entonces simplemente abre tu index.html, y tu consola debería darte lo siguiente:

 121           bundle.js:27
 5             bundle.js:28
 23
Author: trekforever,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-03 09:12:31

Comencé probando lo mismo, pero finalmente descubrí que Gulp realmente ayudó mucho.

Una cosa a tener en cuenta: babel source.js > destination.js no rellenará la nueva sintaxis de ES6 . Su código en este momento no está usando ninguna instrucción let, asignación desestructurada, funciones de generador ni nada por el estilo; pero si agrega eso en una etapa posterior, necesitará una transformación más sofisticada.

Aquí hay una respuesta que explica cómo configurar el archivo gulp: Javascript 6to5 (ahora Babel) uso del módulo de exportación (Descargo de responsabilidad: Es una de mis respuestas: P)

Estos son los pasos específicos de su caso:

  1. Crea un archivo llamado gulpfile.js en tu directorio con lo siguiente:
var gulp = require('gulp');
var browserify = require('browserify');
var babelify= require('babelify');
var util = require('gulp-util');
var buffer = require('vinyl-buffer');
var source = require('vinyl-source-stream');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');

gulp.task('build', function() {
  browserify(['./lib.js', './main.js'], { debug: true })
  .add(require.resolve('babel/polyfill'))
  .transform(babelify)
  .bundle()
  .on('error', util.log.bind(util, 'Browserify Error'))
  .pipe(source('app.js'))
  .pipe(buffer())
  .pipe(sourcemaps.init({loadMaps: true}))
  .pipe(uglify({ mangle: false }))
  .pipe(sourcemaps.write('./'))
  .pipe(gulp.dest('./'));
});

gulp.task('default', ['build']);
  1. Ejecute npm install gulp browserify babel babelify gulp-util vinyl-buffer vinyl-source-stream gulp-uglify gulp-sourcemaps para instalar las dependencias necesarias.
  2. Ejecuta gulp para agrupar todo.
  3. Use el script incluido en su HTML con este elemento: <script src="app.js"></script>

Lo bueno además de ser polyfills añadido es que el código está minificado, y obtiene sourcemaps, lo que significa que incluso en sus herramientas de desarrollador, puede depurar el código ES6 en sí.


Nota: Si bien la instrucción import que está utilizando es correcta de acuerdo con la especificación del borrador de ES6, a Babel no le gustará. Necesitará agregar un ./, para que se vea algo como esto:

import { square, diag } from './lib';

Sospecho que esto se debe a que la transformación ocurre en el nodo.js, y esto diferencia un archivo de un módulo de nodo. Como punto lateral, puede escribir ES6 para el nodo do requiere con instrucciones de importación:)

 2
Author: Andrew Odri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:29:24

[Nota: Me doy cuenta de que mi respuesta es pobre, ya que no refleja completamente los interrogadores tienen la intención de utilizar módulos ES6 a través de babeljs en un flujo de trabajo front-end. Mantener la respuesta para aquellos que quieran usar módulos ES6 dentro de una página web]

Intenta usar jspm.io para cargar los módulos ES6 en el navegador sin transpilar por adelantado con babel. Un émbolo se puede encontrar aquí

Jspm funciona encima del sistema .js que intenta ser un cargador para cualquier formato de módulo (ES6, AMD, CommonJS)..

Para hacer que esto funcione en mi navegador, me basé en esta demo de jspm ES6. Simplemente copiado Sistema.js y es6-module-loader.js en una carpeta js/lib y copió sus archivos es6 js en la carpeta js. Entonces el html se ve así:

<html>
    <body>
        Test .. just open up the Chrome Devtools console to see the ES6 modules output using jspm
        <script src="js/lib/system.js"></script>
        <script>System.import("main");</script> </body>
</html>

Se puede encontrar un émbolo aquí

 2
Author: AardVark71,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-07 08:10:41

¿Compilaría uno de los conmutadores --modules en JS que se puede incluir directamente en una página web de la misma manera que el indicador --script compilará en el navegador JS (--script no se puede usar con módulos)? Véase https://github.com/google/traceur-compiler/wiki/Options-for-Compiling

 0
Author: user5321531,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-06 10:18:31