Browserify npm library - javascript

I have a well tested npm library (https://www.npmjs.com/package/yuml-diagram) that I would like to Browserify so it can be used in browser applications.
The full source code is here: https://github.com/jaime-olivares/yuml-diagram
I managed to build the library as a monolithic package with the following command line:
browserify index.js -g uglifyify -o ./dist/yuml-diagram.min.js
Then I tried to use it in a similar fashion as in Node-JS, as suggested in several places:
<html>
<head>
<script src="https://gist.githubusercontent.com/jaime-olivares/5cd18b40f2bdcf5e403ed78d181c3d85/raw/00f5624fe30500a22144962184e927236f1ac45f/yuml-diagram.min.js"></script>
<script>
function loadSvg()
{
var yuml_diagram = require('yuml-diagram');
var yumlText =
`// {type:sequence}
[:Computer]async test>>[:Server]
[:Computer]sync test>[:Server]`;
var yuml = new yuml_diagram();
var svg = yuml.processYumlDocument(yumlText, false);
document.body.innerHTML = svg;
}
</script>
</head>
<body onload="loadSvg();">
</body>
</html>
The require() function is not recognized, even if I use the flag --exports require in Browserify.
How can I invoke the library's processYumlDocument() function from the application script?

Browserify does not add support for require onto your page. Browserify is used on a javascript file that is using resolve internally and produces a version with the resolves statically included.
In your example you should move the content of your script block into a javascript file and then execute browserify on that file. Then include the final produced file in your page.

Found my own answer. It is required the standalone parameter in Browserify, as here:
browserify index.js --standalone yuml_diagram -g uglifyify -o ./dist/yuml-diagram.min.js
Where yuml_diagram represents the whole bundle. Then the library can be used with a couple of lines:
<html>
<head>
<script src="../dist/yuml-diagram.min.js"></script>
<script>
function loadSvg()
{
var yumlText =
`// {type:sequence}
[:Computer]async test>>[:Server]
[:Computer]sync test>[:Server]`;
// Create the object and invoke a function inside it
var yuml = new yuml_diagram();
var svg = yuml.processYumlDocument(yumlText, false);
document.body.innerHTML = svg;
}
</script>
</head>
<body onload="loadSvg();">
</body>
</html>

Related

function is not defined, when it is

today i was working on a project, and i got this error.
Uncaught ReferenceError: launch is not defined
at HTMLInputElement.onclick (home.html:77)
i don't understand what i did wrong here..
Here is the index.js file:
function launch() {
console.log('test');
}
module.exports.launch = launch;
and home.html:
<script>
let func = require('./index');
let launch = func.launch();
document.getElementById('lanBTN').addEventListener('click', () => {
launch();
});
<input type="button" value="Launch!" id="lanBTN" onclick="launch()">
</script>
Any ideas why this is happening..?
Require is a commonjs module specification, it doesn't work on the browser unless you use some bundler like webpack or browserify to resolve the dependencies between all of you modules and bundles one single js file to include in your html
As #mehdi-belbal mentioned you can not use CommonJS in HTML files expect if when using module bundlers like Webpack.
Besides of that module.exports is useless here, try to link your javascript module in the head of the document. and the declared function after. that will attach to the window object and you can use them both by using window.func() and ‍func()
<head>
<script src="./index.js"></script>
</head>
<body>
...
<script>
func();
</script>
</body>

Is there a way to replace some javascript variables (at build time?) with some DEV or RELEASE config data?

I have a really simple website (ASP.NET core) that is a single .html static page and 6 .js files.
In one of the js files are some data that is based on my configuration:
localhost
dev
production
right now, it's hardcoded for my localhost.
Is there way that I can build/package the simple app so that if i say dev or prod in some command line arg, it replaces those values with something from somewhere else?
eg.
in main.js:
var environment = "localhost";
var rooturl = "https://localhost:43210";
and lets imagine i wish to build to my dev server...
var environment = "dev";
var rooturl = "https://pewpew.azurewebsites.com";
Is this possible? To keep things simple, assume I know nothing of JS tools and processes. (it's actually the truth, but lets not tell anyone that).
Update (further clarifications):
with 1x static html file and 6x static JS files, I have a static website. So i'm hoping to generate the js files as static files (still) but with the environment data already compiled in it.
you can use some build tools like grunt. where you can define build task which takes the environment parameter and change the variables to the desired values.
another (more simple) way is to dynamicaly create main.js (with dependency on the environment) file with your backend and the frontend will load it when it starts. src of the script tag can be the asp script, where the output is javascript
This is a snippet from a project in which I do just that. I replace various place holders with values stored in the environment variables.
This example is based on a linux environment, so I used sed to modify the file in-place, however you could just as easily read the file into memory, do the replace and write it back to disk.
grunt.task.registerTask('secretkeys', 'Replace various keys', function() {
var oauth;
try{
oauth = JSON.parse(process.env.oauthKeys).oauth;
}
catch(e){
oauth = {google:{}};
}
var replaces = {
'==GOOGLECLIENTID==':oauth.google.client_id || '{**GOOGLECLIENTID**}',
'==GOOGLESECRETKEY==':oauth.google.client_secret || '{**GOOGLESECRETKEY**}',
'==SECRETKEY==':oauth.secret || '{**SECRETKEY**}',
'==LOCALAUTH==':oauth.login,
};
const child = require('child_process');
grunt.file.expand('bin/**/*.json').forEach(function(file) {
grunt.log.write(`${file} \n`);
for(var key in replaces){
var cmd = 'sed -i s~{{orig}}~{{new}}~g {{file}}'
.replace(/{{file}}/g,file)
.replace(/{{orig}}/g,key.replace(/~/g,'\\~'))
.replace(/{{new}}/g,replaces[key].replace(/~/g,'\\~'))
;
grunt.log.write(` - ${key} \n`);
//grunt.log.write(` ${cmd} \n`);
child.execSync(cmd);
}
});
});
Hopefully you can modify to your purposes.
EDIT : I am reconsidering my answer, you are modifying javascript on a windows environment. You are likely better using PowerShell
(gc script.js) `
.replace("==GOOGLECLIENTID==",$Env:GoogleClientId) `
.replace("==SECRETKEY==",$Env:SecretKey) `
> script-build.js
So after re-reading your question, I realize there is a better solution that I have used in the past. My other answer is still relevant, so I'll leave it.
It may be simplest to just create a config file in the same folder.
<html>
<head>
<script type="text/javascript" src="config.js" ></script>
<script type="text/javascript" src="myscript.js" ></script>
</head>
<body>
ask me your questions, bridgekeeper
</body>
</html>
config.js
var config = {
'colour': 'yellow'
};
myscript.js
var user = prompt("What is your favourite colour?", "");
if(user !== config.colour){
alert("No BLUE! Ahhh....");
}
else{
alert("You may pass");
}
This is the technique I use when developing simple HTA apps for use around the office.
Check out envify. You can run it from the command line. https://github.com/hughsk/envify
sudo npm install -g envify
Say you have
var myVar = process.env.MYVAR;
Run from the command line
MYVAR=somevalue envify input.js > output.js
and the output js file should have
var myVar = 'somevalue';

Can't load Backbone.DOMStorage using require keyword

I need some help because i'm fairly new to javascript and nodejs world and i'm stuck..
I have a nodejs app project where I installed dependencies (npm install) and then in my .js file, I load my modules like : var Backbone = require('backbone') and it works well.
But then i tried to install Backbone.DOMStorage (https://github.com/mikeedwards/Backbone.DOMStorage) module...
I did npm install https://github.com/mikeedwards/Backbone.DOMStorageand installation was Ok (js file is present in the node_modules folder), but when I try to load it with require('Backbone.DOMStorage') it failed to find and load the module...
From what I understood after many searches, it seems that the plugin isn't CommonJS compliant..
So how can I transform this script to be able to use it like any other module ??
Thanks !
I will show you 4 ways do what you want.
First way
Its a js plugin that's why you need to add it to your HTML page like this.
Include Backbone.domStorage after having included Backbone.js:
<script type="text/javascript" src="backbone.js"></script>
<script type="text/javascript" src="backbone.domStorage.js"></script>
and use it like this
window.SomeCollection = Backbone.Collection.extend({
localStorage: new Backbone.LocalStorage("SomeLocalCollection"), // Unique name within your app.
// ... everything else is normal.
});
Second way
If you're using browserify.
Install using npm install backbone.localstorage, and require the module.
Backbone.LocalStorage = require("backbone.localstorage");
third way
RequireJS
Include RequireJS:
<script type="text/javascript" src="lib/require.js"></script>
RequireJS config:
require.config({
paths: {
jquery: "lib/jquery",
underscore: "lib/underscore",
backbone: "lib/backbone",
localstorage: "lib/backbone.localStorage"
}
});
Define your collection as a module:
define("SomeCollection", ["localstorage"], function() {
var SomeCollection = Backbone.Collection.extend({
localStorage: new Backbone.LocalStorage("SomeCollection") // Unique name within your app.
});
return SomeCollection;
});
Require your collection:
require(["SomeCollection"], function(SomeCollection) {
// ready to use SomeCollection
});
forth way
Download js file from GitHub and put it to your library files directory after require it us js file like this
var domStorage = requier('yourLibPath/backbone.domStorage.js');

ReferenceError: "require" is not defined

I am a beginner to node js and angular js.
I have a string which is html text and i want to convert it to jade.
I can do this with node js module 'html2jade' but when I am writing my code in js file (in controller), it is giving me a 'require' is not defined error.
This is the code:
app.controller('comicController', function($scope, resources) {
$scope.searchComic = function() {
resources.routes.charactersAPI.fetch({title: $scope.title}, function done(response) {
console.log(response);
$scope.comic = response;
//$scope.comic.description
require('html2jade').convertHtml($scope.comic.description, {}, function (err, jade) {
$scope.desc = jade;
});
});
};
});
Any help is appreciated. Thanks in advance!
You require a module on your build process.
Browsers don't have the require method defined, but Node.js does. With Browserify you can write code that uses require in the same way that you would use it in Node.
Install browserify
npm install -g browserify
Write a module
// hello.js
module.exports = function(name) {
return 'Hello ' + name + '!';
}
Use the module
// app.js
var greetings = require('./hello');
alert(greetings('Christophe'));
Create the bundle
browserify app.js -o bundle.js
Refer your bundle
<html>
<body>
<script src="bundle.js"></script>
</body>
</html>
Browserify is a tool that lets you bundle node.js modules and consume them in the browser. In other words, it allows you to write browser-based applications using node.js-style requires.
You can check here for reference.

Global require with Browserify v2

I want to use Browserify to bundle my files, but I then need to require one of the modules inside of my Browserify bundled bundle.js on the HTML page itself. This is currently not possible because there is no require function defined on the page.
It appears that the require function defined by browserify in bundle.js is inside of an IIFE, so I can't use that. Is it possible to throw this one out in place of a global require?
<script src="bundle.js"></script>
<script>
// Require the `app` module inside of `bundle.js`
var app = require('app');
app.start();
</script>
I need to do this because my app.start function requires some JSON is passed to it which can only be rendered by the server-side template.
N.B. I am using Browserify v2.
You can use -r to expose a global require() function for the files you specify:
x.js:
module.exports = function (n) { return n * 111 }
Console
$ browserify -r ./x.js > bundle.js
then in your html:
<script src="bundle.js"></script>
<script>
var x = require('./x.js');
console.log(x(3))
</script>
will print 333.
In your case, just do browserify -r app to expose require('app') to the external context.

Categories