Importing JavaScript Library into NativeScript - javascript

I am learning NativeScript. I have a basic app working. I am now trying to import a JavaScript library that I've used in the past. I'm importing the library by using:
npm install git://github.com/my-company/my-project.git --save
I've confirmed that the package is being installed. In my view model, I then add the following:
var MyLibrary = require('MyLibrary');
That line alone causes the app to crash. Basically, NativeScript cannot seem to find it (or load it). I looked, and I can see the "MyLibrary" directory in the "node_modules" directory. The directory structure looks like this:
.
node_modules
MyLibrary
dist
MyLibrary.min.js
src
MyLibrary.js
package.json
The MyLibrary.js file looks like this:
class MyLibrary {
process(vals) {
let result = 0;
if (vals) {
vals.forEach(function(val) {
result = result + val;
});
}
return result;
}
}
module.exports = MyLibrary;
The "MyLibrary.min.js" file is the result of running it through Babel and converting it to ES5. What am I doing wrong? I'm just trying to get the following code into my view model:
var MyLibrary = require('MyLibrary');
var library = new MyLibrary();
var result = library.process([1, 2, 3, 4]);

In your package.json, add a property like this :
{
"main": "./dist/MyLibrary.min.js"
}
In your code, use your module like this :
var MyLibraryModule = require('MyLibrary');
var library = new MyLibraryModule.MyLibrary();
var result = library.process([1, 2, 3, 4]);

Related

Rename webpack/gatsby chunkmapping strings

When building our production app in Gatsby, I see something like this:
window.___chunkMapping={
"app":[],
"component---src-templates-page-tsx":[],
"component---src-templates-pages-newsletter-tsx":[]
}
Is it possible to hash these paths instead of printing them out? We don‘t want to expose too much from what is happening in the back.
I tried setting these configs in webpack:
output: {
filename: `[chunkhash:2][contenthash:5].js`,
chunkFilename: `[chunkhash:2][contenthash:5].js`,
},
And it successfully hashes .js files but not the template paths.
I upvoted this question when I first saw it, I think it's definitely should be done in production build.
Unfortunately, componentChunkName (the template path in question) is generated by Gatsby in createPage & not handled by webpack.
The code that generates componentChunkName is over here: github
I tried to modify the code as follow:
const { kebabCase } = require(`lodash`)
const path = require(`path`)
+ const uuidv5 = require(`uuid/v5`)
const { store } = require(`../redux`)
const generateComponentChunkName = componentPath => {
const program = store.getState().program
let directory = `/`
if (program && program.directory) {
directory = program.directory
}
const name = path.relative(directory, componentPath)
- return `component---${kebabCase(name)}`
+ return process.env.NODE_ENV === `production`
+ ? `component---${uuidv5(name, uuidv5.URL)}`
+ : `component---${kebabCase(name)}`
}
exports.generateComponentChunkName = generateComponentChunkName
This successfully hides all the component names in production build:
app: Array [ "/app-e593b3d93932ed3a0363.js" ]
"component---11d478fe-6a55-579c-becf-625ab1e57cf4": Array [ "/component---11d478fe-6a55-579c-becf-625ab1e57cf4-76c90ae50035c52657a0.js" ]
"component---15c76861-b723-5e0a-823c-b6832aeeb0a0": Array [ "/component---15c76861-b723-5e0a-823c-b6832aeeb0a0-18eb457ba6c147e1b31b.js" ]
...
None of the local unit tests failed, my clicking-around-until-something-breaks test also hasn't yielded any errors. I might submit a PR later today to see if the maintainers have some insights on why this is not a good idea.
Edit: I opened an issue instead: github, you can subscribe to the issue to see how it resolves.

Electron: Load a file with `executeJavaScript`

I need to inject an NPM package into a BrowserView by using executeJavaScript. The package is Web3 and here is what I've tried so far.
import Web3 from 'web3'
const web3 = '' + Web3; // stringify the Web3 class
view.webContents.executeJavaScript(`
const provider = // ... provider got injected successfully because it doesn't have dependencies.
const web3 = new ${web3}(provider);
`)
But this throws the following error.
Uncaught ReferenceError: core is not defined
at new Web3 (<anonymous>:45:5)
at <anonymous>:41:16
Web3 is trying to load its core dependency which unfortunately did not get stringified.
So my question is, how can I load this whole package into the BrowserView? Aka how can you load npm package in the browser, if you do not have control over <script /> tags (at least I wouldn't know how to inject those in Electron)?
Update:
Because of what OJ Kwon suggested in the comments, I tried bundling Web3 with Browserify by running
browserify packages/web3/src/index.js -o web3-bundle.js
. It seemed to have worked, because at the very end of the bundled file (web3-bundle.js) it says:
// ... 50k+ lines long file
var version = require('../package.json').version;
var core = require('web3-core');
var Eth = require('web3-eth');
var Net = require('web3-net');
var Personal = require('web3-eth-personal');
var Shh = require('web3-shh');
var Bzz = require('web3-bzz');
var utils = require('web3-utils');
var Web3 = function Web3() {
var _this = this;
// sets _requestmanager etc
core.packageInit(this, arguments);
this.version = version;
this.utils = utils;
this.eth = new Eth(this);
this.shh = new Shh(this);
this.bzz = new Bzz(this);
// overwrite package setProvider
var setProvider = this.setProvider;
this.setProvider = function (provider, net) {
setProvider.apply(_this, arguments);
this.eth.setProvider(provider, net);
this.shh.setProvider(provider, net);
this.bzz.setProvider(provider);
return true;
};
};
Web3.version = version;
Web3.utils = utils;
Web3.modules = {
Eth: Eth,
Net: Net,
Personal: Personal,
Shh: Shh,
Bzz: Bzz
};
core.addProviders(Web3);
module.exports = Web3;
Now, I'm trying to import and include it like this:
const Web3 = require('./web3-bundle.js');
which doesn't work. It says undefined is not a constructor.
const Web3 = require('./web3-bundle.js').Web3;
and
const Web3 = require('./web3-bundle.js').default;
both didn't work, either. How should one do this?
Update 2:
Inspecting the bundle further, it has uses exports. and module.exports =. My editor only suggests methods and objects exported with exports. as importable 🤔
I suggest you to use this boilerplate or a boilerplate including a good webpack configuration (suggested boilerplate).
Follow these steps:
Clone the repository
Run yarn install
Run yarn add web3
Add import Web3 from 'web3'; into the app/containers/HomePage.js file (react render view).
Enjoy

How to use IBMIoTF for node.js in a WebApplication?

I tested the IBMIoTF in a node.js server and it worked well.
IBMIoTF you can find here: https://www.npmjs.com/package/ibmiotf
Now I want to use the IBMIoTF in a WebApplication and I notice this little note in the documentation: https://www.npmjs.com/package/ibmiotf#load-the-library-in-browser
Load the library in browser
load iotf-client-bundle.js or iotf-client-bundle-min.js from the dist directory
I also took a look into the http://browserify.org/, but I am not able to get it working.
It is able to load the library in the index.html
<script src="libs/iotf/iotf-client-bundle.min.js"></script>
, but how can I create a object instance in the angular module?
Option 1
I am not able to use require in a WebApplication.
var config = {
"org": "THEORG",
"id": "IOT_WEB_APPLICATION",
"auth-key": "THEKEY",
"auth-token": "THETOKEN",
"type" : "shared"
};
var IotClient = require('ibmiotf');
var iotClient = new IotClient.IotfApplication(config);
In this situation I get
angular.js:14110 ReferenceError: require is not defined
Option 2
I also tried to use a object, I found in iotf-client.js file.
module.exports = {
IotfDevice: _IotfDevice['default'],
IotfManagedDevice: _IotfManagedDevice['default'],
IotfGateway: _IotfGateway['default'],
IotfManagedGateway: _IotfManagedGateway['default'],
IotfApplication: _IotfApplication['default']
};
and did a implementation like this in my controller:
var config = {
"org": "THEORG",
"id": "IOT_WEB_APPLICATION",
"auth-key": "THEKEY",
"auth-token": "THETOKEN",
"type" : "shared"
};
var iotClient = new IotfApplication(config);
Here I get:
angular.js:14110 ReferenceError: IotfApplication is not defined
These options didn't work, but how to create a instance for the IBMIoTF?
Can anyone help me?
You need to browserify the ibmiotf as part of your buildprocess:
1. in your package.json add dependency to ibmiotf npm
2. do npm install
3. add a script command to your package.json for browserify/uglify like this
"scripts": {
"build": "browserify your.js | uglifyjs -m -c warnings=false > bundle.js"
}
do npm build, this will produce a bundle.js with all your javascript files and the dependencies specified to bundle.js
Include the bundle.js in your web html file. ...<script src="bundle.js"></script>
in "your.js" do something like this
var config = require(YOURCONFIG);
var deviceType = "YOURDEVICETYPE";
var appClient = new client.IotfApplication(config);
appClient.connect();
appClient.on("connect", function () {
console.log("Connected");
appClient.subscribeToDeviceEvents(deviceType);
});
appClient.on("deviceEvent", function (deviceType, deviceId, eventType, format, payload) {
console.log("Device Event from :: "+deviceType+" : "+deviceId+" of event "+eventType+" with payload : "+payload);
});

Accessing typescript file variable values using gulp

I have several typescript files, some of them export a const named APIS.
I'm trying to access those exports (I want to concatenated all of them to a single file), but it doesn't seem to work. I'm obviously doing something wrong, but I'm not sure what.
For example, I have a folder named services, with 2 files: service1.ts, service2.ts.
service1.ts:
...
export const APIS = [ { "field1" : "blabla" } ];
service2.ts: does not contain the APIS var.
This is my gulpfile.js:
var gulp = require('gulp');
var concat = require('gulp-concat');
var map = require('gulp-map');
gulp.task('default', function() {
return gulp.src('.../services/*.ts')
.pipe(map(function(file) {
return file.APIS;
}))
.pipe(concat('all.js'))
.pipe(gulp.dest('./test/'));
});
When I run this task, I get nothing. When I added console.log(file.APIS); to the map function, I get undefined for all the values (although it is defined in service1.ts!).
This is following to: Extracting typescript exports to json file using gulp
EDIT: OK, so I tried saving the exports in a .js file instead of a .ts file, and now I can access those vars using require:
gulp.task('default', function() {
return gulp.src('./**/*.service.export.js')
.pipe(map(function(file) {
var fileObj = require(file.path);
...
}))
Now if I try console.log(fileObj.APIS); I get the correct values. What I'm still confused about is how I can pass these value on, and create a single file out of all these vars. Is it possible to push them into an array?
This will not work as you think it would work. Gulp itself knows nothing about typescript files, that file is a vinyl-file and has no knowledge about the typescript code within its content.
Edit
Based on your example, you can do something like this:
var gulp = require('gulp');
var concat = require('gulp-concat');
var map = require('gulp-map');
var fs = require('fs');
gulp.task('test', function ()
{
var allConstants = [];
var stream = gulp.src('./**/*.service.export.js')
.pipe(map(function(file)
{
var obj = require(file.path);
if (obj.APIS != null)
allConstants = allConstants.concat(obj.APIS);
return file;
}));
stream.on("end", function (cb)
{
// Do your own formatting here
var content = allConstants.map(function (constants)
{
return Object.keys(constants).reduce(function (aggregatedString, key)
{
return aggregatedString + key + " : " + constants[key];
}, "");
}).join(", ");
fs.writeFile('filename.txt', content, cb);
});
return stream;
});
Suggestion
If you want to collect multiple variables into a single file i.e. a common variables file I suggest gulp-replace.
Steps
Create a file, require it and use tags within that file to place your variables.
Advice
If you are already using services don't create an array. Instead create an object (JSON) where every property is a constant. i.e.
var constants = {
const_1: 0,
const_2: 1,
const_3: 2,
}

hbsfy outputs hbsfy code on compile - using Gulp + Browserify

I am trying to get any variation of hbsfy or browserify-handlebars to compile correctly using browserify. Compiling results in the handlebars.js(hbsfy) code outputting to my browser. I've tried just using the browserify command browserify -t hbsfy app.js > bundle.js but it doesn't change anything
I haven't the reputation to post images but basically this is the output:
var templater = require("handlebars/runtime").default.template;module.exports = templater(function (Handlebars,depth0,helpers,partials,data) { this.compilerInfo = [4,'>= 1.0.0']; helpers = this.merge(helpers, Handlebars.helpers); data = data || {}; var buffer = "", stack1, helper, functionType="function", escapeExpression=this.escapeExpression; buffer += "
Hello "; if (helper = helpers.name) { stack1 = helper.call(depth0, {hash:{},data:data}); } else { helper = (depth0 && depth0.name); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; } buffer += escapeExpression(stack1) + "
"; return buffer; });
My template (template.hbs) is simply <h1>Hello {{name}}</h1>
My gulpfile setup:
var gulp = require('gulp');
var livereload = require('gulp-livereload');
var browserify = require('gulp-browserify');
var hbsfy = require('browserify-handlebars');
//var hbsfy = require('hbsfy'); //this one shows up the same way
gulp.task('scripts', function() {
return gulp.src('./app/app.js')
.pipe(browserify({
transform: [hbsfy]
}))
.pipe(rename('bundle.js'))
.pipe(gulp.dest('./build/js'))
.pipe(connect.reload());
});
and my js file:
var Handlebars = require('hbsfy/runtime');
var $ = require('jquery'),
router = require('./router/routerDefault'),
template = require('./template.hbs');
$(document).ready(function(){
document.body.innerHTML = template({name: 'browserify'});
})
Does anyone have any experience on how to handle this? Any suggestions would be heplful!
The cause of this issue is redundant compiling. Listing a transform in both the packages.json and the gulpfile.js will perform it twice, I believe. In my packages.json, I now just use this 'node':
"browserify": {
"transform": [
"hbsfy"
]
},
This will compile your templates for you. Your gulpfile.js DOES NOT require this section:
.pipe(browserify({
transform: [hbsfy]
}))
You can use either one. My scripts gulp task now looks like this:
gulp.task('scripts', function() {
return browserify('./app/app.js')
.bundle()
.pipe(source('bundle.js'))
.pipe(gulp.dest('./build/js'))
.pipe(connect.reload());
});
I am experiencing something similar.
Just curious, what OS are you using? Seems to affect Mac but Windows seems OK.
I'm not entirely sure what's causing this but I stopped using gulp-browserify as it is now blacklisted.
I followed the suggestions from this blog post and it seems to solve the issue: http://viget.com/extend/gulp-browserify-starter-faq
The last bit is most relevant.
EDIT:
While using gulp-browserify, I would also check if you've listed your transforms in package.json. I think you may only need to specify transforms in one place (either in gulpfile as you have now or in package.json).

Categories