Accessing module.exports with a browserified node app - javascript

We are trying to Browserify our node app
Sample File (index.js)
module.exports = {
index: () => 'test',
};
Browserify command
browserify src/index.js > dist/bundle.js --node
If we use a file to require and console
console.log(require('src/index')); // { index: [Function: index] }
console.log(require('dist/bundle')); // { }
Our expectation is that bundle.js would export the same as index.js.
Can anyone point us at what we are doing wrong or missing?
Additional Info
~This is not our app, this is a sample to demonstrate the issue
We are currently sending our entire app zipped to AWS Lambda with the entry point src/index.index and the objective is to just send the bundle.js file and be able to to have the entry point bundle.index
bundle.js
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
module.exports = {
index: () => 'test',
};
},{}]},{},[1]);

You need to use the --standalone flag. If I reproduce the setup you describe in your question and execute:
$ browserify src/index.js --standalone mylib > dist/bundle.js
Then I can run an interactive Node session on it and use the library in the way you expect it to be used:
$ node
> require("./dist/bundle").index()
'test'
The --standalone flag tells Browserify to wrap your code in a UMD stub which allows loading the bundle as CommonJS module, an AMD module, or as a plain script (i.e. does not use a module system). The argument you pass with --standalone indicates what name your library will take in the "plain script" case. So in the example above, if you were to load the library in a browser without any module system, you'd be able to run index as mylib.index().

You can use serverless for this, pretty easy to configure. No need to use browserify cli for this.
Keep following following official documentations to setup serverless cli.
Installation
AWS - Credentials
Quick Start
Once everything is setup and you are able to deploy your lambda functions to AWS using serverless cli. Follow following steps to setup browserify.
Install browserify as a dev dependecy.
Install serverless-plugin-browserifier as a dev dependency.
Add the plugin to your serverless.yml file and set package.individually to true. (Ref)
plugins:
- serverless-plugin-browserifier
package:
individually: true
Note: Personally tried this and is working.

Related

Node.js require webpacked modules

I'm trying to get rid of the thousand files you get once you npm install various modules having their own dependencies.
Thus I was thinking of compiling only the libraries using webpack into one javascript file (and other required resources), then loading it to the Node.js project this way :
Entry point, that will be compiled to bundle by webpack.
module.exports = {
lodash : require('lodash'),
colors : require('colors'),
test : require('test'),
abc : require('abc')
} ;
Main
var { lodash, colors, test, abc } = require('./lib/bundle') ;
The problem I got is that some modules require system (or uncompilable) modules, such as fs, and webpack tries to bundle them to.
You just have to specify in the webpack.config.js file :
node: {
fs : "empty",
electron : "empty"
}
However, once packed into bundle, it seems that every require('fs') is replaced by Object.freeze({}) because of this setting, and then the modules fail using fs.
Would anyone have a solution for using packed modules in a Node.js project ?
P.S.: I tried using yarn with yarn autoclean --force to remove all unnecessary files, but it only removed 5% to 10% of the total.
The problem using the current node config object and set fs: 'empty' is that it will provide an empty object for those modules. More info about Webpack Node here.
You can set the Webpack target property to 'node'
Compile for usage in a Node.js-like environment (uses Node.js require to load chunks and not touch any built in modules like fs or path)
module.exports = {
target: 'node'
};
Read more about Webpack Targets
Also, to import a built-in module, use __non_webpack_require__
Generates a require function that is not parsed by webpack

How to pass browserify --require file to angular module?

I have engineered a build for an Angular SPA using NPM to call the browserify script to bundle it, i.e. you can run from the terminal npm run build:js which calls the following script in package.json:
"build:js": "browserify -r ./params-dev.js -e src/app/index.js -o build/index.js"
What I'm trying to do now is to create two different config objects for prod and QA. Each one will require a different file: params-dev.js or params-prod.js (like in the command above).
I am wondering how to access these variables in the resulting bundle? They are environment specific and some of it points to analytics codes, etc. Furthermore, I'm trying to move them out of the global scope, where they currently live.
Here is a sample of the params files I'd like to include with the bundles. There will be one for prod and one for QA:
var merge = require('merge'),
params = require('./params')
exports.config = merge(params, {
env: 'prod',
analyticsCode: 'blah08yweblah2e823lnblah',
otherProps: '...etc...'
})
So how do I access these variables now in my AngularJS module? I feel like I'm missing something obvious here.
Anyone have any ideas? Please let me know if you need more info.
In case it helps, my index.js looks like
(function () {
// common app require statements
require('blah')
require('blah-2')
angular.module('app', [require('angular-route')])
// etc etc
})()
I figured it out. :) If I add the target to the end of the required file path in the command like so:
"build:js": "browserify -r ./params-dev.js:params -e src/app/index.js -o build/index.js"
I can access the object by adding var params = require('params') to my angular file.

Gulp with browserify: Cannot find start module

I have pretty much the exact same problem as described in Gulp with browserify: Cannot find module src/js/main.js: I have a JavaScript project that I can build using browserify from the command line, but not in gulp. But the solution for that question does not work for me.
From the command line:
browserify -t reactify ./js/inspector > static/js/inspector.js
works perfectly. When I run the following gulp task:
gulp.task('browserify', function() {
return browserify({
transform: ['reactify'],
entries: ['./js/inspector.js']
})
.bundle()
.pipe(source('inspector.js'))
.pipe(gulp.dest('./static/js/'));
});
and run it, I get the following error in the console:
Error: Cannot find module '../../inspector'
and also the generated file has the same length as the CLI file but not the same order of modules. Which puzzles me.
I have the same version of browserify in my global and local modules, and I've not knowingly configured it, anywhere.
Unlike Ben Davis, who asked the other question, adding a ./ to the start of my path changes nothing.
I don't understand why browserify gives a different, and broken, output, when run through gulp.
Update: The directory structure of the project:
gulpfile.js
node_modules/
js/ (also contains subdirectories with JS code)
inspector.js
static/
js/
inspector.js (built)
Update: When I run Browserify through Grunt, I also get a different file, but it works.
You can try wrapping your return function in an IIFC.
//======================================
// Task: browserify
//======================================
gulp.task('browserify', function() {
return (function() {
browserify(config.src)
.bundle()
.pipe(source(config.name))
.pipe(gulp.dest(config.dest));
})();
});
I am using the above successfully in a current proj.
I had other modules that required the root module, à la:
var inspector = require('../../inspector');
This is what caused the problem (somehow). Putting in a root module that was never required by anything else made gulp + browserify work without any problems.
I'll see if I can create a minimal reproduction project for the gulp / browserify maintainers.

How to use npm modules on grunt?

Earlier when I was using node.js without grunt I had to simply write the following code to include an external module.
var express = require('express');
After I switched to grunt I am trying to use the following module qr-image.
I am stuck with the use of this module as whenever I use the following command my code breaks.
[ This is as per an official example. ]
var qr = require('../');
To Install this module in my node_modules directory I changed the package.json by adding the following dependency in
"devDependencies": {
.
.
.
"qr-image": "^2.0.0"
},
And then ran npm install command at the root directory level of my app.
Thus, Stuck with the implementation of this node.js qr-image module on grunt. Any help will be appreciated.
I believe the right way to do this is:
var qr = require('qr-image');
You can find an example in the project's readme.

How do I use a NodeJS package with RequireJS?

I would like to use the the node-bencoding package with my current RequireJS project setup, but I have been unable to get it configured.
I have followed these instructions and have ran:
npm install requirejs
npm install node-bencoding
Then in my app.js file I had changed it:
var requirejs = require('requirejs');
// Place third party dependencies in the lib folder
//
// Configure loading modules from the lib directory,
// except 'app' ones,
requirejs.config({
nodeRequire: require,
"baseUrl": "assets/js/lib",
"paths": {
"app": "../app",
"jquery": "https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min",
"angularjs": "https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min"
},
});
However when I load the page I get the error:
Error: Module name "requirejs" has not been loaded yet for context: _. Use require([]) http://requirejs.org/docs/errors.html#notloaded
I'm not exactly sure where I should have my node_modules directory. My directory structure is as follows: all my JS files are contained within src/assets/js - there is assets/js/app and assets/js/lib as is the RequireJS convention. Currently I have put my node_modules directory in src/.
Looks like you are trying to use it in a browser. And your application is not server side JavaScript, so RequireJS usage sample in a Node does not apply. In this case you would like to use node only to optimize your scripts.
I recently blogged about Understanding AMD & RequireJS, it might be useful.

Categories