it-swarm.com.ru

Как использовать модули ECMAScript6 на веб-страницах

Я очень рад использованию функций ECMAScript 6 через Babeljs - в частности, я бы хотел начать делать мой код JavaScript более модульным, используя функцию новых модулей.

Вот что я написал до сих пор:

// 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));

Я понимаю, что я могу перенести этот код из ES6 в ES5 через babel в командной строке:

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

Но что мне нужно сделать, чтобы использовать этот код в моем HTML?

Например, как будет выглядеть этот файл index.html:

<!-- 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>

Спасибо

28
wmock

Без использования модулей: Если вы не используете модули (импорт/экспорт), вы можете просто перенести свой код в ES5 и включить эти файлы ES5 в ваш html . Пример:

// 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);

Перенести на es5: babel index.js > es5.js

В index.html включите <script src="es5.js"></script> Выведите на консоль следующее:

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

Использование модулей: Теперь, если вы используете модули (как в вашем случае с lib.js и main.js), после преобразования вашего кода в ES5 вы также должны связать их (из AMD/CommonJS/Modules в код, понятный вашему браузеру). ). Вы можете сделать это с различными системами сборки, такими как gulp , webpack , browserify и т.д. Я собираюсь использовать browserify в качестве примера здесь.

Скажем, моя структура папок выглядит так:

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

Я запускаю babel для переноса моих файлов /src в папку /compiled: babel src --out-dir compiled.

Теперь у меня есть код ES5 в скомпилированной папке. Я устанавливаю browserify в строке cmd, а затем упаковываю свой main.js (точка входа) в мою скомпилированную папку

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

Теперь у меня есть bundle.js, который выглядит так:

(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]);

Тогда в вашем index.html:

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

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

  </head>
  <body>

  </body>
</html>

Затем просто откройте свой index.html, и ваша консоль должна дать вам следующее:

 121           bundle.js:27
 5             bundle.js:28
23
trekforever

Я начал с того, что попробовал то же самое, но в итоге обнаружил, что Гулп действительно очень помог.

Следует помнить одну вещь: babel source.js > destination.js не заполняет новый синтаксис ES6. Ваш код сейчас не использует никаких операторов let, деструктурированного присваивания, функций генератора или чего-либо подобного; но если вы добавите это на более позднем этапе, вам понадобится более сложное преобразование.

Вот ответ, который объясняет, как настроить файл gulp: Использование модуля экспорта Javascript 6to5 (теперь Babel) (Отказ от ответственности: Это один из моих ответов: P)

Вот шаги, специфичные для вашего случая:

  1. Создайте файл с именем gulpfile.js в вашем каталоге со следующим:
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. Запустите npm install gulp browserify babel babelify gulp-util vinyl-buffer vinyl-source-stream gulp-uglify gulp-sourcemaps, чтобы установить необходимые зависимости.
  2. Запустите gulp, чтобы собрать все вместе.
  3. Используйте связанный скрипт в вашем HTML с этим элементом: <script src="app.js"></script>

В дополнение к добавляемым полифиллам, приятно то, что код минимизирован, и вы получаете исходные карты, что означает, что даже в инструментах разработчика вы можете отлаживать сам код ES6.


Примечание: Хотя используемый вами оператор импорта корректен в соответствии с черновой спецификацией ES6, Babel это не понравится. Вам нужно будет добавить ./, чтобы он выглядел примерно так:

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

Я подозреваю, что это потому, что преобразование происходит в Node.js, и это отличает файл от модуля узла. В качестве побочного момента вы можете написать ES6 для узла do с инструкциями import :)

2
Andrew Odri

[Примечание: я понимаю, что мой ответ плохой, так как он не полностью отражает намерение спрашивающих использовать модули ES6 через babeljs в рабочем процессе внешнего интерфейса . Сохранение ответа для те, которые хотят использовать модули ES6 на веб-странице]

Попробуйте использовать jspm.io для загрузки модулей ES6 в браузере без предварительной загрузки с помощью babel . Можно найти плункер здесь

jspm работает поверх system.js , который пытается быть загрузчиком для любого формата модуля (ES6, AMD, CommonJS).

Чтобы заставить это работать в моем браузере, я основывался на этой демонстрации jspm ES6 . Просто скопируйте System.js и es6-module-loader.js в папку js/lib и скопируйте файлы es6 js в папку js. Тогда HTML выглядит так: 

<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>

Можно найти плунжера здесь

2
AardVark71

Будет ли один из ключей --modules компилироваться в JS, который может быть непосредственно включен в веб-страницу так же, как флаг --script будет компилироваться в браузер JS (--script не может использоваться с модулями)? См. https://github.com/google/traceur-compiler/wiki/Options-for-Compiling

0
user5321531