Use an NPM module directly in the browser - node.js

This might be a stupid question, or the answer is so obvious that I just couldn't find it.
Basically I want to use Redux in my very simple web app. I wanna be able to include redux like this :
<script type="text/javascript" src="js/redux.js"></script>
And just use it directly in my code like this :
var store = redux.createStore(...);
I tried webpack and browserify but I couldn't make it work. Any ideas ?

To import Redux via a <script> tag you have to use the UMD builds.
According to the docs, they are present on the dist/ folder.

I got Redux working with their pre-built UMD files.
But to use other NPM modules directly in the browser here's what to to (I don't know if this is the correct method but it worked for me) :
1- Create a simple file main.js with :
window.Redux = require('redux');
2- Install browserify globally :
npm install -g browserify
3- Browserify the file from the command line (no config files) :
browserify main.js -o redux.js
Now just include redux.js as a <script> tag

If you want to include the package directly on the browser for a smaller use case you could use unpkg.com which is a fast prepackage list of everything available on NPM (per the claim on their website)

Related

how to use require in main.js

I try to use axios in my main.js.
i tried import axios from 'axios'. ... I got error for import. I read here that I should use require instead of import.
after that I tried
var axios=require('axios');
but I got the error ....require is not defined.
after that I read about browserify. I installed it
npm install -g browserify
after that I used this code to bundle it
browserify main.js -o bundle.js
and I add this script to my index.html code.
<script src="bundle.js"></script>
but I got the same error
REQUIRE IS NOT DEFINED!!
I am actually confused. can somebody HELP ME!
appreciated
By default require() is not a valid function in client side Javascript and is primarily used in server side Node.js. I recommend you look into require.js as this does extend the client side to provide you with that function. Or else go with ES6 import.
npm install axios --save-dev
will help you to solve problem

browserify will not compile express js

I wrote a very basic express.js app. Then tried to make it one .js file. Browserify compiled the whole thing to a one file. But browserify-compiled code didn't work. As far as I know, browserify just replaces require statements with module codes. Error is:
C:\Users\HP\n\express\app.js:27025
__proto__: http.IncomingMessage.prototype
^
TypeError: Cannot read property 'prototype' of undefined
at Object.__dirname.173.accepts (C:\Users\HP\n\express\app.js:27025:34)
at s (C:\Users\HP\n\express\app.js:1:316)
at C:\Users\HP\n\express\app.js:1:367
at Object.__dirname.170../application (C:\Users\HP\n\express\app.js:26823:11)
at s (C:\Users\HP\n\express\app.js:1:316)
at C:\Users\HP\n\express\app.js:1:367
at Object.__dirname.168../lib/express (C:\Users\HP\n\express\app.js:26154:18)
at s (C:\Users\HP\n\express\app.js:1:316)
at C:\Users\HP\n\express\app.js:1:367
at Object.__dirname.153.express (C:\Users\HP\n\express\app.js:24010:15)
Browserify is designed specifically to package code for a browser.
Node.js supports a number of modules that a browser doesn't which have to be emulated by builtins. These modules will be replaced by a browser-specific shim. Some only supply a subset of the Node API that makes sense to have in a browser.
So you are running an app that has converted all the Node.js modules to support running what it can in a browser, back in Node where the modules are available but are no longer being used.
Try rollup or you could possibly configure babel to work like you need
I had this very same issue but like you said the compile code should work on server side. I solved it from this link:
https://www.linkedin.com/pulse/bundling-nodemodules-your-nodejs-app-one-single-file-xuan-son-nguyen/
Use browserify for bundling and terser for minifying. Starting by installing them globally:
npm install -g browserify
npm install -g terser
Next, we have to add a build script to package.json
...
"scripts": {
...
"build": "browserify --node --ignore-missing index.js | terser > bundle.js"
}
...
Each time you want to promote to production, you have to make a new bundle:
npm run build
A new file called "bundle.js" will be created.
Let there be peace, and there was peace. Happy coding.

How to fetch modules from npm as standalone AMD/CommonJS modules

So, I'm not using Node or WebPack serverside, but would still like to use modules from npm every now and then. My clientside uses requirejs, so I would need the modules in either AMD (preferred) or CommonJS.
What I want to archieve is a script that takes the module name + "external dependencies" as arguments and creates a module that contains all the other deps.
E.g.
sh npmtoamd.sh draft-js react react-dom
It creates an ES5 AMD module that contains draft-js and all of it's dependencies excluding react and react-dom. If it's not possible to eg. include css files and other non-js content in the module, providing them in eg. draft-js.css is tolerable.
While I don't use Node or Webpack serverside, we can use npm and webpack in the said script.
Fetching the module from npm is the trivial part, but I'm pretty lost in how to do the webpack parts. I know for a fact that it's possible though, as I managed to do it earlier with help, just don't have it down anywhere and no idea how it went.
I think as elmigranto commented, Browserify is what you're looking for. Unlike its name implies, it can be used in both the browser environment and the node environment. In a nutshell, it does this:
Browserify starts at the entry point files that you give it and searches for any require() calls it finds using static analysis of the source code's abstract syntax tree.
For every require() call with a string in it, browserify resolves those module strings to file paths and then searches those file paths for require() calls recursively until the entire dependency graph is visited.
Each file is concatenated into a single javascript file with a minimal require() definition that maps the statically-resolved names to internal IDs.
This means that the bundle you generate is completely self-contained and has everything your application needs to work with a pretty negligible overhead.
If you check out some of the demos you can see that all the dependencies (and their co-dependencies) are bundled into one file.
A simple example:
browserify main.js -o bundle.js
In regards to using AMD as well Browserify supports it by using deamdify.
Using AMD modules:
browserify -t deamdify main.js -o bundle.js
I ended up doing the npm fetch thingy in java instead of a batch script and finally got it working. Didn't get browserify to work however.
Heres what I do:
creating the following webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js',
library:"<modulename>",
libraryTarget:"amd"
},
externals: {
react: "React",
"react-dom": "ReactDOM",
immutable:"Immutable",
moment:"Moment"
}
};
npm install <modulename>
Creating the following main.js
define('FOOBAR', ['<modulename>'], function(Foo) {
return Foo;
});
Running webpack main.js

Meteor leaderboard app on node-webkit

I am trying to get the meteor leaderboard app to run on Node-Webkit.
I have demeteorized it and compressed it to a .nw file but when I drop it in. I get errors:
Invalid Package There is no 'package.json' in the package, please
make sure the 'package.json' is in the root of the package.
I have read on various thread but nothing clear yet.
It seems like the demeteorized app needs to be restructured. Also need to figure out how to run the server [Locally/DDP].
Edited:
P.S. I am using the demeteorized files from the leaderboard meteor app to be able to run it in node-webkit.
What exactly I am trying to figure out here is :
how to run/init the local node(demeteorized) server and set the port.
How to set environment variables for the demeteorized app for mongodb etc.
What would be used as the
"main": ?,
"node-remote": ?
for the node-webkit package.json file.
Can someone please shed some light and if possible an example will be highly appreciated.
Thanks in advanced.
Praney :)
UPDATE:
After tinkering a bit, I added the "main": "index.html" and added index.html file to the root of the demeteorized app. This file just loads the main.js file in the browser, here:
<!DOCTYPE html>
<html>
<head>
<title>Leaderboards</title>
</head>
<body>
</body>
<script src="main.js" type="text/javascript"></script>
</html>
Now I am getting this error:
"Uncaught ReferenceError: __dirname is not defined", source:
file:///Users/Praney/projects/webkit/nw-sample-apps/leaderboards/main.js(2)
main.js
process.argv.splice(2, 0, 'program.json');
process.chdir(require('path').join(__dirname, 'programs', 'server'));
require('./programs/server/boot.js');
This isn't how demeteorizer is meant to be used.. exactly/kind of.
You would use the output bundle on your deployed server to run as your meteor app, not put it in an existing meteor app.
The package.json that you get from it is slightly different to the one that meteor-npm would use.
When you've finished your meteor app you would use demeteorizer to create an easy bundle that can run on your server. If you uploaded it and untarred it:
You would install the npm modules by cding into the bundle and running npm install
You can run the app as normal as described in the docs.
The whole purpose of demeteorizer is to nodify your app, you wouldn't need to this on the platform you made it since all the npm modules would already be working. The problem it solves is usually with cross-archs, e.g if you made your app on OS X and it uses binary npm modules and the server uses Ubuntu (not os x)
I suppose node-webkit could also do it, you would need to use the root directory of demeteorize for this (seperate from your app). You can see there's a package.json already in it, perhaps the root directory you set it to use is that of your meteor app and not the untarred output of the demeteorized app?

Node.js use installed package in public/javascripts file

I have installed a package using 'npm install package-name' and now I am wondering how I can use this package in my global.js file which is in the public/javascripts folder?
I have tried using 'var name = require('package-name');' in the global.js file however this does not seem to be working. Am I meant to reference the package some place else?
Any help would be appreciated. Thank you.
So the short answer is use the browserify. Really understanding all the implications of sharing code between node and the browser is somewhat of a lengthy topic, so please take the time to read the tutorials and the handbook. But the basic idea is
in your global.js file, load the module from node with var name = require("package-name"); as you are doing.
Transform your file with browserify a la browserify public/javascripts/global.js > public/javascripts/main.js
change your HTML <script> tag to load the new main.js file.

Resources