CORS blocked when I use type="module"

Hello guys,

I’m new to using modules in the browser. I just tried to use browserify to compile a file that merely contains

const jsdom = require("jsdom");

into a file called main.js

Now, here’s my html:

<!Doctype html>
<html>
	<head>
		<meta charset="utf-8">
	</head>
	
	<body>
		<script type="module" src="main.js"></script>
		<script type="module" src="index.js"></script>
	</body>
</html>

I use import statement in the index.js file:

import * as jsdom from 'main.js';

Anyway, I keep getting this error:

When I exclude the type=“module” from each script tag, I just get the last error. I am trying to get NO errors! :sweat_smile:

I just want to use this npm module in the browser. Any insight onto how to do that, let alone solve this problem, is greatly appreciated.

Hello!

That’s because you’re not using a server. Many (if not all) browsers block requests that come from different origins, even if that origin is the local file system.

Create a basic server that just serve that page and it should work. Or upload the project to a hosting (github pages, for instance).

Hope it helps,

Happy coding!

Hey,

I just tried running a simple express server with nodejs, and…


It appears that it can’t find any of the JavaScript files. Here’s the code I used for the server:

var express = require('express');
var app = express();

app.get('/', (req, res)=>{res.sendFile('index.html', { root: __dirname });});
app.listen(8080, function()
{
	console.log("When Server Starts, Log This");
});

How do I make it see my JavaScript files? Thanks a lot for your help.

Nevermind, I got the server to work, and…it didn’t work. CORS error is gone but I still get the error about not being able to use import statement outside a module

Sorry, I didn’t see the last error :sweat_smile:.

Your files should have a mjs extension, not js: main.mjs, index.mjs.

No no, mjs is a stopgap thing for Node, has nothing to to do with browsers, it has to be .js else it can’t work

There’s no export, so there’s nothing to import in the other file, and I assume your error is because you’re attempting import

You’re trying the a lot of stuff at once here:

  • node
  • commonJS syntax imports
  • a bundler to I assume convert files there to browser compatible JS
  • normal JS import/exports
  • browser js

Why can’t you just write JS modules at first here to get things working before you make it all extremely complicated, what is your end goal here?

Also not sure why you’re using JSDom for this test, it’s a strange choice, why are you trying to have this run browser-side?

Yes, you’re right. Sorry for my mistake and thanks for clarifying it :slight_smile:.

Hah…perhaps you could give me some advice…

I am trying to make…*drumroll please*…a content management system (don’t ask why)!

I have written a program that makes an ajax request to a php file that retrieves the contents of another html file. I want to put that html in a div so that the user can see the rendering of the other html file in real time while they add or delete content in a custom terminal I made with JavaScript. The problem is I don’t want to put all the html in the div because I figure the dom interpreter might get confused (with 2 different sets of < html> tags and whatnot), so I wanted to use JavaScript dom manipulation on said html to retrieve what’s important before putting it in the div. Does that make sense?


(And yes, I’m aware that there’s [apparently] a dom interpreter library in php. It doesn’t work for me so far. I’m using WAMP).

I’m kind of surprised that what I need doesn’t exist for front end… :frowning:

Anyway, using the syntax browserify main.js -o theFileWithRequireInIt.js

I got a browserified version of jsdom into main.js, and it has a lot of statements like this:

exports.EncoderBuffer = EncoderBuffer;

I assumed there might be some sort of export object that is exported at the end…otherwise what’s the point of having used browserify? They mean to tell me I have to go through this 205,847 line file and export each function manually? Ridiculous!

So, perhaps you could offer some insight.

  1. Is it possible to use npm modules in the browser? If so, how?
  2. How would you go about parsing the html? I thought JavaScript dom manipulation would be easier for this…

Thanks so much for your time and help :slightly_smiling_face:

It does, but the normal answer is use an iframe. I understand why you’re doing this, it just seems the more difficult way to do it (definitely much more complex). You could just render the HTML as an HTML page, and view that page in the iframe

But that difficulty kinda pales in comparison to trying to use JS modules in the browser in the way you are. You are making life staggeringly difficult for yourself. It’s a good thing to try out, but this technology is in its infancy. Nothing is really currently written to make this easy.

There is, that’s what the require/module.exports is, but that’s CommonJS. JSDom (or basically any Node module) isn’t written as an uncompiled ES6 module. There would be no point – Node didn’t really support them fully up until a few months ago, and even then that support comes with caveats. To work out-of-the-box in a browser as a script type="module", a package needs to be all ES6, with import and export statements throughout. Because most libraries are written using ES6 module syntax nowadays, if you can get at the source (rather than the compiled distribution version) it can sometimes be fudged, but that’s often as good as you’ll get

Yes, Browserify was designed to do that, and nowadays Webpack or Parcel (or Rollup for libraries) are generally used to do the same job. They take a load of modules, some written in ES6 module syntax and some in CommonJS, and bundle them up into one file (or several chunked files) that you can then use in a browser. They aren’t designed to take arbitrary modules, translate them to ES6 if necessary, then spit out the results as a set of modules you can then use in-browser as set of scripts of type module. As far as I know nothing exists that provides a toolchain to automate that process.

Personally? Ajax request sent → backend generates HTML page to your specs at some URL → page is rendered in an iframe pointing at that URL → force refresh the iframe.

You.may have some complex requirements that make using JSDom very important, but afaics above should fit the bill

Thanks. That was an excellent solution.

1 Like