#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. Я исправляюсь, я не знал об этой функциональности, и сегодня я кое-что узнал, спасибо. Однако по-прежнему рекомендуется оставаться в системе модулей файла.