Using a JavaScript npm Package - javascript

tl;dr: I come from a Python background - where I would basically use pip install foo, then use the python interpreter to run code that uses foo. How does this translate to the world of JS?
I'm trying to use this package: https://github.com/skatejs/dom-diff
And execute this simple code example given by the author -
/** #jsx h **/
import { diff, h } from 'skatejs-dom-diff';
const source = <div><span>source</span></div>;
const target = <div><span>target</span></div>;
const instructions = diff(source, target);
Now I'm extremely new to the world of JS and just cannot figure out how I can run this code.
I was of course able to install this using npm install skatejs-dom-diff, but what now? I figured I might be able to run the code using node. So I saved the above code into foo.js and then executed node foo.js
% node foo.js
/Users/foo/Dev/DomDiff/skatejs_dom-diff/foo.js:2
import { diff, h } from 'skatejs-dom-diff';
^^^^^^
SyntaxError: Unexpected token import
When I tried to debug this, I kept going down the rabbit hole of Babel, JSX, ES6 etc etc, but to no real benefit since I'm even more confused still can't understand how to run this JS code.

What you are trying to use here is a syntax for EcmaScript, which is a super-set of JavaScript. In order to execute your ES code you need a transpiler like Babel in order to convert your code from EcmaScript to Pure JavaScript, which can then be understood by node or your browser.
But, I recommend you to use pure JavaScript if you don't need to follow an Object-Oriented paradigm or the salient features of EcmaScript, that allow JavaScript to become a multi-paradigm language.
You can check out the major differences between the 2 here.
You can visit this website to understand more about jsx and how to use it.
----Edit----
To fix your code you can follow these steps:
Open cmd and change directory to your project.
Type the command npm i -g browserify
Type the command npm i -D babelify babelify-preset-2015
Add the following code and save it as test.js
test.js
/** #jsx h **/
import { diff, h } from 'skatejs-dom-diff';
const source = h('div', h('span', 'source'));
const target = h('div', h( 'span' , 'target'));
const instructions = diff(source, target);
console.log(instructions);
Type the command browserify test.js -o bundle.js -t [ babelify --presets [ es2015 ] ]
Create a file index.html and add the following code to it.
index.html
<html>
<body>
<script src="bundle.js">
</script>
</body>
</html>
Open index.html in your browser and check the output in console (Right click->inspect->console)
Tada! :)

Related

How to use node Buffer module in a client side browser - detailed explanation required please

First things first. I know that there are other questions that are similar to this e.g. use NodeJs Buffer class from client side or
How can I use node.js buffer library in client side javascript
However, I don't understand how to make use of the reference to use browserify though it is given approval.
Here is my Node code:
import { Buffer } from 'buffer/';
I know this is the ES6 equivalent of require.
I would like a javaScript file implementation of this module so that I can simply use the standard html file reference:
<script src=./js/buffer.js></script>
And then use it as in for example
return new Buffer(temp).toString('utf-8');
This simply falls over with the
Uncaught ReferenceError: Buffer is not defined
no matter how I create the buffer.js file.
So using the browserify idea I've tried using the standalone script (from the https://www.npmjs.com/package/buffer as https://bundle.run/buffer#6.0.3 )
I've created a test.js file and put
var Buffer = require('buffer/').Buffer
in it and then run browserify on it as
browserify test.js -o buffer.js
and many other variations.
I'm not getting anywhere. I know I must be doing something silly that reflects my ignorance. Maybe you can help educate me please.
These instructions worked for me. Cheers!
Here are the instructions you can look at the web section.
https://github.com/feross/buffer
Here is what the instructions state about using it in the browser without browserify. So from what you tried
browserify test.js -o buffer.js
I would just use the version directly that does not require browserify
To use this module directly (without browserify), install it:
npm install buffer
To depend on this module explicitly (without browserify), require it like this:
var Buffer = require('buffer/').Buffer // note: the trailing slash is important!

Requiring normal javascript file from node compiled script?

Firstly, i want to state i'm very new to anything to do with node...
Before i state my issue, here is some example code to refer to.
test.js
//test.js
const myMessage = 'Bananas';
export default myMessage; // Im not to sure about this line (problem)
main.js
//main.js
const test = require('./test.js');
console.log(test.myMessage);
I want to require a normal external javascript script called test.js from a node compiled script called main.js. I have compiled main.js simply by typing node main.js in my terminal. But node spat out an error 'Unexpected token export'. I know I'm doing something wrong here. Do i use "Modules"? How do i exclude the export statement?
Thanks for reading, sorry if my problem is making people facepalm on how dumb this issue might seem.
I think the external file you are trying to require is esModule. Such files can't be directly required unless you transpile them to commonJSModule. You have two solutions.
Transpile esModule to commonJSModule using babel. (or change export to module.exports in your test.js)
If you use new node version you can change it's extension to .mjs (rename test.js to test.mjs)
Please take a look at this Medium article which should help.
https://medium.com/#giltayar/native-es-modules-in-nodejs-status-and-future-directions-part-i-ee5ea3001f71
The export syntax is not yet supported in Nodejs (its in an alpha version), instead Nodejs provides a global object* (module.exports) which is what you get back with the require() call, so you just have to set that objects property to the thing you want to export:
const myMessage = 'Bananas';
module.exports.myMessage = myMessage;
or shorter:
exports.myMessage = 'Bananas';
*global in the sense of "it exists although you haven't defined it", actually for every script that gets executed, a new module object will be created that can only be accessed inside of that script.
Use babel register: https://babeljs.io/docs/en/babel-register
npm install #babel/core #babel/register #babel/preset-env --save
And require it in your main.js:
require('#babel/register')({
presets: [
[
'#babel/preset-env',
{
targets: {
node: true
}
}
]
],
ignore: [
/node_modules/
]
});
This will parse other required files through babel which are not in node_modules, so ES6 import/export will work, and it will also polyfill features not present in your current version of node (node: true).
Note this should only be used if you have to require front-end scripts you can't reasonably modify. It's heavyweight to parse every require so if you do have to, make ignore as strict as possible (or even better use the only option) so you're only parsing what you need.

How to compile npm package from src (source) for both lib (module) and dist (browser)?

I'm writing a small class object in JavaScript that I wish to be able to use both for node applications but also as a standalone browser JavaScript file.
I think I've found a solution, but I'm not really sure if that's how it's supposed to be.
Let me try to explain how the directory looks.
Ok, I've got my main file inside a directory called src/index.js.
This file consists of a simple ES6 Class, which I export with ES6 export (following AirBnb Use Import/Export).
export default Person class {
constructor() {
// some code here...
}
getExampleMethod() {
// some code here...
}
}
Okay. So this code will not run in the browser because browsers do not support "export default" and it's ES6 so I should transpile it to ES5 using Babel.
But using Babel with --presets=es2015 will not cut out the "export default" so browsers will still throw an error. So I solved this using a package called "replace" which simply search and replaces that string before transpiling it using Babel.
In my package.json it looks like this:
"build:dist": "babel src -d dist --no-babelrc && replace 'export default ' '' dist/index.js && babel dist -d dist --presets=es2015",
So basically first moving the file, then removing the "export default " line, and the transpiling it... And this works!
For the lib directory I do this:
"build:lib": "babel src -d lib --plugins=add-module-exports,transform-es2015-modules-commonjs",
So basically move the file and transpile it, adding "module exports" and into a "commonjs" module.
This works... But it does not really feel like the way to do it? I've tried using Browserify, Webpack etc, but when doing that, I do not seem to be able to initiate a new object from my class? It gives me an error message saying "new Person()" is not defined or something similar to this.
How am I suppose to write my source code in plain ES6 style, transpiling it to both to be used in the browser and for node usage, while being able to have an API that looks like this: "var person = new Person();"?
Really, my question is maybe more aimed to be: How do I turn src/index.js into both browser and node compatible files?
Thanks a lot!

How to export a module

I started learning from https://egghead.io/technologies/es6 the ECMAScript 6 way, knowing there is still a lot that might change, but wanted to get a early start.
However, when I follow the tutorial instructions on (https://egghead.io/lessons/ecmascript-6-es6-modules-es2015-import-and-export) exactly the same, I get an error which I have no idea what I might have done wrong.
Uncaught ReferenceError: require is not defined
Code on that line after Babel converted to ES5
"use strict";
var _distExporter = require("dist/exporter");
console.log("2 + 3=", (0, _distExporter.sumTwo)(2, 3));
//# sourceMappingURL=importer.js.map
Developers are mentioning CommonJS and WebPack as a solution some even mentioned RequireJS, but nowhere in the tutorial did it state I should should code or use alternative libraries.
My HTML is this
<html>
<head>
<script src="dist/importer.js"></script>
</head>
<body>
</body>
</html>
My importer.js is
import { sumTwo } from "dist/exporter";
console.log( "2 + 3=", sumTwo(2,3))
And my exporter.js is
function sumTwo(a, b){
return a + b;
}
export { sumTwo };
I have no idea where I'm going wrong. I'm using BabelJS (https://babeljs.io/)
If you run this code under Node, rather than in a browser, you should see the results you are expecting. Node understands CommonJS require calls and will go away and grab that other file for you.
The browser has no idea that require is anything special. But we can use a tool to make the browser understand. Here's an example with Browserify, as some other people have mentioned you can also use WebPack, but I think the learning curve for WebPack is a lot steeper.
First you'll need a couple of modules.
npm install -g browserify
npm install --save-dev babelify
Then we can use these modules together like this.
browserify main-file.js -o output-file.js -t babelify
This will walk your source files checking calls to require in each one and adding the other files that it requires to the bundle. Then it runs the Babel transform over it, to convert ES6 to ES5. Finally it wraps it all up in some code that lets require work in a browser.

Transforming TypeScript into JavaScript

I'm wondering how is it possible to transform the TypeScript into JavaScript in a cross platform manner. I'm aware about availability of node package manager for typescript, but are there any other alternatives which can be used on the server side?
The TypeScript compiler is built in TypeScript, and hence is available as a JS file (tsc.js) that can be run using just about any ES3-compiliant VM or JS implementation.
That said, the compiler's current file I/O infrastructure only supports Node and Windows Scripting Host file APIs. If you'd like to recommend for support for another environment, feel free to reach out to the team at our GitHub site (Formerly CodePlex)
Short version: use Node if you can. It's becoming unavoidable nowadays.
Maybe it's not the answer you want, but as everybody mentioned, the compiler is a JS file, so, your options are the options of executing a JS file.
In Windows, there are 2 obvious ones, Node, and Windows Script Host.
You know about node already, the other option is a component that comes with all versions of Windows (I think), you can do it like this:
cscript path/to/tsc.js source-file.ts
You can see all compiler options by just:
cscript path/to/tsc.js
On Linux I assume you should be able to use (in addition to node):
V8 standalone shell, replace node or cscript with v8-shell
ExecJS https://github.com/sstephenson/execjs
Any other JS runner available on the selected platform (another answer mentioned Rhino for example)
Update: Another answer suggests the compiler API is only compatible with node and Windows Script Host (cscript tool), so, if correct, then on Linux you'll need Node to compile TypeScript.
If you are looking for something like apt get tsc (or whatever the Linux/Mac package managers are like), I think there isn't.
I remember reading somewhere that the I/O is optimized for Node and Windows Script Host, so, if you have problems with options, you'll probably end up with Node if seeking platform independence.
Update: Another answer here confirms the same about compatibility.
Concretely, on the server (assuming your server has Node.js available), you'd simply run:
node path/to/tsc.js yourFile1.ts yourFile2.ts [etc]
You can run that command without any input filenames to see the command-line help for tsc.js.
From the command line you can use ts-node:
npm install ts-node
Then call the command like this:
tsc file.ts --outFile file.js
I have a project which compiles Typescript to Javascript in Java:
https://github.com/martypitt/typescript4j
As discussed in other answers, this makes use of Rhino, so has no dependencies on npm or node.
Here's an example:
// Instantiate the compiler:
TypescriptCompiler compiler = new TypescriptCompiler();
// Compile a string:
String output = compiler.compile("class Greeter { greeting: string; }");
// Or, compile and output to a file:
compiler.compile(new File("example.ts"), new File('output.js'));
I use it in another project - 'Bakehouse' to perform on-the-fly compilation of typescript resources within Spring environments
If it's Java that you need to target then you could run tsc.js with the Rhino engine as part of your build process.
To compile ts -> js: node is available for all common platforms, so I fail to see why you'd want to have a tsc.java when you already have a tsc.js. Installing node is no big deal. In fact, it's easier than Java.
Once you have your proj.js file, you can then copy it to which ever deployment platform you wish to use.
From my point of view, JavaScript - or more accurately ECMAScript is an alternative to Java. So I'm happy that I don't have to wrangle JVM etc to use the tool. But if you prefer Java, then why even bother with JS?
SublimeText2 Trick
You can transpile typescript to javascript directly from SublimeText2 (you need node) :
Create a Typescript.sublime-build file in /Sublime Text 2/Packages/User with this content :
{
"cmd": ["tsc", "$file"],
"selector" : "source.ts",
"path": "/usr/local/bin:$PATH"
}
then, now, you can transpile your code with ctrl+B or cmd+B
I've been playing around with this, and can compile TypeScript with javascript with the following code:
<script src=typescript.js></script>
<script>
var scriptText = ""
+ "/// <reference path=\"test.ts\"/>" + "\r\n"
+ "class Car {"
+ " constructor (private name: string) { } "
+ " getName() { "
+ " var juice = new Juice();"
+ " return name; "
+ " } "
+ "} "
+ "var car = new Car('Subaru Impreza');"
+ "console.log(car.getName());";
var TextWriter = function () { };
TextWriter.prototype = {
collected: '',
Write: function (sc) {
this.collected += sc;
},
WriteLine: function(sc) {
this.collected += sc + '\n';
},
toString: function() {
return this.collected;
}
};
var output = new TextWriter();
var tsc = new TypeScript.TypeScriptCompiler(output);
var script = tsc.addUnit(scriptText, "");
tsc.emit();
console.log(output.toString());
</script>
It's not exactly ideal though. I'm trying to get something running so I can convert TypeScript to JS within C# (using Javascript .NET), but i'm getting a stack overflow on the ts.addUnit call.
You probably don't wanna use ts-node, because it is slow, instead follow following steps for fast .ts files compilation (Make sure node is installed):
npm i -D #types/node typescript nodemon
npx tsconfig.json and select node from the list. You are free to modify it as per your needs.
Create a file names src/index.ts in your project root.
Then in your package.json, add the following 2 scripts:
"scripts": { "watch": "tsc -w", "dev": "nodemon dist/index.js" },
Then use:
npm run watch
npm run dev
And, it will automatically look for changes in .ts files and you can see the compiled file output in the terminal as you go!
This is what worked for me:
First, installed the typescript node module >> npm install -g typescript. This gives a command line utility tsc.
Next, tsc gulpfile.ts gulp-config.ts typings/tsd.d.ts
this will transpile the gulpfile.ts and gulp-config.ts files to gulpfile.js and gulp-config.js. We supply the typings/tsd.d.ts file as reference for correct transpilation.
The typescript node module covers many options >> tsc -h to specify output directory or file, etc..
If you are using "firebase -tool" you can use
npm run build
inside your functions directory.

Categories