JavaScript / TypeScript issue with HTML [duplicate] - javascript

utility.ts
let books = [
{ id: 1, title: "the dark window", author: "krishna", available: true },
{ id: 2, title: "naked eye", author: "sydney", available: false },
{ id: 3, title: "half girlfriend", author: "chetan", available: true },
{ id: 4, title: "make my dreams", author: "salam", available: false }
];
export { books };
main- app.ts
import {books} from './utility';
let getAllBooks = (): void => {
books.filter((val) => {
console.log(val.author);
})
}
How can I access the getAllBooks functiion in a Html page?
If I don't use export and import it works perfectly fine but I have to use it instead of writing everything into one file.
Please advice [using amd module] to generate one JS file as output [main.js].
Getting the below error in the chrome console.
[(index):13 Uncaught ReferenceError: getAllBooks is not defined
at HTMLInputElement.onclick ((index):13)]
My html page
<html>
<title>Welcome</title>
<head>
<script data-main="./js/main" src="./js/require.js"></script>
<script src="./js/main.js"></script>
<body>
<div id="mytest"></div>
<input type="button" value="Click!" id="btnClick" onclick="getAllBooks();" />
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</body>
</head>
</html>
main.js
define("utility", ["require", "exports"], function (require, exports) {
"use strict";
let books = [
{ id: 1, title: "the dark window", author: "krishna", available: true },
{ id: 2, title: "naked eye", author: "sydney", available: false },
{ id: 3, title: "half girlfriend", author: "chetan", available: true },
{ id: 4, title: "make my dreams", author: "salam", available: false }
];
exports.books = books;
});
define("app", ["require", "exports", "utility"], function (require, exports, utility_1) {
"use strict";
let getAllBooks = () => {
utility_1.books.filter((val) => {
console.log(val.author);
});
};
});
//# sourceMappingURL=main.js.map

Update browser to recent one (recent enough to support ES2015 module)
Change tsconfig.json target to es2015
Change tsconfig.json module to es2015
Always add .js extension to your import statements
Use an http server like live-server to avoir CORS concerns with file:// protocol
BONUS: Explicitly set tsconfig.json moduleResolution to node. This is not necessary if you don’t use external libraries or #types/* packages.
See it altogether at : https://github.com/SalathielGenese/ts-web
Disclosure : I'm its author.

Browsers do not yet support javascript modules. Until they do you will need to include browserify into your development workflow. Browserify concatenates your modules into a browser friendly bundle.
Browserify is very simple to get working in a typescript workflow. If you are feeling adventurous you can look at other bundlers like WebPack, Rollup or SystemJs.
Note, this is not specific to TypeScript. When developing any modern javascript (es6 or CommonJS modukes) you will need to bundle modules for the browser.

Im new to AMD but it looks like you only define the modules, never invoke/import them to the sites scope.
In this tutorial the author has a bootstrapping file that acts as entry point for an app which seems to be what you're missing: http://www.codebelt.com/typescript/typescript-amd-with-requirejs-tutorial/

I think the title is incorrect and what you really trying to do is running TypeScript applications in te browser which is totally different yo "Run TypeScript in the browser, right?
In that case to get started with TypeScript I recommend you to not use require.js add instead a bundler-like tool like a tool like parcel, webpack, browserify, rollup. parcel is super easy : For your example, 1) remove ALL script tags and add only the following: <script src="my/app.ts"> then "compile" that html with parcel theFile.html or build for production : parcel build theFile.html
if I was right, could you please change the title of this question since is confusing and misleading ? thanks.
Now, on the other side, If you really want to run TypeScript as the title say, typescript is fully compatible with the browser (the .js file library is node_modules/typescript/lib/typescript.js ). just import it as another module or load the file in a script tag and use the Compiler API..
This project contains my research on the topic with several working examples and demo apps and some tools: https://github.com/cancerberoSgx/typescript-in-the-browser

Related

Why doesn't importing scripts from <script> tags work under html-loader?

I'm developing a website with Webpack 5, html-webpack-plugin, and html-loader.
Here's my index.html:
<!DOCTYPE html>
<html>
<head>
<title>test page</title>
</head>
<body>
<p>hello there</p>
<script type="application/javascript" src="../script/index.ts">
</script>
</body>
</html>
Here's my index.ts:
console.log('hi');
document.body.append('this isnt hmr but its not bad for a static site generator');
document.body.append('ree');
Here's the relevant section of my webpack.config.js:
module.exports = async (env) => {
return {
// ...
module: {
rules: [
// ...
{
test: /\.html$/i,
use: ['html-loader'],
},
],
},
plugins: [
// ...
new HtmlPlugin({
template: '../path/to/index.html',
filename: 'index.html',
})
],
// ...
};
};
When I try to compile this, I get the following error:
ERROR in Error: webpack-internal:///608:2
document.body.append('this isnt hmr but its not bad for a static site generator');
^
ReferenceError: document is not defined
- 608:2 eval
webpack-internal:///608:2:1
- index.html:21 Object.608
/home/laptou/website/client/source/page/index.html:21:1
- index.html:71 __webpack_require__
/home/laptou/website/client/source/page/index.html:71:41
- 673:3 eval
webpack-internal:///673:3:34
- index.html:48 Object.673
/home/laptou/website/client/source/page/index.html:48:1
- index.html:71 __webpack_require__
/home/laptou/website/client/source/page/index.html:71:41
- index.html:81
/home/laptou/website/client/source/page/index.html:81:18
- index.html:82
/home/laptou/website/client/source/page/index.html:82:12
- index.js:320 HtmlWebpackPlugin.evaluateCompilationResult
[client]/[html-webpack-plugin]/index.js:320:28
Why is the code in my index.ts being evaluated, instead of just being bundled, and how do I make this stop happening?
Edits:
I have looked at this question, but I feel my question is different because I am getting a different error. I already have a Babel loader in my chain, so all of the code should be perfectly digestible, plain JS.
I have looked at this question and its answer also, but I do not want to use Parcel because I could not get its glob imports to work correctly and consistently, and it does not have all of the features and community support that Webpack has.
I see a couple of issues in your webpack.config.js, and your index.html template.
Your template directly tries to include the index.ts, which is typescript.
But the plugin will inject the bundled script, so you shouldn't specify the script tag
yourself.
You have typescript in your project, but no rule specified with a loader for typescript.
You mention you are using 'html-webpack-plugin',
but the plugin you specify is spelled differently.
A final hint, on the error:
Whenever I've encountered 'docucument is not defined',
it has been because the webpack loader rules were configured inconsistently,
which causes webpack to execute the loaders on the wrong kinds of input,
which leads to weird 'the world is not defined!' kinds of errors.
Otherwise 'document is not defined' happens when clientside typescript/javascript
is erroneously included in a SSR(server-side-rendering) and/or nodeJS/server-side context.

Error with javascript: require('fs'). Why? [duplicate]

I am writing an application with the Node.js, Express.js, and Jade combination.
I have file client.js, which is loaded on the client. In that file I have code that calls functions from other JavaScript files. My attempt was to use
var m = require('./messages');
in order to load the contents of messages.js (just like I do on the server side) and later on call functions from that file. However, require is not defined on the client side, and it throws an error of the form Uncaught ReferenceError: require is not defined.
These other JavaScript files are also loaded at runtime at the client, because I place the links at the header of the webpage. So the client knows all the functions that are exported from these other files.
How do I call these functions from these other JavaScript files (such as messages.js) in the main client.js file that opens the socket to the server?
This is because require() does not exist in the browser/client-side JavaScript.
Now you're going to have to make some choices about your client-side JavaScript script management.
You have three options:
Use the <script> tag.
Use a CommonJS implementation. It has synchronous dependencies like Node.js
Use an asynchronous module definition (AMD) implementation.
CommonJS client side-implementations include (most of them require a build step before you deploy):
Browserify - You can use most Node.js modules in the browser. This is my personal favorite.
Webpack - Does everything (bundles JavaScript code, CSS, etc.). It was made popular by the surge of React, but it is notorious for its difficult learning curve.
Rollup - a new contender. It leverages ES6 modules and includes tree-shaking abilities (removes unused code).
You can read more about my comparison of Browserify vs (deprecated) Component.
AMD implementations include:
RequireJS - Very popular amongst client-side JavaScript developers. It is not my taste because of its asynchronous nature.
Note, in your search for choosing which one to go with, you'll read about Bower. Bower is only for package dependencies and is unopinionated on module definitions like CommonJS and AMD.
I am coming from an Electron environment, where I need IPC communication between a renderer process and the main process. The renderer process sits in an HTML file between script tags and generates the same error.
The line
const {ipcRenderer} = require('electron')
throws the Uncaught ReferenceError: require is not defined
I was able to work around that by specifying Node.js integration as true when the browser window (where this HTML file is embedded) was originally created in the main process.
function createAddItemWindow() {
// Create a new window
addItemWindown = new BrowserWindow({
width: 300,
height: 200,
title: 'Add Item',
// The lines below solved the issue
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
})}
That solved the issue for me. The solution was proposed here.
ES6: In HTML, include the main JavaScript file using attribute type="module" (browser support):
<script type="module" src="script.js"></script>
And in the script.js file, include another file like this:
import { hello } from './module.js';
...
// alert(hello());
Inside the included file (module.js), you must export the function/class that you will import:
export function hello() {
return "Hello World";
}
A working example is here. More information is here.
Replace all require statements with import statements. Example:
// Before:
const Web3 = require('web3');
// After:
import Web3 from 'web3';
It worked for me.
In my case I used another solution.
As the project doesn't require CommonJS and it must have ES3 compatibility (modules not supported) all you need is just remove all export and import statements from your code, because your tsconfig doesn't contain
"module": "commonjs"
But use import and export statements in your referenced files
import { Utils } from "./utils"
export interface Actions {}
Final generated code will always have(at least for TypeScript 3.0) such lines
"use strict";
exports.__esModule = true;
var utils_1 = require("./utils");
....
utils_1.Utils.doSomething();
This worked for me
Get the latest release from the RequireJS download page
It is the file for RequestJS which is what we will use.
Load it into your HTML content like this:
<script data-main="your-script.js" src="require.js"></script>
Notes!
Use require(['moudle-name']) in your-script.js,
not require('moudle-name')
Use const {ipcRenderer} = require(['electron']),
not const {ipcRenderer} = require('electron')
Even using this won't work. I think the best solution is Browserify:
module.exports = {
func1: function () {
console.log("I am function 1");
},
func2: function () {
console.log("I am function 2");
}
};
-getFunc1.js-
var common = require('./common');
common.func1();
window = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
});
I confirm. We must add:
webPreferences: {
nodeIntegration: true
}
For example:
mainWindow = new BrowserWindow({webPreferences: {
nodeIntegration: true
}});
For me, the problem has been resolved with that.
People are asking what is the script tag method. Here it is:
<script src='./local.js'></script>.
Or from network:
<script src='https://mycdn.com/myscript.js'></script>
You need plugin the right url for your script.
I was trying to build metronic using webpack. In my package.json I had to remove the "type": "module" section.

Client on Node.js: Uncaught ReferenceError: require is not defined

I am writing an application with the Node.js, Express.js, and Jade combination.
I have file client.js, which is loaded on the client. In that file I have code that calls functions from other JavaScript files. My attempt was to use
var m = require('./messages');
in order to load the contents of messages.js (just like I do on the server side) and later on call functions from that file. However, require is not defined on the client side, and it throws an error of the form Uncaught ReferenceError: require is not defined.
These other JavaScript files are also loaded at runtime at the client, because I place the links at the header of the webpage. So the client knows all the functions that are exported from these other files.
How do I call these functions from these other JavaScript files (such as messages.js) in the main client.js file that opens the socket to the server?
This is because require() does not exist in the browser/client-side JavaScript.
Now you're going to have to make some choices about your client-side JavaScript script management.
You have three options:
Use the <script> tag.
Use a CommonJS implementation. It has synchronous dependencies like Node.js
Use an asynchronous module definition (AMD) implementation.
CommonJS client side-implementations include (most of them require a build step before you deploy):
Browserify - You can use most Node.js modules in the browser. This is my personal favorite.
Webpack - Does everything (bundles JavaScript code, CSS, etc.). It was made popular by the surge of React, but it is notorious for its difficult learning curve.
Rollup - a new contender. It leverages ES6 modules and includes tree-shaking abilities (removes unused code).
You can read more about my comparison of Browserify vs (deprecated) Component.
AMD implementations include:
RequireJS - Very popular amongst client-side JavaScript developers. It is not my taste because of its asynchronous nature.
Note, in your search for choosing which one to go with, you'll read about Bower. Bower is only for package dependencies and is unopinionated on module definitions like CommonJS and AMD.
I am coming from an Electron environment, where I need IPC communication between a renderer process and the main process. The renderer process sits in an HTML file between script tags and generates the same error.
The line
const {ipcRenderer} = require('electron')
throws the Uncaught ReferenceError: require is not defined
I was able to work around that by specifying Node.js integration as true when the browser window (where this HTML file is embedded) was originally created in the main process.
function createAddItemWindow() {
// Create a new window
addItemWindown = new BrowserWindow({
width: 300,
height: 200,
title: 'Add Item',
// The lines below solved the issue
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
})}
That solved the issue for me. The solution was proposed here.
ES6: In HTML, include the main JavaScript file using attribute type="module" (browser support):
<script type="module" src="script.js"></script>
And in the script.js file, include another file like this:
import { hello } from './module.js';
...
// alert(hello());
Inside the included file (module.js), you must export the function/class that you will import:
export function hello() {
return "Hello World";
}
A working example is here. More information is here.
Replace all require statements with import statements. Example:
// Before:
const Web3 = require('web3');
// After:
import Web3 from 'web3';
It worked for me.
In my case I used another solution.
As the project doesn't require CommonJS and it must have ES3 compatibility (modules not supported) all you need is just remove all export and import statements from your code, because your tsconfig doesn't contain
"module": "commonjs"
But use import and export statements in your referenced files
import { Utils } from "./utils"
export interface Actions {}
Final generated code will always have(at least for TypeScript 3.0) such lines
"use strict";
exports.__esModule = true;
var utils_1 = require("./utils");
....
utils_1.Utils.doSomething();
This worked for me
Get the latest release from the RequireJS download page
It is the file for RequestJS which is what we will use.
Load it into your HTML content like this:
<script data-main="your-script.js" src="require.js"></script>
Notes!
Use require(['moudle-name']) in your-script.js,
not require('moudle-name')
Use const {ipcRenderer} = require(['electron']),
not const {ipcRenderer} = require('electron')
Even using this won't work. I think the best solution is Browserify:
module.exports = {
func1: function () {
console.log("I am function 1");
},
func2: function () {
console.log("I am function 2");
}
};
-getFunc1.js-
var common = require('./common');
common.func1();
window = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
});
I confirm. We must add:
webPreferences: {
nodeIntegration: true
}
For example:
mainWindow = new BrowserWindow({webPreferences: {
nodeIntegration: true
}});
For me, the problem has been resolved with that.
People are asking what is the script tag method. Here it is:
<script src='./local.js'></script>.
Or from network:
<script src='https://mycdn.com/myscript.js'></script>
You need plugin the right url for your script.
I was trying to build metronic using webpack. In my package.json I had to remove the "type": "module" section.

dojo 1.9 config with custom package paths

So I can see that the file was loaded properly from the dojoConfig reference but, when I attempt to use the module its 'undefined' any suggestions:
Updated: This will load the file, but when I throw the variable into a console nothing comes out. When inspecting it, I see a lot of text instead of the array of objs I placed inside.
index.html:
<script>
dojoConfig = {
tlmSiblingOfDojo: true,
async: true,
parseOnLoad: false,
packages: [
{ name: "main", location: "/components/3.6compact/js/dojo/dojo/main"},
{ name: "jquery", location: "/scripts/libs", main: "jquery"},
{name: "jam", location: "/scripts/mylibs", main: "lod"}
]
};
</script>
<script src="/components/3.6compact/js/dojo/dojo/dojo.js"></script>
<script src="/scripts/app.js"></script>
lod.js:
define([], function(){
var lod = [{
'level': 0,
'resolution': 156543.033928,
'scale': 591657527.591555
}, {
'level': 1,
'resolution': 78271.5169639999,
'scale': 295828763.795777
}
];
return lod;
});
app.js:*
require(['jam'], function(jam){
console.log(lod);
});
It's hard to provide an example on something like jsfiddle where we can't specify resources by file path, but I think the problem is with the module id in your javascript. In your dojoConfig, the location property defines the path to the directory where modules in that package can be located.
If your lod module is located at in /scripts/mylibs/lod.js, then you'd need to require lod/lod:
require(['lod/lod'], function(lod) {
console.log("lod module:", lod);
});
Here's the documentation for dojo config. I would look at the "Loader Configuration" section.
I attempted a jsfiddle anyway, which could be useful: http://jsfiddle.net/tupton/ftN6h/
Note the errors in the console:
'lod':
GET http://fiddle.jshell.net/scripts/mylibs/LOD.js 404 (Not Found)
and 'lod/lod':
GET http://fiddle.jshell.net/scripts/mylibs/lod.js 404 (Not Found)
I'm not familiar with the "main" property of the package config, but it looks like that's what it's using when you try to require an entire package. Maybe try changing that to "lod" so it looks for ".../lod.js"?

How to import dojo javascript file into worklight application?

When creating a new project, I have selected to include the dojo toolkit. I can import dojo.js using src="dojo/dojo.js". However when I try importing some other modules such as dijit.js using
require(["dijit/dijit"], function(){})
...I always get an error in the web console (ie the resource is not found). The problem is not applied when I import dojo modules. How can I fix this?
Make sure, you have configured Dojo correctly, kindly find the Dojo configuration which I have been using in my Hybrid App.
<script>
var dojoConfig = {
baseUrl: "js",
packages: [
{ name: "dojo", location: "dojo/dojo"},
{ name: "dijit", location: "dojo/dijit"},
{ name: "dojox", location: "dojo/dojox"}
],
isDebug: false,
async: true,
parseOnLoad: true,
deps:['app/main']
}
</script>
If you still not able to resolve it, try to make a sample use case or jsfiddle, would look into it further.
You made simple mistake of syntax:-
To require js file instead of require[("dojo/parser")]
you have use require(["dojo/parser"],function(parser){})

Categories