Экспорт класса с ES6 (Babel)
Я пишу какой-то внешний код с ECMAScript 6 (транслируется с BabelJS, а затем браунируется с помощью Browserify), чтобы я мог иметь класс в одном файле, экспортировать его и импортировать в другой файл.
Как я делаю это:
export class Game {
constructor(settings) {
...
}
}
И затем в файле, который импортирует класс, который я делаю:
import {Game} from "../../lib/pentagine_browserified.js";
var myGame = new Game(settings);
Затем я скомпилирую его с помощью grunt
, это мой Gruntfile
:
module.exports = function(grunt) {
"use strict";
grunt.loadNpmTasks('grunt-babel');
grunt.loadNpmTasks('grunt-browserify');
grunt.initConfig({
"babel": {
options: {
sourceMap: false
},
dist: {
files: {
"lib/pentagine_babel.js": "lib/pentagine.js",
"demos/helicopter_game/PlayState_babel.js": "demos/helicopter_game/PlayState.js"
}
}
},
"browserify": {
dist: {
files: {
"lib/pentagine_browserified.js": "lib/pentagine_babel.js",
"demos/helicopter_game/PlayState_browserified.js": "demos/helicopter_game/PlayState_babel.js"
}
}
}
});
grunt.registerTask("default", ["babel", "browserify"]);
};
Однако при вызове new Game(
я получаю следующую ошибку:
Uncaught TypeError: undefined is not a function
Итак, что я делал, анализировал сгенерированный код Babel и Browserify, и я нашел эту строку на PlayState_browserified.js
:
var Game = require("../../lib/pentagine_browserified.js").Game;
Я решил распечатать вывод require
:
console.log(require("../../lib/pentagine_browserified.js"));
И это не что иное, как пустой объект. Я решил проверить файл pentagine_browserified.js
:
var Game = exports.Game = (function () {
Кажется, что он правильно экспортирует класс, но по какой-то другой причине он не требуется в другом файле.
Кроме того, я уверен, что файл требуется должным образом, потому что изменение строки "../../lib/pentagine_browserified.js"
выплевывает ошибку Not Found
, поэтому она подходит для правильного файла, о котором я уверен.
Ответы
Ответ 1
Browserify предназначен для подачи одного файла "точки входа", через который он рекурсивно пересекает все ваши операторы require
, импортируя код из других модулей. Таким образом, вы должны быть require
в версиях модулей _babel.js
, а не _browserified.js
.
По внешнему виду, вы намерены, чтобы ваше приложение "точка входа" было demos/helicopter_game/PlayState_browserified.js
, да? Если это случай:
- В PlayState.js измените его на
import {Game} from "../../lib/pentagine_babel.js";
.
- В Gruntfile.js удалите
"lib/pentagine_browserified.js": "lib/pentagine_babel.js"
.
Работает для меня. Дайте мне знать, если этого достаточно или я не понимаю ваши требования здесь.
P.S. Вы можете использовать babelify, чтобы избежать отдельных задач Grunt для Babel и Browserify. Для примера см. Мой ответ здесь.
Ответ 2
У меня была немного другая конфигурация файла, что затруднило работу синтаксиса "require" в Node, но этот пост дал мне подсказку о том, как использовать версию имени файла с именем babel-ified.
Я использую WebStorm с параметром FileWatcher, установленным в Babel, и у меня есть FileWatcher, настроенный на просмотр всех файлов с суффиксом .jsx и переименование скомпилированного выходного файла из {my_file}.jsx в {my_file} -compiled.js.
Итак, в моем тестовом случае у меня есть 2 файла:
Person.jsx:
class Person { ... }
export { Person as default}
и другой файл, который хочет его импортировать:
Test.jsx:
var Person = require('./Person-compiled.js');
Я не мог получить инструкцию require для того, чтобы найти модуль до тех пор, пока я не запустил путь к файлу с помощью "./", а также добавлю "-compiled.js", чтобы правильно указать имя файла, чтобы Node es5 мог найти модуль.
Я также смог использовать синтаксис "import":
import Person from './Person-compiled.js';
Поскольку я настроил проект WebStorm как проект Node ES5, мне нужно запустить "Test-compiled.js" (не "Test.jsx" ).