0

I'm refactoring my code from one big browser javascript file into a nicer node JS structure, with webpack, and I'd really like to be able to import the OpenLayers node module into my node scripts.

My JS files and package.json are stored in /mymodule, and the node_modules folder for my project is in /node_modules - I have a symlink set up to /mymodule from /node_modules/mymodule. My /mymodule/index.js file loads a bunch of other files into which I've been refactoring my code from my original browser javascript.

This is my package.json:

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

Here's my 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)

And this is where I'm having issues - 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,
  }),
});

I ran npm install, and that created a new /mymodule/node_modules folder, with OpenLayers installed in an /ol folder in there. Something tells me that was not the right way to do things, because I was expecting my module to just load OpenLayers from the existing /node_modules/ol installation rather than making a new /mymodule/node_modules/ol installation. I was hoping that setting "bundledDependencies": false in package.json would achieve that, but I guess not.

npm run dev goes ahead and completes without any errors, but then in the browser console I get Uncaught ReferenceError: exports is not defined at this line:

exports.image = new Circle({

... in fact that line above has been rewritten by webpack (I assume) as follows:

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

Everything else I've done so far with other exports from my other JS files (myConstants.js, myHelpers.js etc) has worked just fine, so I'm sure I'm just doing this import process the wrong way. But what am I actually doing wrong here?

2 Answers 2

2
+50

Your code is mixing ESM and CommonJS, unfortunately you can not use both, you must use one or the other.

You want to use the Export keyword rather than module.exports/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,
  }),
});

This will allow you to import {image} from "filename"

Note - as Jackie said, This will only work for node>=13.x

In node <12 you must add the flag --experimental-modules and use .mjs file extension

Sign up to request clarification or add additional context in comments.

8 Comments

Also make sure you are using the --experimental-modules flag and the file has an extension .mjs.
Since v13 this is actually not experimental anymore, and there is no more flag.
Lol ok sorry been on pre since 12 but still should be sure to denotate the Module system (IE cjs, mjs, etc) in the extension
So I guess first question is what version of node is he using.
I'll modify my answer to account for that @Jackie
|
0

You are using both module.exports and exports. Since exports is a variable referring to module.exports, and it seems to not be available in the browser, use module.exports instead of exports.

This

exports.image = new Circle({

would become this :

module.exports.image = new Circle({

7 Comments

ESM modules may not assign module.exports, that is CommonJS, this is ESModules. The proper syntax is export OBJECT
@EthanSnow Webpack supports CommonJS modules
Correct, however he is using ESM Imports, if was using require then yes, he could use module.exports. You can't mix the two in a single file.
@EthanSnow Look at the first line of his index.js, he is require-ing myStyles.js and not importing it, so the functionality should be exposed via module.exports.
I stand corrected, I was unaware of that functionality and I learned something today, thank you. However it's still good practice to stay within the module system of the file.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.