SyntaxError: "import" и "export" могут появляться только с "sourceType: module" - подождите что?
Итак, рассмотрим следующие два файла:
app.js
import Game from './game/game';
import React from 'react';
import ReactDOM from 'react-dom';
export default (absPath) => {
let gameElement = document.getElementById("container");
if (gameElement !== null) {
ReactDOM.render(
<Game mainPath={absPath} />,
gameElement
);
}
}
index.js
import App from './src/app';
gulpfile.js
var gulp = require('gulp');
var source = require('vinyl-source-stream');
var browserify = require('browserify');
var babelify = require("babelify");
var watch = require('gulp-watch');
gulp.task('make:game', function(){
return browserify({
entries: [
'index.js'
]
})
.transform('babelify')
.bundle()
.pipe(source('index.js'))
.pipe(gulp.dest('app/'));
});
Ошибка:
gulp make:game
[13:09:48] Using gulpfile ~/Documents/ice-cream/gulpfile.js
[13:09:48] Starting 'make:game'...
events.js:154
throw er; // Unhandled 'error' event
^
SyntaxError: 'import' and 'export' may appear only with 'sourceType: module'
Извините, что? Что это за ошибка? Что я делаю неправильно?
12 ответов
Старые версии Babel поставлялись со всем из коробки. Более новая версия требует, чтобы вы установили те плагины, которые нужны вашей установке. Во-первых, вам нужно установить предустановку ES2015.
npm install babel-preset-es2015 --save-dev
Далее вам нужно указать babelify, чтобы использовать установленный вами пресет.
return browserify({ ... })
.transform(babelify.configure({
presets: ["es2015"]
}))
...
ESLint изначально не поддерживает это, потому что это противоречит спецификации. Но если вы используете анализатор babel-eslint, то внутри вашего конфигурационного файла eslint вы можете сделать это:
{
"parser": "babel-eslint",
"parserOptions": {
"sourceType": "module",
"allowImportExportEverywhere": true
}
}
Ссылка на документ: https://github.com/babel/babel-eslint
Ответ отсюда: игнорировать ошибку eslint: "import" и "export" могут появляться только на верхнем уровне
Я столкнулся с той же ошибкой при попытке импортировать модуль из node_modules
который экспортируется в стиле ES6. Ничего из того, что было предложено на SO, не сработало для меня. Затем я нашел раздел часто задаваемых вопросов о репозитории babelify. Согласно инсайту оттуда, ошибка появляется, поскольку модули изnode_modules
не передаются по умолчанию, а объявления ES6, такие как export default ModuleName
в них не понимаются узлы, работающие на модулях в стиле Common.js.
Итак, я обновил свои пакеты, а затем использовал global
возможность запустить babelify как глобальное преобразование, исключая все модули узлов, кроме того, который меня интересовал, как указано на странице репозитория babelify:
...
browserify.transform("babelify",
{
presets: ["@babel/preset-env"],
sourceMaps: true,
global: true,
ignore: [/\/node_modules\/(?!your module folder\/)/]
}).bundle()
...
Надеюсь, это поможет.
По какой-то причине babelify 8.0.0 не работает для меня ни с подарками es2015, ни с env. Однако по состоянию на 2018-07-10 esmify
Плагин от Mattdesl работал на меня. Мой тестовый случай был экспорт Spinner
от spin.js
как окно глобальное. Мой пример репо здесь; ключевые детали следуют.
main.js
import {Spinner} from 'spin.js';
window.Spinner = Spinner;
Тестовое задание
В пустой директории:
npm init
и принять все значения по умолчанию, затем:
npm install --save spin.js
npm install --save-dev browserify esmify
npx browserify -p esmify main.js -o main-packed.js
Тестовый файл HTML
<html><head>
<link rel="stylesheet" href="node_modules/spin.js/spin.css" />
<script src="main-packed.js"></script> <!-- <== the browserify output -->
</head>
<body>
<div id="x"></div>
<script>
var target = document.getElementById('x');
var spin = new Spinner().spin(target);
</script>
</body></html>
При загрузке в центре страницы отображается счетчик.
Примечание: я не связан с mattdesl или esmify.
В .eslintrc вам может потребоваться указать параметры парсера, например:
{
"rules": {
"indent": [
2,
4
],
"linebreak-style": [
2,
"unix"
],
"semi": [
2,
"always"
]
},
"env": {
"es6": true,
"browser": true,
"node": true,
"mocha": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
}
}
Пожалуйста, ознакомьтесь с руководством по документации от Eslint.
Для корректной компиляции кода es2015-response вам необходимо установить несколько узловых модулей:
глобально
- npm install -g browserify
в каталоге вашего приложения:
- npm установить browserify --save
- npm установить babelify --save
- npm установить babel-preset-es2015 - сохранить
- npm установить babel-preset-stage-0 - сохранить
npm install babel-preset-реакции --save Затем создайте задание gulp:
var browserify = require ("browserify"); var babelify = require ("babelify");
gulp.task('es6-compile', function() { browserify({ debug: true }) .transform(babelify.configure({ presets: ["es2015","react", "stage-0"] })) .require("./public/src/javascripts/app.js", { entry: true }) .bundle() .pipe(gulp.dest('./public/dest/javascripts')); });
В каталоге./public/dest/javascripts вы найдете скомпилированный файл es5 app.js.
Если вы хотите использовать что-нибудь import
или require
метод в npm на стороне клиента просто выполните следующие шаги
- Пробег
npm install browserify babelify @babel/preset-env @babel/preset-react @babel/core es2015 --save-dev
установить необходимые пресеты - Добавьте этот код в свой
package.json
"babel": {
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
- Создайте файл с именем
dom_front.js
Внутри/app
папку файл, который вы хотите преобразовать как клиентский js.
const ReactDOM = require('react-dom')
import React, {Component} from 'react'
export {Component,React,ReactDOM};
Это смешанные данные экспорта модулей и требуемых файлов.
Примечание: не забудьте установить react-dom & react
- Использование browserify api - создайте файл js, такой как browserifyload.js и папку с ресурсами
const browserify = require("browserify")
const fs = require('fs')
browserify("./dom_front.js", {
debug : true,
standalone: "util"
}).transform(['babelify', { compact: false }], {
global: true,
ignore: [/\/node_modules\/(?!@vizuaalog\/)/],
presets: [
"@babel/preset-env",
"@babel/preset-react"]
}).bundle().on('error', function (err) {
console.log(err);
}).pipe(fs.createWriteStream('assets/mynpmmodule.js')).on('end', function(){
console.log( 'finished writing the browserify file' );
});
- Теперь структура папок
app
--dom_front.js
--browserifyload.js
--assets(folder)
- Пробег
/node_proj/app$ node browserifyload.js
или беги/node_proj/app$ browserify dom_front.js --transform babelify --standalone util > ./assets/mynpmmodule.js
- Проверьте папку с ресурсами, где теперь создается файл с именем
mynpmmodule.js
- Добавьте этот файл в свой HTML
<script src="assets/mynpmmodule.js"></script>
- Теперь вы можете использовать экспортированные модули / классы npm или необходимые файлы, используя автономный ключ, упомянутый выше.
util
нравиться
<script>
const Component = util.Component;
console.log(Component);
const ReactDOM = util.ReactDOM;
</script>
return browserify(jsConfig.src)
.transform(babelify.configure({
presets: ["@babel/preset-env"]
}))
.bundle()
.on('error', function (e) {
console.log(e.message);
this.emit('end');
})
Работает на меня.
Я попробовал все ответы выше, ни один из них не работал у меня, я даже пытался использовать синтаксис gulp-include / require, они не были ни решением, ни достаточным для моих требований.
Вот мое требование.
- Объедините все модули / файлы в один
- Сохраняйте все комментарии /JSDocs
- Храните все типы (например,
const example = (parameter: string) => {}
) - Использовать синтаксис импорта / экспорта
Причина перечисленных требований заключается в том, что нам нужен репозиторий для хранения наших общих функций, общих конфигураций, общих типов и общих констант в виде пакета npm (установка с URL-адресом). В этом случае мы уже знаем, что все наши проекты используют TypeScript, поэтому нет необходимости компилировать наш общий модуль в.js
, и нам также необходимо сохранить все описания, как это делают другие пакеты (действительно помогают JSDoc и Type).
Пока лучшее, что я могу сделать, это использовать browserify
с участием tsify
. Я случайно нашел обходной путь от сюда.
browserify()
.plugin(tsify, { target: 'es6' })
.transform(babelify, { extensions: [ '.tsx', '.ts' ] })
Я все еще ищу способ сохранить наши встроенные типы и комментарии /JSDocs, но я считаю, что этого достаточно для ваших нужд.
Запретите всем, кто дергает себя за волосы, пытаясь заставить машинописный текст работать в Babelify. Как оказалось,'import' and 'export' may appear only with 'sourceType: module'
ошибка также имеет место, если вы не добавили.ts
к расширениям опций Babelify. Обратите внимание, что вам, возможно, придется указатьextensions
как в браузера , так и в Babelify :параметрах параметрах
...
const babelify = require('babelify');
var appBundler = browserify({
entries: ["./index.ts"],
debug: true,
extensions: [".js", ".jsx", ".ts", ".tsx"],
})
.transform(babelify.configure({
"presets": [
"@babel/preset-env",
"@babel/preset-react",
["@babel/preset-typescript", { isTSX: true, allExtensions: true }],
],
extensions: [".js", ".jsx", ".ts", ".tsx"], // <============= fix here
}))
.bundle()
.pipe(source("index.js"))
.pipe(gulp.dest('app/'));
Эта ошибка может быть вызвана отсутствием подключаемого модуля tsify для компиляции машинописи в задаче gulp.
пример
var tsify = require('tsify');
return browserify({ ... })
.plugin(tsify)
.transform(babelify.configure({
presets: ["es2015"]
}))
...
Смотрите установку и использование здесь: https://www.npmjs.com/package/tsify
В моем случае я использовал экспорт вместо экспорта.
изменить экспорт на экспорт.