HTML page not running JavaScript (transpiled by Babel) - javascript

I'm trying to port my JavaScript source code to JavaScript ES6. To acomplish this I have so far:
1) installed Babel to my project folder
2) created .babelrc file
3) defined the file watcher in my WebStorm to auto transpile JavaScript files.
Transpiling seems to work well, the "older" syntax JavaScript files get created in a dist folder. However, when I try to run my transpiled code (added in a .html file) the alert test doesn't show up when using import statement.
Here's the source code:
arquivo.js
let test = 'Alert from Arquivo.js';
export {test};
main.js
import {test} from "./arquivo";
alert(test);
After auto transpile:
arquivo.js
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var test = 'Alert from Arquivo.js';
exports.test = test;
//# sourceMappingURL=arquivo.js.map
main.js
"use strict";
var _arquivo = require("./arquivo");
alert(_arquivo.test);
//# sourceMappingURL=main.js.map
This is my index.html file inside same transpiled JavaScript files folder:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test</title>
<!--
main.js is the after
transpiled code
-->
<script src="main.js"></script>
</head>
<body>
</body>
</html>
Browser console reports this:
Uncaught ReferenceError: require is not defined
at main.js:3
How to avoid this problem?

Related

How to import modules for unit tests with QUnit

I've been trying to add unit tests for some modular ES6 code. I have a project structure like this:
project
└───src
| └───js
| cumsum.js
| index.js <--- entry point
└───test
tests.js <--- QUnit test code
This is what's in cumsum.js:
export const cumsum=x=>{
var result = x.reduce((r, a)=> {
if (r.length > 0) {
a += r[r.length - 1];
}
r.push(a);
return r;
}, []);
return result;
}
Now, if I run this sample test by running qunit in the command line, it will work:
const A=[1,2,3,4,5];
const expected=[1,3,6,10,15];
QUnit.test( "cumsum", function( assert ) {
assert.deepEqual([1,3,6,10,15],expected);
});
but if I try to import the actual cumsum function, it doesn't recognize proper ES6 import syntax:
import {cumsum} from '../src/js/cumsum';
const A=[1,2,3,4,5];
const expected=[1,3,6,10,15];
QUnit.test( "cumsum", function( assert ) {
assert.deepEqual(cumsum(A),expected);
});
I just get the error
SyntaxError: Unexpected token {
Is there a way to use QUnit with ES6 modules? If not, is there a unit testing framework that will let me test these modules?
Here's what I've come up with so far.
Chrome can sort of natively run ES6 modules. It's not good enough for web production but it is enough to run some unit tests. So in the test folder I have index.html like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>QUnit Example</title>
<link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.9.2.css">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="https://code.jquery.com/qunit/qunit-2.9.2.js"></script>
<script type="module" src="../src/js/cumsum.js"></script>
<script type="module" src="tests.js"></script>
</body>
</html>
In test/tests.js I have the original test code:
import {cumsum} from '../src/js/cumsum';
const A=[1,2,3,4,5];
const expected=[1,3,6,10,15];
QUnit.test( "cumsum", function( assert ) {
assert.deepEqual(cumsum(A),expected);
});
Now, for some reason you can't directly open test/index.html in the web browser because although Chrome will happily read ordinary javascript files locally it will break if you set type="module" on a local file. Instead we have to launch a web server and view it that way. Any dev server will do, so webpack-dev-server works fine. Open http://localhost:8080/test/ in Chrome and the unit tests load.
Does anyone have a better way of doing this? Node.js uses the same javascript engine as Chrome so in theory I think it should be possible to do this from the command line without launching a web server and opening a browser.

Typescript require not working [duplicate]

This question already has answers here:
Importing an external module in TS causes "ReferenceError: require is not defined"
(2 answers)
Closed 6 years ago.
I have 3 typescript files: main.ts, print.ts, log.ts
I installed node modules and used typescript compiler - tsc main.ts - to compile .ts files.
After that, I tried to run index.html with npm start, but console.log says require is not defined. Am I still missing something? I use Visual Studio Code editor.
INDEX.HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>this is the title</title>
<style type="text/css">
</style>
</head>
<body>
<div id="wrapper">
</div>
<script type='text/javascript' src='main.js'></script>
</body>
</html>
MAIN.TS
import log = require('./log')
import print = require('./print')
log.logMessage();
print.printMessage();
PRINT.TS
export function printMessage() {
console.log('print');
}
LOG.TS
export function logMessage() {
console.log('log');
}
Console.log should say 'log' and 'print', but it doesn't.
Your code is fine. The important part of your question is
but console.log says require is not defined
require is used in node's module system, called CommonJS. Browsers do not understand this system by default. You have to use a bundler, like webpack or fuse-box
TypeScript can not really bundle your application :-/

Using express-babelify-middleware with FeathersJS

I am trying to use express-babelify-middleware
with FeathersJS and the error shows up in the browser console:
ReferenceError: main_run is not defined
I take this to mean that babelify is not working or I am using it incorrectly as main_run is in the global namespace of the src in my html file.
Here is my setup using the structure from feathers generate:
public/index.html:
<!DOCTYPE html>
<html>
<head>
<title>babelify test</title>
<script src="main.js"></script>
<script>
main_run()
</script>
</head><body>
<p>Testing feathers with babelify</p>
</body></html>
public/main.js
const external_module = require('./test')
function main_run(){
external_module()
}
public/test.js
module.exports = function(){
console.log("Hello world for an external module")
}
among the .uses of src/app.js:
...
const babelify = require('express-babelify-middleware')
...
app.use(compress())
.options('*', cors())
.use(cors())
//the line that is not working:
.use('/main.js', babelify( path.join(app.get('public'), 'main.js') ))
.use(favicon( path.join(app.get('public'), 'favicon.ico') ))
.use('/', serveStatic( app.get('public') ))
When I visit localhost:3030/main.js I can see the file, but the functions look to be in a function of their own, so I don't know how to get into that function.
Silly problem, one can't access browserified code in the html file that calls it. So public/index.html can't access main_run unless it is attached to the window object. There is a similar question
here.
Other than that, my code works perfectly.
In main.js place the following code at the bottom:
window.main_run = main_run
Then in index.html replace the main_run() line with:
window.main_run()
This will write the contents of test.js to the console.

"ReferenceError: window is not defined" when compiling with r.js

I've been using RequireJS and it works perfectly. I use a lot of "window.document" to manipulate different DOM elements, but when I try to optimize it with r.js i get a ReferenceError: window is not defined which only happens with r.js.
Here is a minimal example of code that reproduces the issue:
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body >
<div id="commentbox">
</div>
<script data-main="code/main" src="code/require.js"></script>
</body>
</html>
main.js:
require(["roomManager"], function (roomManager){
return {
}
});
roomManager.js:
define(["commentManager"], function(commentManager){
var commentHand = new commentManager.commentHand();
commentHand.init();
return{
}
});
commentManager.js:
define([], function(){
function commManager(getDisplayIdVariable){
var messagebox = window.document.getElementById("commentbox");
this.init = function(){
messagebox.innerHTML = "hi!";
}
}
return{
commentHand : commManager
}
});
This version works correctly without r.js but when I try to compile it by running r.js main.js. I get this:
var messagebox = window.document.getElementById("commentbox);
ReferenceError: window is not defined
at new new commManager
You cannot just do r.js main.js.
For one thing, you have to specify -o so that r.js performs the optimization. (r.js can be used for other things.)
You also have to pass configuration to r.js, either in a file, or on the command line. One possibility for you would be:
r.js -o name=main out=built.js
I've tried this with the code you show in your question and I get no errors.
I strongly suggest going over this documentation for r.js.
if your code is optional you can use
if (typeof window !== 'undefined') {
// Inside browser
}
{
// outside browser
}

How to use javascript on nodejs and web at the same time?

i want to use a config file in nodejs and in a web javascript.
config.js:
var conf = {};
conf.name = 'testname';
conf.pass = 'abc123';
conf.ip = '0.0.0.0';
conf.port = 100;
conf.delay = 5;
exports.config = conf;
use it in nodejs with:
var conf = require('config.js');
console.log(conf.config.name);
want to use this same file inside html but how? I was thinking by this way but i don't know how to use it in web. When i try to use it in web i get Reference error: exports is not defined.
config.html:
<!doctype html>
<html lang="en">
<head>
<title>Document</title>
<script src="./config.js"></script>
<script>
var cnf = conf;
function getCnf(){
alert(cnf.config.name);
}
</script>
</head>
<body>
<button onclick="getCnf();">test</button>
</body>
</html>
Anyone know how i must change config.js to use it in both systems nodejs and web?
PS: Webside is running on nodejs http npm module.
You can put a condition around that, like this
if (typeof module !== 'undefined' && module.exports) {
module.exports.config = conf;
}
This makes sure that you have module and exports are available before setting any value on exports.
Note: exports is just another variable referring module.exports. So, they both are one and the same unless you assign something else to either of them. In case, you assign something to either of them, whatever is there in module.exports will be exported in Node.js. You can read more about exports in this blog post
Thanks, that typeof was all i needed.
#Phoenix: I know that there is a way to do that but that's not necessary. The variable are only used for some ajax requests and deley timers later.
You can use browserify to bundle your CommonJS for the browser without resorting to environment switches.
Install browserify using npm i browserify -g
Bundle your config.js and export it for external use with the -r tag
browserify -r ./config.js -o bundle.js
Include the bundle in your code and use it:
<!doctype html>
<html lang="en">
<head>
<title>Document</title>
<script src="./bundle.js"></script>
<script>
var cnf = require("./config.js");
function getCnf(){
alert(cnf.config.name);
}
</script>
</head>
<body>
<button onclick="getCnf();">test</button>
</body>
</html>

Categories

Resources