Как импортировать node.js модуль в node.js модуль

#javascript #node.js #webpack #node-modules

Вопрос:

Я рефакторингую свой код из одного большого файла javascript браузера в более приятную структуру JS узла с помощью webpack, и мне бы очень хотелось иметь возможность импортировать модуль узла OpenLayers в мои сценарии узлов.

Мои файлы JS и package.json хранятся в /mymodule , а папка node_modules для моего проекта находится в /node_modules — у меня есть символическая ссылка, настроенная на /mymodule from /node_modules/mymodule . Мой /mymodule/index.js файл загружает кучу других файлов, в которые я переделывал свой код из исходного javascript браузера.

Это мой пакет.json:

 {
  "name": "mymodule",
  "version": "1.0.0",
  "description": "Description goes here",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" amp;amp; exit 1"
  },
  "keywords": [],
  "author": "Me",
  "license": "ISC",
  "type": "module",
  "bundledDependencies": false,
  "dependencies": {
    "ol": "6.5.0"
  }
}
 

Вот мой index.js:

 const myConstants = require('./myConstants.js')
const myHelpers = require('./myHelpers.js')
const myStats = require('./myStats.js')
const myStyles = require('./myStyles.js')

module.exports = Object.assign({}, myConstants, myHelpers, myStats, myStyles)
 

И вот тут у меня возникают проблемы — myStyles.js:

 import { Style, Circle, Stroke, Fill, Text } from 'ol/style';

exports.image = new Circle({
  radius: 5,
  fill: null,
  stroke: new Stroke({
    color: 'red',
    width: 1,
  }),
});
 

Я побежал npm install , и это создало новую /mymodule/node_modules папку, в которой в /ol папке были установлены OpenLayers. Что-то подсказывает мне, что это был неправильный способ, потому что я ожидал, что мой модуль просто загрузит OpenLayers из существующей /node_modules/ol установки, а не сделает новую /mymodule/node_modules/ol установку. Я надеялся, что установка "bundledDependencies": false в package.json позволит этого достичь, но, думаю, нет.

npm run dev идет дальше и завершается без каких-либо ошибок, но затем в консоли браузера я попадаю Uncaught ReferenceError: exports is not defined в эту строку:

 exports.image = new Circle({
 

… на самом деле эта строка выше была переписана webpack (я предполагаю) следующим образом:

 exports.image = new __WEBPACK_IMPORTED_MODULE_0_ol_style__["a" /* Circle */]({
 

Все остальное, что я до сих пор делал с другими экспортными файлами из других моих файлов JS (myConstants.js, myHelpers.js и т. Д.) Работал просто отлично, поэтому я уверен, что просто неправильно выполняю этот процесс импорта. Но что я на самом деле здесь делаю не так?

Ответ №1:

Ваш код смешивает ESM и CommonJS, к сожалению, вы не можете использовать оба, вы должны использовать один или другой.

Вы хотите использовать ключевое слово Export, а не module.exports/экспорт

 import { Style, Circle, Stroke, Fill, Text } from 'ol/style';

export const image = new Circle({
  radius: 5,
  fill: null,
  stroke: new Stroke({
    color: 'red',
    width: 1,
  }),
});
 

Это позволит вам import {image} from "filename"

Примечание — как сказала Джеки, это будет работать только для узла>=13.x

В узле <12 необходимо добавить флаг --experimental-modules и использовать расширение файла .mjs

Комментарии:

1. Также убедитесь, что вы используете флаг —experimental-modules и файл имеет расширение .mjs.

2. Начиная с версии 13, это на самом деле больше не экспериментально, и флага больше нет.

3. Lol ок, извините, был на pre с 12, но все равно должен быть уверен, что обозначил систему модулей (т. Е. cjs, mjs и т. Д.) В расширении

4. Поэтому я предполагаю, что первый вопрос заключается в том, какую версию узла он использует.

5. Я изменю свой ответ, чтобы учесть это @Jackie

Ответ №2:

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

Этот

 exports.image = new Circle({
 

стало бы это :

 module.exports.image = new Circle({
 

Комментарии:

1. Модули ESM могут не назначать модуль.экспорт, то есть CommonJS, это ESModules. Правильный синтаксис таков export OBJECT

2. @EthanSnow Webpack поддерживает модули CommonJS

3. Правильно, однако он использует импорт ESM, если бы использовал require, то да, он мог бы использовать module.exports. Вы не можете смешать их в одном файле.

4.@EthanSnow Посмотрите на его первую строку index.js , он require myStyles.js ее импортирует, а не импортирует, поэтому функциональность должна быть доступна через module.exports .

5. Я исправляюсь, я не знал об этой функциональности, и сегодня я кое-что узнал, спасибо. Однако по-прежнему рекомендуется оставаться в системе модулей файла.