Нужно ли мне использовать js, когда я использую babel?

Im экспериментирует с ES6, а Im использует gulp для сборки и babel для перехода на ES5. Вывод не выполняется в node, просто связан с файлом .htm с тегом. Я думаю, что мне нужно добавить

<script src='require.js'></script>

или что-то в этом роде.

Im пытается импортировать/экспортировать.

////////////////scripts.js
import {Circle} from 'shapes';

c = new Circle(4);

console.log(c.area());


/////////////////shapes.js
export class Circle {

    circle(radius) {
        this.radius = radius;
    }

    area() {
        return this.radius * this.radius * Math.PI;
    } 

}

Ошибка

Uncaught ReferenceError: require is not defined

Относится к этому (после .pipe(babel()) в gulp)

var _shapes = require('shapes');

Ответ 1

Нужно ли мне использовать js при использовании babel?

Вам может понадобиться некоторый загрузчик модулей, но это необязательно RequireJS. У вас есть несколько вариантов. Следующее поможет вам начать работу.


rollup.js с rollup-plugin-babel

Накопитель - это блок-модуль JavaScript следующего поколения. Он понимает модули ES2015 изначально и создает пакет, для которого не требуется какой-либо загрузчик модулей. Неиспользованный экспорт будет отделен от результата, он называется дрожанием дерева.

Теперь я лично рекомендую использовать rollupjs, поскольку он дает самый четкий вывод и его легко настроить, однако он дает другой аспект ответа. Все остальные подходы делают следующее:

  • Скомпилируйте код ES6 с помощью babel, используйте формат модуля по вашему выбору.
  • Объединение скомпилированных модулей вместе с загрузчиком модулей ИЛИ использование связующего, которое будет пересекать ваши зависимости.

С rollupjs вещи действительно не работают таким образом. Здесь rollup - это первый шаг, а не babel. По умолчанию он понимает модули ES6. Вы должны предоставить модуль ввода, в котором будут проходить и контатетировать зависимости. Поскольку ES6 допускает множественный экспорт по имени в модуль, rollupjs достаточно умен, чтобы лишить неиспользуемый экспорт, тем самым уменьшая размер пакета. К сожалению, анализатор rollupjs-s не понимает > синтаксис ES6, поэтому модули ES7 должны быть скомпилированы до того, как rollup проанализирует их, но компиляция не должна влиять на импорт ES6. Это делается с помощью плагина rollup-plugin-babel с предустановкой babel-preset-es2015-rollup (этот пресет такой же, как у es2015, кроме модуля-трансформатора и плагина внешних помощников). Таким образом, при правильной настройке накопитель будет выполнять следующие действия с вашими модулями:

  • Считывает ваш модуль ES6-7 из файловой системы
  • Плагин babel скомпилирует его в ES6 в памяти
  • rollup анализирует код ES6 для импорта и экспорта (с использованием анализатора желудей, скомпилированного в накопительный файл).
  • он перемещает весь граф и создает единый пакет (который по-прежнему может иметь внешние зависимости, и экспорт записей может быть экспортирован в выбранном вами формате)

Пример nodejs build:

// setup by `npm i rollup rollup-plugin-babel babel-preset-es2015 babel-plugin-external-helpers --save-dev`

// build.js:
require("rollup").rollup({
  entry: "./src/main.js",
  plugins: [
    require("rollup-plugin-babel")({
      "presets": [["es2015", { "modules": false }]],
      "plugins": ["external-helpers"]
    })
  ]
}).then(bundle => {
  var result = bundle.generate({
    // output format - 'amd', 'cjs', 'es6', 'iife', 'umd'
    format: 'iife'
  });

  require("fs").writeFileSync("./dist/bundle.js", result.code);
  // sourceMaps are supported too!
}).then(null, err => console.error(err));

Пример сборки grunt с grunt-rollup

// setup by `npm i grunt grunt-rollup rollup-plugin-babel babel-preset-es2015 babel-plugin-external-helpers --save-dev`

// gruntfile.js
module.exports = function(grunt) {
  grunt.loadNpmTasks("grunt-rollup");
  grunt.initConfig({
    "rollup": {
      "options": {
        "format": "iife",
        "plugins": [
          require("rollup-plugin-babel")({
            "presets": [["es2015", { "modules": false }]],
            "plugins": ["external-helpers"]
          })
        ]
      },
      "dist": {
        "files": {
          "./dist/bundle.js": ["./src/main.js"]
        }
      }
    }
  });
}

Пример gulp build с gulp-rollup

// setup by `npm i gulp gulp-rollup rollup-plugin-babel babel-preset-es2015 babel-plugin-external-helpers --save-dev`

// gulpfile.js
var gulp       = require('gulp'),
    rollup     = require('gulp-rollup');

gulp.task('bundle', function() {
  gulp.src('./src/**/*.js')
    // transform the files here.
    .pipe(rollup({
      // any option supported by Rollup can be set here.
      "format": "iife",
      "plugins": [
        require("rollup-plugin-babel")({
          "presets": [["es2015", { "modules": false }]],
          "plugins": ["external-helpers"]
        })
      ],
      entry: './src/main.js'
    }))
    .pipe(gulp.dest('./dist'));
});

Babelify + Browserify

У Babel есть аккуратный пакет под названием Babelify. Это простое и понятное использование:

$ npm install --save-dev babelify babel-preset-es2015 babel-preset-react
$ npm install -g browserify
$ browserify src/script.js -o bundle.js \
  -t [ babelify --presets [ es2015 react ] ]

или вы можете использовать его из node.js:

$ npm install --save-dev browserify babelify babel-preset-es2015 babel-preset-react

...

var fs = require("fs");
var browserify = require("browserify");
browserify(["./src/script.js"])
  .transform("babelify", {presets: ["es2015", "react"]})
  .bundle()
  .pipe(fs.createWriteStream("bundle.js"));

Это будет передавать и объединять ваш код сразу. Browserify .bundle будет содержать красивый маленький загрузчик CommonJS и организует ваши преобразованные модули в функции. У вас даже есть относительный импорт.

Пример:

// project structure
.
+-- src/
|   +-- library/
|   |   \-- ModuleA.js
|   +-- config.js
|   \-- script.js
+-- dist/
\-- build.js
...

// build.js
var fs = require("fs");
var browserify = require("browserify");
browserify(["./src/script.js"])
  .transform("babelify", {presets: ["es2015", "react"]})
  .bundle()
  .pipe(fs.createWriteStream("dist/bundle.js"));

// config.js
export default "Some config";

// ModuleA.js
import config from '../config';
export default "Some nice export: " + config;

// script.js
import ModuleA from './library/ModuleA';
console.log(ModuleA);

Для компиляции просто запустите node build.js в корне вашего проекта.


Babel + WebPack

Скомпилируйте весь свой код с помощью babel. Я рекомендую использовать модуль модуля amd (называемый babel-plugin-transform-es2015-modules-amd в babel 6). После этого скомпилируйте ваши скомпилированные источники с помощью WebPack.

WebPack 2 не работает! Он понимает родные модули ES6, и будет выполнять (или, скорее, имитировать) дрожание дерева используя babili - встроенное удаление мертвого кода. На данный момент (сентябрь 2016 года) я все же предлагаю использовать накопительный пакет с babel, хотя мое мнение может измениться с первого выпуска WebPack 2. Не стесняйтесь обсуждать свои мнения в комментариях.


Консоль пользовательской компиляции

Иногда вы хотите получить больше контроля над процессом компиляции. Вы можете реализовать свой собственный конвейер следующим образом:

Сначала вам нужно настроить babel для использования модулей amd. По умолчанию babel транслирует модули CommonJS, что немного сложно обрабатывать в браузере, хотя браузеру удается справиться с ними красиво.

  • Вавилон 5: используйте опцию { modules: 'amdStrict', ... }
  • Babel 6: используйте плагин es2015-modules-amd

Не забудьте включить параметр moduleIds: true.

Проверьте переданный код для сгенерированных имен модулей, часто возникают несоответствия между определенными и необходимыми модулями. См. sourceRoot и moduleRoot.

Наконец, у вас должен быть какой-то модуль-загрузчик, но он не является обязательным требованием. Существует almondjs, крошечный блок, который хорошо работает. Вы даже можете реализовать свои собственные:

var __modules = new Map();

function define(name, deps, factory) {
    __modules.set(name, { n: name, d: deps, e: null, f: factory });
}

function require(name) {
    const module = __modules.get(name);
    if (!module.e) {
        module.e = {};
        module.f.apply(null, module.d.map(req));
    }
    return module.e;

    function req(name) {
        return name === 'exports' ? module.e : require(name);
    }
}

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


Код шаблона Babel дублируется в каждом модуле

По умолчанию большинство вышеперечисленных методов объединяют каждый модуль с буфером в отдельности, а затем объединяют их вместе. То, что делает babelify, тоже. Но если вы посмотрите на скомпилированный код, вы увидите, что babel вставляет множество шаблонов в начале каждого файла, большинство из которых дублируется во всех файлах.

Чтобы предотвратить это, вы можете использовать плагин babel-plugin-transform-runtime.

Ответ 2

barebones webpack 2

1) Если это ваш корневой каталог:

index.html

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

scripts.js

import { Circle } from './shapes.js';
  ...

shapes.js

export class Circle {
  ...
}

2) установлены node node

3) запустите следующую команду в терминале:

$ npm install -g webpack

5) в корневом каталоге выполните следующее:

$ webpack scripts.js bundle.js

Теперь вы должны иметь файл с именем bundle.js в корневом каталоге, который будет являться файлом, который будет использовать ваш index.html. Это минималистическая функция связывания с webpack. Вы можете узнать больше здесь

Ответ 3

require не существует в браузере, поэтому ожидается такая ошибка. Вам нужно использовать что-то вроде require.js или Browserify.