<p>gatsby-node.js не разрешает импорт ES6</p>

Созданный на 2 сент. 2018  ·  39Комментарии  ·  Источник: gatsbyjs/gatsby

Описание

gatsby-node.js не поддерживает JavaScript для ES6.

Действия по воспроизведению

gatsby-node.js :

import myOnCreatePage from './gatsby/node/onCreatePage';
export const onCreatePage = myOnCreatePage;

Ожидаемый результат

gatsby-node.js должен быть передан и разрешить ES6 как gatsby-ssr.js или gatsby-browser.js .

Фактический результат

Ошибка

Error: <root>/gatsby-node.js:1
SyntaxError: Unexpected token import

Среда

  System:
    OS: macOS High Sierra 10.13.6
    CPU: x64 Intel(R) Core(TM) i7-6567U CPU @ 3.30GHz
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 8.10.0 - ~/.nvm/versions/node/v8.10.0/bin/node
    Yarn: 1.9.4 - /usr/local/bin/yarn
    npm: 6.4.1 - ~/.nvm/versions/node/v8.10.0/bin/npm
  Browsers:
    Chrome: 68.0.3440.106
    Firefox: 61.0.2
    Safari: 11.1.2
  npmPackages:
    gatsby: next => 2.0.0-rc.5 
    gatsby-source-filesystem: next => 2.0.1-rc.1 
  npmGlobalPackages:
    gatsby-cli: 1.1.58

Самый полезный комментарий

Я использую для этого esm, и он пока работает. Вот что я сделал:

  1. Установить esm ( npm i esm )
  2. Создайте файл с именем gatsby-node.esm.js в корневой папке (в той же папке, что и gatsby-node.js ).
  3. Переместите весь свой код из gatsby-node.js в gatsby-node.esm.js
  4. Замените весь код в gatsby-node.js следующим:
    javascript require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
  5. Используйте import в gatsby-node.esm.js сколько хотите 🎉

@KyleAMathews Есть что-нибудь опасное в том, чтобы делать это таким образом? Потому что, если это безопасно, я могу добавить его в документацию :)

Все 39 Комментарий

Этот файл запускается node.js, поэтому он поддерживает любую версию используемого вами узла. Поддержка модуля Es6 в узле по-прежнему отсутствует https://medium.com/@giltayar/native -es-modules-in-nodejs-status-and-future-направления-part-i-ee5ea3001f71

Я тоже сталкиваюсь с этим. Мне нужно использовать gatsby-mdx/mdx-renderer , и даже если я require it, сам требуемый файл использует синтаксис модуля ES6 и прерывается. Есть ли способ изменить конфигурацию, чтобы gatsby-node.js проходил через babel? Было бы здорово иметь возможность использовать JSX внутри него, хотя для меня это менее актуально.

Что нужно сделать, чтобы включить поддержку import / export в gatsby-node.js ? Сообщение Medium связано с упоминаниями с использованием файлов .mjs но я не думаю, что это сработает с Gatsby?

Есть ли способ использовать babel-node вместо node ?

Я использую для этого esm, и он пока работает. Вот что я сделал:

  1. Установить esm ( npm i esm )
  2. Создайте файл с именем gatsby-node.esm.js в корневой папке (в той же папке, что и gatsby-node.js ).
  3. Переместите весь свой код из gatsby-node.js в gatsby-node.esm.js
  4. Замените весь код в gatsby-node.js следующим:
    javascript require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
  5. Используйте import в gatsby-node.esm.js сколько хотите 🎉

@KyleAMathews Есть что-нибудь опасное в том, чтобы делать это таким образом? Потому что, если это безопасно, я могу добавить его в документацию :)

Этот шаблон определенно работает @nikoladev! Не уверен, где это будет в документации. Есть идеи @ gatsbyjs / docs?

Вот как я это сделал:

require('babel-register')({
  presets: [ 'env' ]
})
require('babel-polyfill')
module.exports = require(`./gatsby-node.mjs`)

Кажется, он работает достаточно хорошо, но мне интересно, может ли это не испортить кеш? Я думаю, что кеш должен сбрасываться, когда вы изменяете gatsby-node.js но у меня возникли проблемы с этим, хотя я не знаю, связаны ли они.

@KyleAMathews Как насчет получения контента и данных ? По крайней мере, поэтому я его использовал.

Это своего рода разные дискуссии, но есть ли шанс, что использование import может поддерживаться из коробки? Мне кажется, что для более крупных проектов Gatsby то, что происходит в gatsby-node.js , почти так же важно, как и ваш фактический интерфейс, и отстойно не иметь возможности кодировать современным способом с помощью import , async/await и т.д. без лишних хаков.

@KyleAMathews , есть ли способ потребовать локальный файл ES6? Например, у меня есть файл src/utils/article.js который выглядит следующим образом:

// src/utils/article.js
import { format } from 'date-fns'

export const createArticleUrl = (a) => (
  `/${format(a.publishDate, 'YYYY')}` +
  `/${format(a.publishDate, 'MM')}` +
  `/${format(a.publishDate, 'DD')}` +
  `/${a.category.urlSlug}` +
  `/${a.urlSlug}`
)

и мой файл gatsby-node.js :

// gatsby-node.js
...
const { createArticleUrl } = require(`./src/utils/article`)
...

И я получаю ошибку:

  Error: .../src/utils/article.js:1
  (function (exports, require, module, __filename, __dirname) { import { format } from 'date-fns'
                                                                ^^^^^^
  SyntaxError: Unexpected token import

Любые идеи? Я использую эту функцию для создания URL-адреса для наших статей / сообщений и хотел бы импортировать его, как я это делаю в своих компонентах React. Спасибо!

Мне удалось решить свою проблему, используя ES5 в моем файле src/utils/article.js , например:

// src/utils/article.js
const { format } = require('date-fns')

var createArticleUrl = function (a) {
  return (
    `/${format(a.publishDate, 'YYYY')}` +
    `/${format(a.publishDate, 'MM')}` +
    `/${format(a.publishDate, 'DD')}` +
    `/${a.category.urlSlug}` +
    `/${a.urlSlug}`
  )
}

module.exports.createArticleUrl = createArticleUrl

а затем gatsby-node.js , вот так:

// gatsby-node.js
...
const { createArticleUrl } = require(`./src/utils/article`)
...

Я также могу импортировать createArticleUrl как обычно, в файлы ES6, import { createArticleUrl } from '../utils/article' .

Я использую для этого esm, и он пока работает. Вот что я сделал:

  1. Установить esm ( npm i esm )
  2. Создайте файл с именем gatsby-node.esm.js в корневой папке (в той же папке, что и gatsby-node.js ).
  3. Переместите весь свой код из gatsby-node.js в gatsby-node.esm.js
  4. Замените весь код в gatsby-node.js следующим:
    js require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
  5. Используйте import в gatsby-node.js сколько хотите 🎉

@KyleAMathews Есть что-нибудь опасное в том, чтобы делать это таким образом? Потому что, если это безопасно, я могу добавить его в документацию :)

Является ли 5-й вариант «Используйте import в gatsby-node.esm.js всем, что вы хотите»?

@WeZZard Вы совершенно правы! Исправлю в своем посте.

Другой способ, которым я обнаружил, что это работает, - это обновить ваш package.json следующим образом:

  "scripts": {
    "build": "npx --node-arg '-r esm' gatsby build",
    "develop": "npx --node-arg '-r esm' gatsby develop",
    "start": "npx --node-arg '-r esm' npm run develop",
    "serve": "npx --node-arg '-r esm' gatsby serve",
    "test": "echo \"Write tests! -> https://gatsby.app/unit-testing\""
  },

Нет необходимости создавать новые файлы

@reaktivo, ваши скрипты работают локально, но мне не удалось заставить их работать с netlify. Можете ли вы развернуть свой сайт для нетлификации с помощью npx ?

@rotexhawk Просто подтолкнул пример, и он отлично сработал:

https://github.com/reaktivo/gatsby-esm/
https://gatsby-esm-example.netlify.com/

Убедитесь, что вы запускаете npm install --save-dev esm раньше и что ваша конфигурация сборки запускает npm run build вместо gatsby build

Посмотрите этот коммит: https://github.com/reaktivo/gatsby-esm/commit/cf620259ac8b118dea38b99409963cb26bf1b240

Спасибо, установил esm. проблема в том, что netlify не имеет доступа к npx , говорит, что команда не удалась. Я указал версию своего узла, но это не помогло.

@rotexhawk Это действительно странно, учитывая, что проект, который я вам отправил, был развернут на Netlify ... в любом случае, если вам нужно избежать npx , следующее может сработать:

  "scripts": {
    "build": "node -r esm ./node_modules/bin/gatsby build",
    "develop": "node -r esm ./node_modules/bin/gatsby develop",
    "start": "npm run develop",
    "serve": "node -r esm ./node_modules/bin/gatsby serve",
    "test": "echo \"Write tests! -> https://gatsby.app/unit-testing\""
  },

@rotexhawk Связался с командой Netlify, вам также может потребоваться указать NPM_VERSION, см. https://www.netlify.com/docs/build-settings/#node -npm-and-yarn

@reaktivo подойдет. Спасибо за помощь.

Я настоятельно рекомендую добавить этот подход esm в документацию, поскольку Гэтсби указывает, что модули es6 должны работать внутри файла gatsby-node.js. Это сообщение об ошибке выводится при смешивании модулей:

error This plugin file is using both CommonJS and ES6 module systems together which we don't support. You'll need to edit the file to use just one or the other.

Это ясно указывает на то, что вы МОЖЕТЕ использовать модули es6.

esm , похоже, не работает при использовании рабочих пространств пряжи. Он говорит, что не может найти модуль рабочей области.

На самом деле кажется, что это работает только для импорта первого уровня в gatsby-node.ems.js , а не для всего, что импортируемый компонент также импортирует.

Например,

./gatsby-node.ems.js

import foo from "./foo";
const fooText = foo + " more text";

./foo

import bar from "bar";
const foo = bar("whatever");
export default foo;

Выдает ошибку:

Error in "C:\...\gatsby-node.js": Cannot find module 'bar'

Поскольку модулей Node почти нет, я хотел использовать node с --experimental-modules вместо esm .

Я изменил scripts.start на "node --experimental-modules ./node_modules/.bin/gatsby develop" , переименовал gatsby-node.js в gatsby-node.mjs , но получаю

Ошибка в "~ / website / gatsby-node.mjs": необходимо использовать импорт для загрузки модуля ES: ~ / website / gatsby-node.mjs

Ошибка: [ERR_REQUIRE_ESM]: необходимо использовать импорт для загрузки модуля ES: ~ / website / gatsby-node.mjs

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

Теперь, когда модули ES больше не являются экспериментальными , стоит ли снова открывать эту проблему?

Они все еще экспериментальны и не совсем закончены. Просто флаг был снят

однако реализация остается экспериментальной и может быть изменена.

Я глубоко погрузился в это, и, похоже, это еще не стоит боли. Подождите, пока загрузчики будут реализованы, или используйте пакет esm .

Кто-нибудь нашел решение с помощью babel? Было бы здорово, если бы я мог отбросить свою конфигурацию babel в проекте gatsby, и все это заработало.

Использование Гэтсби, но затем необходимость вернуться к module.exports действительно кажется огромным шагом назад.

Modern web tech without the headache -> не так много :(

npm i esm

а затем измените свои команды, чтобы они выглядели так:

https://github.com/wesbos/awesome-uses/blob/master/package.json#L39 -L42

@wesbos @reaktivo можете ли вы использовать это исправление с последней версией Gatsby (2.22.17 в моем случае)?

У меня он работал без каких-либо проблем с использованием этого решения, но сегодня обновил gatsby и снова начал получать ошибки импорта:

`` ''

npx --node-arg '-r esm' разработка Гэтсби

ОШИБКА № 10123 КОНФИГУРАЦИЯ

Мы столкнулись с ошибкой при попытке загрузить gatsby-config вашего сайта. Исправьте ошибку и попробуйте еще раз.

Ошибка: /project/gatsby-config.js:1
(функция (экспорт, требование, модуль, __filename, __dirname) {импорт urlJoin из "url-join";
^^^^^^
SyntaxError: невозможно использовать оператор импорта вне модуля.

В качестве альтернативы вы можете использовать TypeScript для файлов gatsby-* .

мой трюк с esm выше просто перестал работать. Я даже откатил версию gatsby и node, и она сохраняется.

Подробно здесь, если у кого-то есть такая же проблема: https://github.com/reaktivo/gatsby-esm/issues/1

@caycecollins вы нашли исправление?

@wesbos В итоге я вернулся к es5, который сейчас требуется :(

РЕДАКТИРОВАТЬ: Я только что заметил ваше последнее исправление здесь https://github.com/gatsbyjs/gatsby/issues/24925 ... Я попробую!

Просто напомню, что я боролся с этим в течение часа и, наконец, понял, что независимо от того, что я добавляю в свой package.json для сборки, конфигурация пользовательского интерфейса Netlify имеет приоритет. Это стало очевидным только после того, как я добавил netlify.toml. Мораль истории, отредактируйте настройки сборки пользовательского интерфейса Netlify или удалите их и добавьте в конфигурацию. Я предпочитаю последнее. 😄

[build]
  command = "npm run build"
  publish = "public"

Стоит отметить, что да, у меня это сработало:

"build": "NODE_OPTIONS='-r esm' gatsby build",

Вау, я понимаю, что изменить сложно, но сейчас модули ES - это Javascript, поэтому очень неприятно видеть (по каким-либо вполне веским причинам) сопровождающие, борющиеся _против поддержки Javascript_ ... особенно когда JDalton и его пакет esm делают это так просто!

PS Несколько важных деталей, о которых вы могли не знать ...

  • Это двухстрочное исправление. Если у Гэтсби нет нескольких «точек входа», весь PR, чтобы исправить это, будет состоять из трех строк: записи package.json для пакета esm и строк:
require = require("esm")(module/*, options*/)
module.exports = require("./main.js")
  • Этот модуль уже широко используется в крупных библиотеках, таких как Knex. В зависимости от этого уже существует буквально 135 ... _тысячи_ библиотек!

  • Ее написал создатель Lodash, так что это не первый проект NPM какого-нибудь младшего инженера: это серьезная библиотека, написанная опытным профессионалом.

  • Он полностью обратно совместим: если кто-то не использует import или export в коде модуля, отличного от ES (и я почти уверен, что это были запрещенные ключевые слова JS с незапамятных времен) все существующие код будет продолжать работать так же

  • если возникнут какие-либо проблемы с производительностью, тривиально легко «сохранить» эту функцию с помощью аргумента командной строки (например, knex выбрал этот путь)

Так это «получить современные возможности языка Javascript с помощью трех строк кода» или ... бороться за это? выгода.

Если есть интерес, с радостью напишу пиар :)

Может ли кто-нибудь предоставить окончательное решение и заблокировать эту ветку?

Ненавижу этот танец просмотра всех комментариев в действительно важных, но, казалось бы, закрытых вопросах, по которым все еще продолжается обсуждение, и попытки просмотреть все комментарии, чтобы увидеть, какой из них получил больше всего одобрения и, вероятно, будет лучшим решением 😔

Как я уже сказал, твердая часть не делает esm модуль работы: он разработан , чтобы сделать вещи очень просто. Я бы сам отправил PR, если бы я знал что-нибудь об архитектуре Гэтсби (и снова, чтобы увидеть, как другая крупная библиотека использует ее, просто посмотрите на Knex ).

Самое сложное - это просто привлечь внимание сопровождающего с такими знаниями :(

Можно подумать, что даже если бы каждый сопровождающий лично ненавидел современный синтаксис JS-модуля, он все равно мог бы по крайней мере оценить желание своих пользователей к нему ... но отказ даже повторно открыть эту проблему, не говоря уже о ее исправлении ( опять же, возможно, всего с двумя строчками кода) предполагает иное. Учитывая, насколько хороша эта команда с другими проблемами, это меня честно сбивает с толку.

Как я уже сказал, самая сложная часть - _не_ заставить работать модуль esm : он разработан, чтобы сделать вещи _экстремально_ простыми. Я бы сам отправил PR, если бы я знал что-нибудь об архитектуре Гэтсби (и снова, чтобы увидеть, как другая крупная библиотека использует ее, просто посмотрите на Knex ).

Самое сложное - это просто привлечь внимание сопровождающего с такими знаниями :(

Можно подумать, что даже если бы у каждого сопровождающего было личное _ненавистное_ к синтаксису современного JS-модуля, они все равно могли бы по крайней мере оценить желание своих пользователей к нему ... но отказ даже повторно открыть эту проблему, не говоря уже о ее исправлении ( опять же, возможно, всего с двумя строчками кода) предполагает иное. Учитывая, насколько хороша эта команда с другими проблемами, это меня честно сбивает с толку.

Какие-нибудь новости от сопровождающих по этому поводу, пожалуйста?

Была ли эта страница полезной?
0 / 5 - 0 рейтинги